W3docs

HTML тег <progress>

Тег <progress> используется для отображения индикатора выполнения задачи (прогресс-бар). Примеры использования.

Тег <progress> — один из элементов HTML5. Он представляет степень выполнения задачи — насколько завершена операция (загрузка файла, скачивание, шаг формы, установка). Браузер отрисовывает полосу прогресса, заполнение которой отражает соотношение value к max.

Поскольку <progress> описывает только насколько далеко продвинулась операция, реальные значения обычно меняются во время выполнения. Обновляют их с помощью JavaScript (см. динамический пример ниже). Точный внешний вид элемента зависит от браузера и операционной системы.

<progress> vs <meter>

Эти два элемента выглядят похоже, но означают разные вещи — выбирайте по назначению, а не по внешнему виду:

Используйте <progress>, когда…Используйте <meter>, когда…
Вы показываете степень завершённости задачи (она движется к завершению).Вы показываете статическое измерение в известном диапазоне, например использование диска, оценку или релевантность результата поиска.
Значение естественно растёт от 0 до max со временем.Значение находится где-то на фиксированной шкале и не является «в процессе».

Практическое правило: если это можно завершить — используйте <progress>. Если просто отображаете уровень — используйте <meter>.

Синтаксис

Тег <progress> используется парно. Содержимое записывается между открывающим (<progress>) и закрывающим (</progress>) тегами.

Пример HTML тега <progress>:

HTML тег <progress>

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="file">Loading:</label>
    <progress id="file" value="35" max="100">35%</progress>
  </body>
</html>

Результат

progress tag example

Текст между тегами (35% в примере выше) — это резервное содержимое: браузеры, поддерживающие <progress>, игнорируют его и отрисовывают полосу, тогда как очень старые браузеры, не распознающие элемент, отображают этот текст. Рекомендуется синхронизировать его с текущим значением.

Доступность: всегда подписывайте прогресс-бар

Голый элемент <progress> объявляется программами чтения с экрана как процент без контекста — «35 процентов» не говорит пользователю ничего о том, что загружается. Задайте доступное имя одним из следующих способов:

  • Элемент <label>, чей атрибут for совпадает с id полосы (как выше). Клик по метке — тоже удобная возможность.
  • aria-labelledby, ссылающийся на id видимого текста.
  • aria-label="…", когда нет видимого текста для ссылки.
<!-- Visible label referenced by the bar -->
<span id="upload-status">Uploading photos</span>
<progress aria-labelledby="upload-status" value="60" max="100">60%</progress>

<!-- No visible text? Use aria-label -->
<progress aria-label="Uploading photos" value="60" max="100">60%</progress>

Определённый и неопределённый режим

Прогресс-бар может быть определённым или неопределённым.

  • Определённый — вы знаете, насколько продвинулась задача, поэтому задаёте value. Полоса заполняется пропорционально (value ÷ max).
  • Неопределённый — вы знаете, что задача выполняется, но не знаете, сколько осталось, поэтому опускаете атрибут value. Браузер показывает анимированную полосу «активности» (бегущая полоска или пульсация) вместо фиксированного заполнения.

Пример неопределённого режима

Уберите value, чтобы получить неопределённое состояние, а затем установите его, когда узнаете реальное значение:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="task">Working:</label>
    <!-- No value attribute → indeterminate (animated) -->
    <progress id="task" max="100">Working…</progress>
  </body>
</html>

Это идеально подходит, когда вы ждёте ответа сервера и ещё не можете вычислить процент. Как только можете — переключите тот же элемент в определённый режим, установив value через JavaScript (progress.value = 40).

Стилизация определённого и неопределённого режима

Неопределённый режим стилизовать проще, поскольку у него нет атрибута value — вы можете выбрать его с помощью CSS-селектора отрицания progress:not([value]).

Определённый режим выбирается селектором progress[value]. Задайте размеры с помощью CSS-свойств width и height, а также установите appearance в значение none:

Стилизация прогресс-баров

Простой современный способ: accent-color

В большинстве случаев вендорные префиксы и псевдоэлементы больше не нужны. Задайте CSS-свойство accent-color, и каждый современный браузер окрасит полосу одинаково одной строкой:

progress {
  accent-color: #2563eb; /* color of the filled portion */
  width: 200px;
}

Прибегайте к префиксным псевдоэлементам ниже только тогда, когда нужен полный контроль над фоном, пользовательские градиенты или поддержка старых движков.

Chrome, Safari и последние версии Opera (16+) относятся к этой категории. Стилизацию внешнего вида элемента <progress> можно выполнить с помощью -webkit-appearance: progress-bar.

Установите -webkit-appearance: none;, чтобы сбросить стили по умолчанию.

Пример прогресс-бара

progress[value] {
  -webkit-appearance: none;
  appearance: none;
  width: 200px;
  height: 15px;
}

Пример определённого состояния прогресс-бара:

Пример определённого прогресс-бара:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        appearance: none;
        width: 200px;
        height: 15px;
      }
    </style>
  </head>
  <body>
    <label for="file">Loading:</label>
    <progress id="file" value="30" max="100">30%</progress>
  </body>
</html>

После этого могут возникнуть трудности, поскольку разные браузеры предоставляют разные псевдоэлементы для стилизации прогресс-бара. Чтобы решить эту проблему, можно использовать запасные варианты.

WebKit/Blink предоставляет два псевдоэлемента:

  • ::-webkit-progress-bar — стилизует контейнер элемента прогресса.
  • ::-webkit-progress-value — стилизует значение внутри прогресс-бара.

Стилизуйте ::-webkit-progress-bar с помощью различных CSS-свойств:

Пример прогресс-бара

progress[value]::-webkit-progress-bar {
  background-color: #eee;
  border-radius: 2px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.26) inset;
}

Стилизуйте ::-webkit-progress-value (аналогично самой полосе) с помощью нескольких градиентных фонов для разных целей. Используйте префикс -webkit- для градиентов:

webkit-progress-value

progress[value]::-webkit-progress-value {
  background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .2) 33%, rgba(0, 0, 0, .2) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #1000ff, #359900);
  border-radius: 4px;
  background-size: 20px 15px, 100% 100%, 100% 100%;
}

Пример HTML тега <progress> с CSS-свойствами:

Пример HTML тега <progress> с CSS-свойствами:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        appearance: none;
        width: 200px;
        height: 15px;
      }
      progress[value]::-webkit-progress-bar {
        background-color: #cccccc;
        border-radius: 4px;
      }
      progress[value]::-webkit-progress-value {
        background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .2) 33%, rgba(0, 0, 0, .2) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #1000ff, #359900);
        border-radius: 4px;
        background-size: 20px 15px, 100% 100%, 100% 100%;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="55" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Firefox

Используя appearance: none, можно убрать объёмный эффект по умолчанию. Однако в Firefox после этого остаётся небольшая рамка, которую можно убрать с помощью border: none. Это также решает проблему рамки в Opera 12.

Пример прогресс-бара <progress> в Firefox

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        border: none;
        width: 200px;
        height: 15px;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="55" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Firefox предоставляет один псевдоэлемент (::-moz-progress-bar) для выбора значения прогресс-бара. Иными словами, стилизовать фон контейнера в Firefox невозможно.

HTML тег <progress> - Firefox

progress[value]::-moz-progress-bar {
  background-image: -moz-linear-gradient( 135deg, transparent 33%, rgba(0, 0, 0, 0.1) 33%, rgba(0, 0, 0, 0.1) 66%, transparent 66%), -moz-linear-gradient( top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.25)), -moz-linear-gradient( left, #ff00f7, #4e922a);
  background-size: 35px 20px, 100% 100%, 100% 100%;
}

Firefox не поддерживает псевдоэлементы ::before и ::after для прогресс-бара, а также не поддерживает анимацию CSS3 keyframe на прогресс-баре, что ограничивает возможности оформления.

Пример HTML тега <progress> для Firefox:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value]::-moz-progress-bar {
        background-image: -moz-linear-gradient( 135deg, transparent 33%, rgba(0, 0, 0, 0.1) 33%, 
                          rgba(0, 0, 0, 0.1) 66%, transparent 66%), 
                          -moz-linear-gradient( top, rgba(255, 255, 255, 0.25), 
                          rgba(0, 0, 0, 0.25)),
                          -moz-linear-gradient( left, #ff00f7, #4e922a);
        background-size: 35px 20px, 100% 100%, 100% 100%;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="35" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Обновление прогресс-бара с помощью JavaScript

Поскольку реальный элемент <progress> предоставляет свойство value, обновить полосу можно просто присвоив ему число — браузер перерисует заполнение автоматически. В примере ниже таймер имитирует загрузку, продвигаясь от 0 до 100, а затем останавливается:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="download">Downloading:</label>
    <progress id="download" value="0" max="100">0%</progress>
    <span id="status">0%</span>

    <script>
      var bar = document.getElementById("download");
      var status = document.getElementById("status");
      var loaded = 0;

      var timer = setInterval(function () {
        loaded += 5;
        bar.value = loaded;          // moves the bar
        status.textContent = loaded + "%";
        if (loaded >= bar.max) {
          clearInterval(timer);
        }
      }, 300);
    </script>
  </body>
</html>

Чтобы переключить полосу из неопределённого в определённый режим во время выполнения, установите value, как только узнаете реальное число (bar.value = 40). Чтобы вернуться к неопределённому режиму, удалите атрибут с помощью bar.removeAttribute("value").

Прогресс-бар прокрутки (альтернатива на чистом CSS)

Элемент ниже построен из стилизованных <div>-ов, а не из реального элемента <progress>. Это распространённый паттерн для индикатора прокрутки страницы, когда нужен полный контроль над внешним видом. Если вы предпочитаете семантический элемент, можно заменить <div> на <progress> и обновлять его value в обработчике прокрутки.

Вот как создать полосу, показывающую, насколько далеко пользователь прокрутил страницу:

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

<!DOCTYPE html>
<html>
  <head>
    <style>
      #progress-bar {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 5px;
        background-color: #ddd;
      }

      #progress-bar-fill {
        height: 100%;
        background-color: blue;
        width: 0%;
      }
    </style>
  </head>
  <body>
    <div id="progress-bar">
      <div id="progress-bar-fill"></div>
    </div>

    <h1>Scrollable Content</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>

    <script>
      window.addEventListener("scroll", function () {
        var progressBarFill = document.getElementById("progress-bar-fill");
        var scrollPosition = window.scrollY;
        var totalHeight = document.body.scrollHeight - window.innerHeight;
        var percentage = (scrollPosition / totalHeight) * 100;
        progressBarFill.style.width = percentage + "%";
      });
    </script>
  </body>
</html>

В этом примере у нас есть div с фиксированным позиционированием и id равным progress-bar, который служит контейнером. Внутри него другой div с id равным progress-bar-fill служит движущимся заполнением. (Поскольку это декоративный индикатор прокрутки, а не задача, обычный <div> здесь приемлем; реальный <progress> тоже подойдёт, если установить его value в том же обработчике.)

Мы использовали CSS для задания начальной ширины и высоты прогресс-бара, а также цветов фона для самого прогресс-бара и его заполнения.

Мы также добавили JavaScript-обработчик событий, который прослушивает событие scroll на объекте window. Когда пользователь прокручивает страницу, мы вычисляем позицию прокрутки и полную высоту страницы, а затем рассчитываем, какой процент страницы был прокручен. Мы обновляем свойство width элемента progress-bar-fill, чтобы отразить этот процент и тем самым обновить прогресс-бар.

Вы можете скопировать этот код в новый HTML-файл и открыть его в браузере, чтобы посмотреть, как он выглядит. По мере прокрутки страницы прогресс-бар будет обновляться, отражая, насколько вы прокрутили. Вы можете настроить высоту и цвет прогресс-бара по своему усмотрению.

Атрибуты

АтрибутЗначениеОписание
maxnumberОпределяет максимальное значение текущего процесса. Значение должно быть положительным числом больше 0.
valuenumberОпределяет размер выполненной части задачи. Значение может быть числом от 0 до числа, указанного в атрибуте max, или числом в диапазоне от 0 до 1, если атрибут max не задан.

Тег <progress> также поддерживает глобальные атрибуты и атрибуты событий.

Практика

Практика
Что представляет HTML тег progress?
Что представляет HTML тег progress?
Was this page helpful?