Element <progress> to semantyczny sposób przedstawiania postępu realizacji zadania, takiego jak pobieranie lub przesyłanie informacji albo ukończenie części wieloetapowego procesu. Użycie elementu natywnego ułatwia dostęp, ponieważ czytniki ekranu mają domyślną rolę role="progressbar" i mogą odczytywać wartości.
W tym przewodniku pokazujemy, jak wdrożyć w pełni stylizowany poziomy pasek postępu z dostosowaniami stylu.
Pasek postępu czy okrąg postępu?
- Jeśli miejsce jest ograniczone lub preferowany jest kwadratowy format obrazu, rozważ użycie okrągłego paska postępu (okręgu postępu): Okrąg postępu
- W przypadku większości scenariuszy z nieokreślonym postępem preferuj wskaźniki postępu (wskaźnik postępu wczytywania). Używaj pasków postępu bez określenia czasu, gdy stan nieokreślony jest tymczasowy i wkrótce zostanie zastąpiony paskiem postępu z określeniem czasu (np.oczekiwanie na metadane dotyczące przesyłania, zanim będzie można wyświetlić procent postępu).
Znacznik
- Użyj natywnego elementu
<progress>: zapewnia on wbudowane ułatwienia dostępu i spójne działanie na różnych platformach. - Jeśli potrzebujesz skali innej niż domyślna (0–1), użyj właściwości
max. - Aby ustawić konkretną wartość postępu, ustaw atrybut
value. Pomińvaluew przypadku stanu nieokreślonego (np. przed rozpoczęciem bardziej konkretnych informacji zwrotnych). - Użyj
<label for="...">,aria-labelledbylubaria-label, aby powiązać element postępu z etykietą.
Jakiego typu dostosowanie jest potrzebne?
W przypadku ograniczonego stylu wystarczą te właściwości:
accent-color, aby zmienić kolor paska postępu;width/inline-size, aby zmienić szerokość paska postępuheight/block-size– niespójne stosowanie, najpierw przetestujwriting-mode: vertical-lrw przypadku słupków pionowych.- Efekty, które są stosowane po malowaniu:
opacity,filter,clip-path, maski, przekształcenia,box-shadowitp.
Jeśli wystarczy Ci ograniczone formatowanie, pomiń następną sekcję.
OSTRZEŻENIE: niektóre właściwości (np. border-radius, background, border) spowodują wyłączenie domyślnego stylu paska postępu bez powiadomienia. Jeśli potrzebujesz stylów innych niż wymienione powyżej, musisz wdrożyć w pełni niestandardowe style, jak opisano w następnej sekcji. NIE stosuj bardziej rozbudowanego stylu „na wszelki wypadek”.
W pełni niestandardowy styl
1. Konfiguracja podstawowa
- OBOWIĄZKOWE: użyj
appearance: none, aby włączyć styl niestandardowy. - Zresetuj granice UA za pomocą
border: 0 solid - Aby przyciąć aktywny pasek do promienia obramowania elementu, użyj
overflow: clipLUB zastosuj ten samborder-radiusdo paska. NIE używajborder-radius: inheritna pasku, który zależy od konkretnej struktury elementów w modelu Shadow DOM.
progress {
/* Reset default browser styles */
appearance: none;
border: 0 solid;
/* Clip bar to element’s border-radius */
overflow: clip;
}
2. Styl
- Stylizuj ścieżkę w samym elemencie
progress. - Użyj odpowiedniego pseudoelementu kierowanego na przeglądarkę, aby kierować reklamy na sam pasek postępu:
::-webkit-progress-valuew przypadku WebKit/Blink i::-moz-progress-barw przypadku Firefoksa. - OBOWIĄZKOWO: NIE grupuj pseudoelementów
-webkit-i-moz-w tej samej regule. Reguła zostanie uznana za nieprawidłową i będzie ignorowana. Atrybuty:is()i:where()nie pomogą w tym przypadku, ponieważ nie obsługują pseudoelementów. - Każdy pseudoelement kierowany na przeglądarkę powinien pojawić się dokładnie raz. Dostosowania dotyczące stanu (takie jak nieokreślony rozmiar segmentu i animacja) powinny być kierowane przez właściwości niestandardowe ustawione w samym elemencie
progress. - Opcjonalnie: przejście
inline-sizena wypełnieniu, aby zmiany wartości były animowane, a nie skokowe. Firefox określa rozmiar wypełnienia w układzie i ignoruje go, co nie ma żadnych negatywnych skutków.
progress {
--progress-bar-radius: 1e5px;
border-radius: var(--progress-bar-radius);
/* Apply color for custom progress track (background) */
background: var(--progress-bar-track, var(--color-neutral-90));
/* Subtle depth on the empty part of the track */
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.1);
}
/* Let <progress> styling show through */
progress::-webkit-progress-bar {
background: transparent;
}
/* Webkit, Chrome */
progress::-webkit-progress-value {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
/* Firefox */
progress::-moz-progress-bar {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
3. Styl stanu nieokreślonego
Dodaj niestandardową animację dla stanu nieokreślonego: przekształć pseudoelement wypełnienia w krótki segment i przesuwaj go wzdłuż ścieżki.
- Nadaj styl samemu wypełnieniu. NIE odtwarzaj go jako tła w elemencie
progress. - Wypełnienie nieokreślone istnieje tylko dzięki animacji: klatki kluczowe określają jego długość za pomocą rzeczywistego elementu
inline-size(co jest lepsze niż wbudowany elementinline-sizew Chromium) i przemieszczają go za pomocą elementutranslate. NIE używajscalejako długości, ponieważ zniekształca to wzór namalowany na wypełnieniu. - Wartości procentowe
translatesą określane względem szerokości wypełnienia, dlatego pozycje należy wyrażać w jednostkach ścieżki: ustawprogressjako kontener o rozmiarze inline i użyjcqiw klatkach kluczowych. Uwzględnijmargin-right: autowfrom, to, aby Chromium wyświetlał wypełnienie po lewej stronie również w przypadku języków zapisywanych od prawej do lewej. - Do przesuwania wypełnienia używaj przekształceń, a nie marginesów.
- Przekształcenia utrzymują animację w kompozytorze (chyba że animowana jest też właściwość
inline-size) - Marginesy nie działają w językach zapisywanych od prawej do lewej z 2 powodów:
- Firefox pozycjonuje nieokreślone wypełnienie, używając tylko fizycznego lewego marginesu, więc
margin-inline-startnie ma wpływu na języki pisane od prawej do lewej i wypełnienie nigdy się nie przesuwa. - W Chromium i WebKit, które układają wypełnienie jako normalny blok, gdy margines wypycha wypełnienie poza koniec ścieżki, marginesy sumują się do wartości większej niż ścieżka. Standardowy arkusz CSS rozwiązuje ten problem, ignorując
margin-leftw językach pisanych od prawej do lewej, dzięki czemu segment przeskakuje do krawędzi, zamiast się z niej zsuwać. translatejest stosowany po układzie, więc żaden z tych problemów nie występuje.
- Przekształcenia utrzymują animację w kompozytorze (chyba że animowana jest też właściwość
- Aby odzwierciedlić ruch w językach zapisywanych od prawej do lewej (jak w przypadku paska natywnego Chrome), odwróć animację w
:dir(rtl):
progress:dir(rtl) {
--progress-bar-indeterminate-animation: progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear reverse;
}
- Zdefiniuj właściwości publiczne
--progress-bar-indeterminate-*wprogress(ich nazwa już określa ich zakres do stanu), aby konsumenci mogli je zastąpić bez znajomości:indeterminate. - Aby zmienić długość segmentu (np. krawędź przednia przesuwa się do przodu, a krawędź tylna ją dogania), ustaw
--progress-bar-indeterminate-animationna 2 równoczesne animacje: jedną, której klatki kluczowe animujątranslatewcqi(pozycja), i drugą, której klatki kluczowe animująinline-size(długość), tak aby każda miała własne klatki kluczowe i efekt spowolnienia. NIE próbuj kształtować obu krawędzi na jednej liście klatek kluczowych. Właściwośćanimation-timing-functiondla klatki kluczowej dotyczy każdej właściwości w tej klatce kluczowej. --progress-bar-animationma zastosowanie w obu stanach i może być używany do efektów takich jak określone migotanie.revert-rulesłuży do zastępowania tylko wtedy, gdy jest ustawiony, aby zmaksymalizować możliwość tworzenia kompozycji.- Nigdy nie wyłączaj animacji nieokreślonej (
animation: nonepozostawia w Chromium wypełnienie o szerokości 0). Aby zmniejszyć ruch, zwolnij go.
progress {
/* Lets the fill position itself in track units (cqi) */
container-type: inline-size;
/* Segment length relative to the track */
--progress-bar-indeterminate-size: 30%;
--progress-bar-indeterminate-animation-duration: 1.5s;
/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
--progress-bar-indeterminate-animation-duration: 10s;
}
}
progress:indeterminate {
--progress-bar-animation: var(
--progress-bar-indeterminate-animation,
progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear
);
}
/* Add to the existing pseudo-element rules */
progress::-webkit-progress-value {
animation: var(--progress-bar-animation, revert-rule);
}
progress::-moz-progress-bar {
animation: var(--progress-bar-animation, revert-rule);
}
/* Physical: left to right regardless of direction (reverse under :dir(rtl) to mirror). */
@keyframes progress-bar-indeterminate {
from, to {
inline-size: var(--progress-bar-indeterminate-size);
/* Pin to the physical left; Chromium would otherwise lay the fill out at the inline start */
margin-right: auto;
}
from { translate: -100%; } /* Own width: fully outside the left edge */
to { translate: 100cqi; } /* Track width: fully outside the right edge */
}
Dodatkowe kwestie dotyczące ułatwień dostępu
Oprócz wymienionych wyżej wskazówek:
- Powiadom o zakończeniu bez przejmowania zaznaczenia: nie ustawiaj
tabindexani nie wywołuj.focus()w<progress>, ponieważ jest to element nieinteraktywny, a przeniesienie na niego zaznaczenia przeszkadza użytkownikom klawiatury. Aby ogłosić zakończenie zadania w tle, zaktualizuj element stanu polite (role="status"lubaria-live="polite"). - Nie dodawaj tekstu zastępczego wewnątrz elementu
<progress>: tekst wewnątrz elementu<progress>jest ignorowany przez nowoczesne przeglądarki i nie jest używany przez technologie wspomagające osoby z niepełnosprawnością. - Unikaj używania skrótu
aria-busy+aria-describedbyw przypadku nieoznaczonego ogólnego elementu<div>. Atrybutaria-busynie jest w pełni obsługiwany przez czytniki ekranu, a atrybutaria-describedbyw nienazwanym elemencie<div>bez roli jest ignorowany przez technologie wspomagające osoby z niepełnosprawnością. Jeśli zawartość regionu nie jest gotowa podczas wczytywania, ukryj ją za pomocąhiddenlubaria-hidden="true". - ZADBAJ o odpowiedni kontrast między paskiem postępu a ścieżką, gdy dodajesz style niestandardowe.
- Rozważ alternatywne sposoby przedstawiania stanu nieokreślonego: animacje paska postępu nieokreślonego wyświetlane równolegle z innymi treściami mogą rozpraszać niektórych użytkowników.
Strategie zastępcze
Kreacje zastępcze i obsługa koloru uzupełniającego w przeglądarkach
Właściwość accent-color jest progresywnym ulepszaniem.
Przeglądarki, które nie obsługują tej właściwości, zignorują ją i użyją domyślnych kolorów interfejsu.
Jeśli właściwość accent-color nie jest obsługiwana, a wymagane jest nadanie stylu paskowi postępu, użyj metody niestandardowej, aby zastosować preferowany styl.
Kreacje zastępcze i obsługa przeglądarek w przypadku revert-rule
Jeśli revert-rule nie jest obsługiwany, animation: var(--progress-bar-animation, revert-rule) powraca do animation-name: revert-rule z czasem trwania 0s, gdy --progress-bar-animation nie jest ustawiony, co jest nieszkodliwą operacją, gdy nie ma @keyframes revert-rule.