Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 113 additions & 54 deletions html/progress/demos/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,65 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap">
<style>
*,
*::before,
*::after {
box-sizing: border-box;
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
color-scheme: dark;
font-size: 18px;
}

body {
min-height: 100vh;
padding: 50px;
display: flex;
align-items: center;
justify-content: center;
padding: 28px;
color: #ffffff;
background-color: #18191C;
color: #FFFFFF;
font-family: "Roboto", sans-serif;
font-size: 18px;
background-color: #18191c;
}

.demo-wrap {
.container {
display: flex;
flex-direction: column;
}

.row {
display: flex;
align-items: center;
max-width: 480px;
width: 100%;
justify-content: space-between;
}

.demo-title {
margin-bottom: 16px;
font-size: 20px;
font-weight: bold;
text-align: center;
.row + .row {
margin-top: 25px;
}

.row--upload {
display: flex;
flex-direction: column;
align-items: end;
}

.row-label {
margin-right: 55px;
font-size: 24px;
font-weight: 500;
line-height: 1;
}

.upload, .button {
width: 350px;
}

.upload {
position: relative;
width: 100%;
height: 28px;
margin-bottom: 12px;
border: 1px solid #5068f6;
border: 1px solid #FF8630;
border-radius: 16px;
}

Expand All @@ -59,78 +76,120 @@
z-index: 1;
}

progress {
.upload__indicator {
overflow: hidden;
display: block;
width: 0;
border: none;
border-radius: 16px;
height: 28px;
background-color: #5068f6;
background-color: #FF8630;
}

progress::-webkit-progress-bar {
.upload__indicator::-webkit-progress-bar {
border: none;
background-color: #5068f6;
background-color: #FF8630;
border-radius: 16px;
}

progress::-webkit-progress-value {
background-color: #5068f6;
.upload__indicator::-webkit-progress-value {
background-color: #FF8630;
border-radius: 16px;
}

progress::-moz-progress-bar {
.upload__indicator::-moz-progress-bar {
border: none;
background-color: #5068f6;
background-color: #FF8630;
border-radius: 16px;
}

#successText {
.success-message {
height: 22px;
margin-bottom: 16px;
margin-top: 15px;
}

button {
display: inline-flex;
align-items: center;
padding: 12px 24px;
border: 1px solid transparent;
border-radius: 12px;
font-family: "Roboto", sans-serif;
font-size: 16px;
color: #ffffff;
background-color: #5068f6;
.button {
display: block;
min-width: 210px;
border: 2px solid transparent;
border-radius: 6px;
padding: 9px 15px;
color: #000000;
font-size: 18px;
font-weight: 300;
font-family: inherit;
transition: background-color 0.2s linear;
}

.button-orange {
background-color: #FF8630;
}

.button:hover {
background-color: #FFFFFF;
cursor: pointer;
transition: border-color 0.2s linear;
transition: background-color 0.2s linear;
}

.button:focus-visible {
border: 2px solid #FFFFFF;
outline: none;
}

button:hover {
border: 1px solid #ffffff;
transition: border-color 0.2s linear;
.button:focus {
border: 2px solid #FFFFFF;
outline: none;
}

@media (max-width: 768px) {
body {
padding: 30px;
}

.row {
display: block;
}

.upload, .button, .container {
width: 100%;
}

.upload {
margin-top: 10px;
}
}
</style>
</head>
<body>
<div class="demo-wrap">
<div class="demo-title">Индикатор загрузки файла</div>
<div class="upload">
<div id="progressCounter" class="upload__counter">0%</div>
<progress id="progressBar" value="0" max="100"></progress>
<div class="container">
<div class="row">
<label class="row-label" for="progressBar">Загрузка файла:</label>
<div class="upload">
<div id="progressCounter" class="upload__counter">0%</div>
<progress id="progressBar" class="upload__indicator" value="0" max="100"></progress>
</div>
</div>
<div class="row row--upload">
<button class="button button-orange" onclick="start()">Загрузить файл</button>
<p class="success-message" id="successText" aria-live="polite"></p>
</div>
<p id="successText"></p>
<button onclick="start()">Загрузить файл</button>
</div>

<script>
const progressBar = document.getElementById('progressBar')
const uploadSuccess = document.getElementById('successText')
const uploadCounter = document.getElementById('progressCounter')
let progressWidth = 0;
let progressWidth = 0

function start() {
setInterval(() => {
if (progressWidth >= 100) {
uploadSuccess.textContent = 'Файл загружен успешно.'
uploadSuccess.textContent = 'Файл успешно загружен.'
clearInterval()
} else {
progressWidth++;
progressBar.style.width = progressWidth + '%'
progressBar.value = progressWidth
uploadCounter.textContent = progressWidth + '%'
}
}, 10)
Expand Down
Binary file modified html/progress/images/default_progressbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 56 additions & 11 deletions html/progress/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ title: "`<progress>`"
description: "Элемент, который показывает ход выполнения задачи."
authors:
- webdb81
contributors:
- tatianafokina
keywords:
- индикация загрузки
- индикатор процесса
related:
- html/meter
- recipes/progress
- css/vendor-prefixes
- a11y/role-progressbar
tags:
- doka
---
Expand All @@ -18,30 +20,73 @@ tags:

Тег `<progress>` создаёт индикатор выполнения задачи. Обычно выглядит как прогресс-бар.

В тег по умолчанию встроена роль [`progressbar`](/a11y/role-progressbar/), которая делает загрузку «живой» областью. Это область страницы, об изменениях в которой пользователи [скринридеров](/a11y/screenreaders/) узнают автоматически, без перехода к ней.

## Пример

Прогресс-бар с известным максимальным значением:

```html
<p>Подождите, пожалуйста, файл загружается</p>
<progress value="30" max="100"></progress>
<label for="progress">Загрузка файла</label>
<progress id="progress" value="0" max="100"></progress>
```

## Как понять
Задача выполняется, но неизвестно, сколько займёт времени. В примере связываем прогресс-бар с фидом, где обновляется содержимое, при помощи атрибута [`aria-describedby`](/a11y/aria-describedby/).

Тег `<progress>` стоит использовать для вывода информации о процессе, который выполняется и должен завершиться: прогресс загрузки файла, процесс соединения абонентов, длительность таймера.
```html
<div role="feed" aria-busy="true" aria-describedby="progress">
<!-- Содержимое, которое сейчас обновляется -->
</div>

<aside>
<progress id="progress" aria-label="Фид обновляется"></progress>
```

💡 Если пользователю надо показать числовое значение в заданном диапазоне, лучше использовать тег [`<meter>`](/html/meter/).
## Как понять

</aside>
Тег `<progress>` стоит использовать для вывода информации о процессе, который выполняется и должен завершиться. Например:

- сообщить о количестве свободного места на диске;
- вывести допустимые пределы громкости;
- показать уровень загруженности интернет-канала.
- показать уровень загруженности интернет-канала;
- прогресс загрузки файла;
- процесс соединения абонентов.

<aside>

💡 Если показываете пользователю числовое значение в заданном диапазоне, используйте тег [`<meter>`](/html/meter/). Для таймера используйте специальную [ARIA-роль `timer`](/a11y/role-timer/).

</aside>

## Как пишется

- `max` — максимальное значение. Должно быть положительным, допускаются дробные значения. По умолчанию равно 1.
- `value` — текущее значение. Положительное число, допускаются дробные значения. Должно находится в пределах между 0 и значением атрибута `max`. Также его можно менять при помощи JavaScript. Если атрибут не прописан, то линия внутри прогресс-бара будет перемещаться от одного края к другому, показывая, что задача выполняется, но не известно, сколько это займёт времени.
Специальные атрибуты `<progress>`:

- `max` — максимальное значение. Должно быть положительным, допускаются дробные значения. По умолчанию равно `1`.
- `value` — текущее значение. Положительное число, допускаются дробные значения. Должно находиться в пределах между 0 и значением атрибута `max`. Если атрибут не прописан, линия внутри прогресс-бара будет перемещаться от одного края к другому. Это показывает, что задача выполняется, но неизвестно, сколько займёт времени.

Минимальное значение `min` всегда равно `0`, и этот атрибут нельзя задавать `<progress>`.

Чтобы прогресс-бар был полностью доступен для всех пользователей, изменяйте значение `value` при помощи JavaScript. В этом случае скринридеры расскажут о процессе загрузки в процентах или с помощью особого звукового оповещения.

К тегу `<progress>` применимы все [глобальные атрибуты](/html/global-attrs/).

Также не забывайте подписывать, что сейчас загружается. Для видимой подписи используйте тег `<label>`, а для видимой только пользователям вспомогательных технологий — [`aria-label`](/a11y/aria-label/).

```html
<!-- Подпись с <label> -->
<label for="progress">Загрузка файла</label>
<progress id="progress" value="0" max="100"></progress>

<label>
Загрузка файла <progress id="progress" value="0" max="100"></progress>
</label>

<!-- Подпись с aria-label -->
<progress
id="progress"
value="0"
max="100"
aria-label="Загрузка файла"
>
</progress>
```
20 changes: 10 additions & 10 deletions html/progress/practice/webdb81.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
🛠 Внешний вид элемента `<progress>` может быть разным — это зависит от браузера и операционной системы устройства пользователя. Вот так стандартный прогресс-бар будет выглядеть на устройствах с macOS и Windows:
🛠 Внешний вид элемента `<progress>` может быть разным — это зависит от браузера и операционной системы устройства пользователя. Стандартный прогресс-бар на устройствах с macOS и Windows имеет голубую заливку в Chrome, Safari и Firefox. Только Edge использует серый цвет. Сильнее всего элемент отличается в Safari. Он гораздо уже остальных.

![Внешний вид прогресс-бара в macOS и Windows](../images/default_progressbar.png)
![Сравнение прогресс-бара в Windows и macOS. Отличия описаны перед картинкой.](../images/default_progressbar.png)

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

```css
progress {
border: none;
background-color: #5068f6;
background-color: #FF8630;
}
```

Но в Firefox эти стили не затронут бегунок, поэтому дополнительно потребуется использовать [вендорный префикс](/css/vendor-prefixes/) `-moz`. А вот для стилизации в Chrome и Safari как самого элемента, так и его бегунка, необходимо использовать префиксы `-webkit`.
В Firefox эти стили не затронут бегунок, поэтому дополнительно используйте [вендорный префикс](/css/vendor-prefixes/) `-moz`. Для стилизации в Chrome и Safari как самого элемента, так и его бегунка, используйте префиксы `-webkit`.

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

```css
progress::-moz-progress-bar {
border: none;
background-color: #5068f6;
background-color: #FF8630;
}

progress::-webkit-progress-bar {
border: none;
background-color: #5068f6;
background-color: #FF8630;
}

progress::-webkit-progress-value {
background-color: #5068f6;
background-color: #FF8630;
}
```

<iframe title="Пример индикатора загрузки" src="../demos/basic/" height="190"></iframe>
<iframe title="Пример индикатора загрузки" src="../demos/basic/" height="350"></iframe>