Spec-Zone.ru › CSS

CSS-функция `progress()`

Базовая поддержка Недавно стала доступна

Эта функция работает на новейших устройствах и в последних версиях браузеров. Она может не работать на старых устройствах и в старых версиях браузеров. Она доступна во всех браузерах с сентября 2026 года.

progress() — это CSS-функция, возвращающая значение <number>, которое представляет положение одного значения (значения прогресса) относительно двух других значений (начального и конечного значений прогресса).

Синтаксис

/* With fixed progress value */
progress(300, 0, 1000)
progress(50px, 0px, 100px)
progress(50%, 30%, 80%)

/* Unclamped return value */
progress(no-clamp 300, 0, 100)
progress(no-clamp 50px, 0px, 100px)

/* With custom property */
progress(var(--container-width), 320, 1200)

/* Inside math function */
calc((progress(var(--container-width), 20%, 80%) / 2) + 0.5)

/* Inside non-math function */
rgb(
  calc(255 * progress(var(--container-width), 320px, 1200px))
  calc(255 * progress(var(--container-width), 320px, 1200px)) 255 / 0.5
);

/* Math function inside progress() */
progress(calc(20 + 30), 0, 100)

Параметры

Функция progress() принимает необязательное ключевое слово, за которым следуют три разделённых запятыми выражения <calc-sum> в качестве параметров:

progress(no-clamp? <calc-sum>, <calc-sum>, <calc-sum>)

Это:

no-clamp Необязательно
Ключевое слово, которое не позволяет ограничивать возвращаемое значение диапазоном от 0 до 1. Оно записывается перед значением прогресса и не отделяется от него запятой. См. раздел Ограничение возвращаемого значения.
Значение прогресса
Значение, положение которого нужно вычислить относительно двух других значений.
Начало прогресса
Нижняя граница прогресса.
Конец прогресса
Верхняя граница прогресса.

Возвращаемое значение

Значение <number>, представляющее положение значения прогресса относительно двух других значений. Оно вычисляется следующим образом:

(progress - progress start) / (progress end - progress start)

Если значение прогресса находится между начальным и конечным значениями прогресса, возвращаемое значение будет находиться между 0 и 1 и представлять собой процент.

Если указано ключевое слово no-clamp, возвращаемым значением может быть любое число. В противном случае возвращаемое значение ограничивается диапазоном от 0 до 1.

Описание

CSS-функция progress() позволяет вычислять коэффициент прогресса. Это полезно для создания, например, анимаций индикаторов выполнения или блоков, которые постепенно становятся видимыми по мере увеличения их ширины и раскрытия содержимого.

Самый простой пример использования может выглядеть так:

opacity: progress(5, 0, 10);

В этом случае вычисленное значение opacity будет равно 0.5, поскольку 5 находится ровно посередине между 0 и 10.

Ограничение возвращаемого значения

По умолчанию возвращаемое значение ограничивается диапазоном от 0 до 1, поэтому значение прогресса, выходящее за пределы начальной и конечной границ, возвращает ближайшую границу:

/* Computes to 1, not 1.5 */
scale: progress(15, 0, 10);

/* Computes to 0, not -0.5 */
scale: progress(-5, 0, 10);

Если добавить ключевое слово no-clamp перед значением прогресса, это ограничение снимается: функция экстраполирует значение за пределы границ, а не останавливается на них:

/* Computes to 1.5 */
scale: progress(no-clamp 15, 0, 10);

/* Computes to -0.5 */
scale: progress(no-clamp -5, 0, 10);

Обратите внимание, что no-clamp — это ключевое слово, а не отдельный параметр, поэтому после него не ставится запятая.

Допустимые типы единиц измерения

Параметры функции progress() могут быть математическими выражениями или простыми значениями. Значения (или результаты выражений) могут быть значениями типа <number>, <dimension> или <percentage>. У них могут быть разные единицы измерения, но все они должны относиться к одному типу, иначе функция будет недопустимой.

Рассмотренный ранее пример допустим — все его параметры являются безразмерными значениями <number>:

progress(5, 0, 10)

Следующий пример тоже допустим — все его параметры используют единицы измерения <length>. Для вычислений используются вычисленные значения. Если font-size в момент вычисления равен 16px, то 3em будет преобразовано в 48px. Это составляет 48% пути между 0px и 100px, поэтому возвращаемое значение будет равно 0.48.

progress(3em, 0px, 100px)

Однако последние два примера в этом разделе недопустимы. Типы не совпадают, поэтому полученные вычисления не имеют смысла.

progress(3s, 0px, 100px)
progress(3em, 0, 100)

Создание безразмерных значений

Функция progress() возвращает безразмерные значения, поэтому её можно использовать для удаления единиц измерения из значений так же, как и хак tan(atan2()). Однако обратите внимание, что благодаря изменениям в работе типизированной арифметики CSS того же результата можно добиться простым делением.

Сочетание progress() с другими функциями и пользовательскими свойствами

Поскольку progress() всегда возвращает безразмерное значение, её часто сочетают с другой математической функцией, например calc(), чтобы получить значение с нужными единицами измерения. В функциях progress() можно также использовать пользовательские свойства CSS. Это удобно, поскольку часто требуется задавать одинаковые значения в нескольких местах и/или основывать их на пользовательских свойствах, установленных с помощью JavaScript.

В следующем примере вычисляется, какой процент ширины области просмотра находится между минимальной шириной 320px и максимальной шириной 1200px. Функция calc() умножает возвращаемое значение progress() на 600px, преобразуя его в значение в пикселях, которое соответствует половине значения прогресса ширины области просмотра между 320px и 1200px.

width: calc(progress(100vw, 320px, 1200px) * 600px);

Например, если ширина области просмотра равна 700px, значение прогресса будет вычислено как ((700 - 320) / (1200 - 320)) = 0.431818. Затем ширина будет вычислена как 0.431818 * 600px, что равно 259.1px.

Следующий пример представляет собой обновлённую версию предыдущего: для значений прогресса, начала и конца прогресса мы использовали пользовательские свойства.

width: calc(
  progress(
      var(--container-width),
      var(--custom-min-width),
      var(--custom-max-width)
    ) *
    var(--custom-max-width)
);

Функции progress() можно использовать для вычисления отдельных значений внутри других функций и значений компонентов внутри значений свойств-сокращений, если возвращаемые функциями значения имеют допустимые типы для этих значений.

В результате могут получаться сложные выражения. Например, здесь мы вычисляем первые два канала цвета rgb() пропорционально тому же соотношению ширины, что и ранее:

background-color: rgb(
  calc(
      255 *
        progress(
          var(--container-width),
          var(--custom-min-width),
          var(--custom-max-width)
        )
    )
    calc(
      255 *
        progress(
          var(--container-width),
          var(--custom-min-width),
          var(--custom-max-width)
        )
    )
    255 / 0.5
);

Формальный синтаксис

Примеры

Базовое использование progress()

В этом примере мы покажем базовое использование функции progress() для задания width индикатора выполнения в виде процента, равного коэффициенту прогресса значения width родительского элемента между его min-width и max-width.

HTML

В нашем HTML есть элемент <section>, представляющий содержимое, и элемент <div>, представляющий индикатор прогресса ширины.

<section>
  <div class="progress"></div>
</section>

CSS

Сначала в CSS мы задаём несколько пользовательских свойств для элемента <section>, представляющих его min-width, max-width и width. Затем присваиваем этим свойствам соответствующие значения пользовательских свойств и задаём для элемента <section> сплошной цвет background-color, чтобы он был виден.

html {
  height: 100%;
  font-family: sans-serif;
}

body,
section {
  height: inherit;
}
section {
  --custom-min-width: 300px;
  --custom-max-width: 700px;
  --custom-width: 600px;

  min-width: var(--custom-min-width);
  max-width: var(--custom-max-width);
  width: var(--custom-width);

  background-color: cyan;
}

Теперь перейдём к элементу <div>: сначала зададим ему height и тёмный background-color, чтобы он выделялся на фоне элемента <section>. Затем вычислим его width: с помощью функции progress() рассчитаем коэффициент прогресса ширины между минимальной и максимальной шириной, а затем с помощью функции calc() умножим возвращаемое значение progress() на 100%, чтобы получить процент.

.progress {
  height: 4px;
  background-color: red;

  width: calc(
    progress(
        var(--custom-width),
        var(--custom-min-width),
        var(--custom-max-width)
      ) *
      100%
  );
}

Результат

Демонстрация будет выглядеть так:

Ширина элемента <div> составляет 75% ширины элемента <section>, поскольку min-width равен 400px, max-width равен 700px, а width равен 600px, то есть 75% расстояния между двумя предыдущими значениями.

Эффекты изменения размера контейнера

В этом примере показаны более сложные способы использования функции progress(), позволяющие создавать интересные эффекты при изменении размера окна браузера.

Этот пример лучше всего выглядит в полноразмерной вкладке настольного браузера. Поэтому мы не встроили его на эту страницу в виде интерактивного примера. Вместо этого его можно посмотреть по ссылке Демонстрация CSS-функции progress() (также см. исходный код).

Откройте пример в отдельной вкладке и попробуйте увеличить и уменьшить ширину окна браузера, чтобы увидеть эффект. Оставьте эту вкладку открытой, чтобы обращаться к ней по мере чтения объяснения ниже.

HTML

В нашем HTML есть элемент <article>, содержащий остальное содержимое, и два элемента <section>: один служит контейнером для фонового изображения, а другой содержит наше содержимое. В элементе <section class="content"> также находится элемент <div class="progress">, представляющий индикатор прогресса ширины, как и в предыдущем примере. Для краткости остальная часть содержимого опущена.

<article>
  <section class="background"></section>
  <section class="content">
    <div class="progress"></div>
    <!-- Content here -->
  </section>
</article>

JavaScript

В скрипте мы сначала получаем ссылку на элемент <article>. Затем определяем функцию с именем setContainerWidth(), которая получает ширину клиентской области элемента <article> с помощью Element.getBoundingClientRect() и задаёт ему пользовательское свойство с именем --container-width. Его значение равно ширине клиентской области, округлённой вниз, с добавлением px.

Затем для объекта Window мы задаём обработчик события resize, который запускает setContainerWidth() при изменении размера окна браузера. Кроме того, мы запускаем её один раз после загрузки страницы, чтобы задать пользовательское свойство --container-width для элемента <article>.

const articleElem = document.querySelector("article");

function setContainerWidth() {
  const clientWidth = articleElem.getBoundingClientRect().width;
  articleElem.style.setProperty(
    "--container-width",
    `${Math.floor(clientWidth)}px`,
  );
}

window.addEventListener("resize", setContainerWidth);

setContainerWidth();

Теперь, когда всё настроено, мы можем задавать значения свойств на основе --container-width, чтобы элементы дизайна динамически менялись при изменении размера окна.

CSS

В следующем разделе объясняется только та часть CSS, которая относится к использованию функции progress() в демонстрации. Полный код CSS см. в исходном коде CSS.

Сначала мы центрируем элемент <article> внутри элемента <body> с помощью flexbox, а затем задаём для него пользовательские свойства, представляющие значения min-width и max-width, которые будут использоваться в других местах. Затем выбираем элемент <article> и задаём ему значения min-width и max-width, равные ранее заданным пользовательским свойствам. Значению position задаём relative, чтобы можно было позиционировать содержимое относительно этого элемента. Затем задаём ему процентную width, фиксированную height и border.

body {
  height: inherit;
  display: flex;
  justify-content: center;
  align-items: center;
  --custom-min-width: 320px;
  --custom-max-width: 1200px;
}

article {
  min-width: var(--custom-min-width);
  max-width: var(--custom-max-width);
  position: relative;
  width: 70%;
  height: 600px;
  border: 3px solid black;
}

Теперь перейдём к элементу progress <div>. Его значение width задаём в процентах, исходя из коэффициента прогресса пользовательского свойства --container-width, установленного для элемента <article> с помощью JavaScript, между значениями min-width и max-width (для второго и третьего параметров progress() мы используем те же пользовательские свойства, что и для <article> min-width и max-width).

Также задаём ему height и background-color, а затем абсолютно позиционируем в верхнем левом углу элемента <article>.

.progress {
  width: calc(
    progress(
        var(--container-width),
        var(--custom-min-width),
        var(--custom-max-width)
      ) *
      100%
  );
  height: 4px;
  background-color: red;
  position: absolute;
  top: 0;
  left: 0;
}

Далее рассмотрим элемент background <section>. Мы абсолютно позиционируем его относительно элемента <article> и задаём ему inset: 0, чтобы он имел тот же размер и располагался поверх него. Затем задаём ему довольно широкое значение background-image и позиционируем фоновое изображение, присваивая свойству background-position-x то же значение, что и свойству width индикатора прогресса. В результате при увеличении ширины окна браузера фоновое изображение смещается влево, создавая эффект прокрутки изображения.

.background {
  position: absolute;
  inset: 0;
  background-image: url("https://mdn.github.io/shared-assets/images/examples/wide-background.jpg");
  background-position-x: calc(
    progress(
        var(--container-width),
        var(--custom-min-width),
        var(--custom-max-width)
      ) *
      100%
  );
}

Мы абсолютно позиционируем элемент content <section> поверх элемента background <section>, а затем задаём ему padding. При изменении размера окна браузера мы меняем два значения свойств, используя тот же коэффициент прогресса, что и ранее:

  • Мы изменяем компоненты R и G значения background-color, умножая коэффициент прогресса на 255 для каждой из них, чтобы получить пропорциональное значение канала. По мере увеличения ширины окна фоновый цвет становится менее синим и более белым, создавая впечатление перехода от ночи к дню (значение цвета имеет прозрачность 0.5, поэтому оно действует как оттенок поверх фонового изображения).
  • Мы изменяем значение opacity, чтобы содержимое постепенно проявлялось при увеличении ширины окна.
.content {
  position: absolute;
  inset: 0;
  padding: 20px;
  background-color: rgb(
    calc(
        255 *
          progress(
            var(--container-width),
            var(--custom-min-width),
            var(--custom-max-width)
          )
      )
      calc(
        255 *
          progress(
            var(--container-width),
            var(--custom-min-width),
            var(--custom-max-width)
          )
      )
      255 / 0.5
  );
  opacity: calc(
    (
        progress(
            var(--container-width),
            var(--custom-min-width),
            var(--custom-max-width)
          ) /
          2
      ) +
      0.5
  );
}

Спецификации

Спецификация
Модуль значений и единиц CSS, уровень 5
# progress

Совместимость с браузерами

Настольные устройства Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome для Android Firefox для Android Opera для Android Safari для iOS Samsung Internet WebView для Android WebView для iOS
progress
138
138
155
122
26
138
155
91
26
30.0
138
26
no-clamp
Нет
Нет
155
Нет
предварительная версия
Нет
155
Нет
Нет
Нет
Нет
Нет

См. также

  • Модуль значений и единиц CSS
  • Запросы стилей контейнера
  • Медиазапросы
  • Запросы возможностей

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/progress

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API