Podstawowe omówienie sposobu tworzenia kolorowego, adaptacyjnego i łatwo dostępnego paska wczytywania za pomocą elementu <progress>
.
W tym poście opowiem, jak stworzyć
dostępny pasek wczytywania z elementem <progress>
. Wypróbuj
w wersji demonstracyjnej i obejrzyj
!
Jeśli wolisz film, oto wersja tego posta w YouTube:
Omówienie
<progress>
dostarcza użytkownikom wizualną i dźwiękową informację o ukończeniu zadania. Ten
opinie wizualne są przydatne w przypadku takich scenariuszy, jak: postęp w wypełnianiu formularza,
wyświetlanie informacji o pobieraniu lub przesyłaniu, a nawet pokazywanie,
wielkość postępu jest nieznana, ale prace wciąż trwają.
To Wyzwanie GUI pracowało z
istniejącego elementu HTML <progress>
, aby zaoszczędzić trochę wysiłku związanych z ułatwieniami dostępu.
kolory i układy zwiększają możliwości dostosowania
do wbudowanego elementu
zmodernizować komponent i lepiej dopasować go do systemów projektowania.
Markup
Element <progress>
chcę umieścić w nagłówku
<label>
tak
Mogę pominąć atrybuty jawne w relacjach na rzecz niejawnego
.
Oznaczyłem też element nadrzędny, na który wpływa stan wczytywania, więc
dzięki technologiom do odczytywania danych użytkownikowi.
<progress></progress>
Jeśli brak wartości value
, postęp elementu jest taki jak
nieokreślone.
Atrybut max
przyjmuje domyślnie wartość 1, więc postęp mieści się w zakresie od 0 do 1. Ustawiam max
na przykład jako 100 ustawi zakres od 0 do 100. Zdecydowałem się zmieścić w zakresie 0
i 1, co przełoży się na postęp na 0,5 lub 50%.
Postęp dodawania etykiet
W relacji niejawnej element postępu jest opakowany w taki sposób:
<label>Loading progress<progress></progress></label>
W mojej wersji demonstracyjnej dodaję etykietę dla czytników ekranu
.
Można to zrobić, zawijając tekst etykiety do obszaru <span>
i stosując kilka stylów.
aby usunąć go z ekranu:
<label>
<span class="sr-only">Loading progress</span>
<progress></progress>
</label>
Za pomocą tej usługi porównywania cen z WebAIM:
.sr-only {
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
Obszar, na który wpływa postęp wczytywania
Jeśli masz zdrowy wzrok, możesz łatwo powiązać wskaźnik postępu
z powiązanymi elementami i obszarami strony, ale użytkownicy niedowidzący mogą mieć
tak jasne. Możesz to poprawić, przypisując parametr
aria-busy
do elementu najwyższego poziomu, który zmieni się po zakończeniu wczytywania.
Ponadto wskaż zależność między postępem a strefą ładowania.
z
aria-describedby
<main id="loading-zone" aria-busy="true">
…
<progress aria-describedby="loading-zone"></progress>
</main>
Z języka JavaScript przełącz ustawienie aria-busy
na true
na początku zadania i na
false
po zakończeniu.
Dodania atrybutów Aria
Pośrednią rolą elementu <progress>
jest
progressbar
, nazwa została ustawiona dla pełnoletnich
w przypadku przeglądarek, które nie mają takiej roli. Dodałem też atrybut
indeterminate
, aby jednoznacznie ustawić element w stanie nieznanym, czyli
jest bardziej zrozumiały niż obserwacja elementu, dla którego nie ustawiono elementu value
.
<label>
Loading
<progress
indeterminate
role="progressbar"
aria-describedby="loading-zone"
tabindex="-1"
>unknown</progress>
</label>
Używaj
tabindex="-1"
, by możliwe było zaznaczenie elementu postępu w JavaScripcie. To ważne w przypadku:
czytnika ekranu, ponieważ skupienie się na postępach
poinformuje użytkownika o tym, jak daleko zaszedł aktualizowany postęp.
Style
Element postępu nie jest łatwy, jeśli chodzi o stylizację. Wbudowany kod HTML elementy zawierają specjalne ukryte części, które może być trudno wybrać i często pozwalają skonfigurować tylko ograniczony zestaw właściwości.
Układ
Style układu mają dawać pewne możliwości elastyczności w procesie tworzenia nowego układu. rozmiaru i pozycji etykiety. Dodano specjalny stan ukończenia, który może może być przydatnym, ale niewymaganym, dodatkowym elementem wizualnym.
Układ <progress>
Szerokość elementu postępu pozostaje nienaruszona, dzięki czemu może się zmniejszać i powiększać.
z ilością potrzebnej przestrzeni w projekcie. Style wbudowane są pomijane przez
Ustawianie wartości appearance
i border
na none
. Dzięki temu element może być
znormalizowane w różnych przeglądarkach, ponieważ każda przeglądarka ma własne style
.
progress {
--_track-size: min(10px, 1ex);
--_radius: 1e3px;
/* reset */
appearance: none;
border: none;
position: relative;
height: var(--_track-size);
border-radius: var(--_radius);
overflow: hidden;
}
Wartość 1e3px
dla _radius
wykorzystuje liczbę naukową
duża liczba, więc border-radius
jest zawsze zaokrąglany. Jest to odpowiednik
1000px
Zależy mi na tym, aby użyć dostatecznie dużej wartości,
Mogę go ustawić i zapomnieć go (i napis jest krótszy niż 1000px
). Jest także
w razie potrzeby można go jeszcze bardziej powiększyć: wystarczy zmienić 3 na 4, a 1e4px
odpowiednik 10000px
.
Styl overflow: hidden
jest używany i jest spornym. Dzięki temu udało mu się
dużo łatwiejsze, na przykład nie trzeba przekazywać wartości border-radius
do funkcji
śledzenie i śledzenie elementów wypełnienia; ale też nie oznaczał dla dzieci postępów
mogą znajdować się poza granicami tego elementu. Kolejna iteracja tego niestandardowego postępu
można wykonać bez użycia funkcji overflow: hidden
. Może on otworzyć
i lepszy stan ukończenia.
Gotowe
Selektory CSS wykonują tu najtrudniejszą pracę, porównując wartość maksymalną z wartością. Jeśli się zgadzają, kończy się proces. Gdy to zrobisz, zostanie wygenerowany pseudoelement, który zostanie dołączony na końcu elementu postępu, co stanowi dodatkowy wizualny sygnał potwierdzający zakończenie.
progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
content: "✓";
position: absolute;
inset-block: 0;
inset-inline: auto 0;
display: flex;
align-items: center;
padding-inline-end: max(calc(var(--_track-size) / 4), 3px);
color: white;
font-size: calc(var(--_track-size) / 1.25);
}
Kolor
Przeglądarka ma własne kolory dla elementu postępu i dostosowuje się jasne i ciemne za pomocą tylko jednej właściwości CSS. Można go opracować przy użyciu specjalne selektory dla konkretnej przeglądarki.
Jasne i ciemne style przeglądarki
Aby włączyć na stronie ciemny i jasny adaptacyjny element <progress>
:
Wystarczy color-scheme
.
progress {
color-scheme: light dark;
}
Kolor wypełnienia pojedynczej usługi
Aby zmienić odcień elementu <progress>
, użyj accent-color
.
progress {
accent-color: rebeccapurple;
}
Zwróć uwagę, że kolor tła ścieżki zmienia się z jasnego na ciemny w zależności od
accent-color
Przeglądarka zapewnia odpowiedni kontrast: całkiem schludnie.
W pełni niestandardowe jasne i ciemne kolory
Ustaw 2 właściwości niestandardowe elementu <progress>
, jedną dla koloru ścieżki
a drugi – kolor postępu ścieżki. Wewnątrz
prefers-color-scheme
zapytania o media, podaj nowe wartości kolorów dla ścieżki i śledź postęp.
progress {
--_track: hsl(228 100% 90%);
--_progress: hsl(228 100% 50%);
}
@media (prefers-color-scheme: dark) {
progress {
--_track: hsl(228 20% 30%);
--_progress: hsl(228 100% 75%);
}
}
Zaznacz style
Wcześniej przypisaliśmy temu elementowi ujemny indeks tabulacji, dzięki czemu można go automatycznie
skupieni. Używaj
:focus-visible
do
Dostosuj ostrość, aby korzystać z inteligentniejszego pierścienia. Dzięki temu
pierścień zaznaczenia nie pojawi się, ale za pomocą klawiatury.
Więcej informacji jest dostępnych w filmie w YouTube.
warto się z nim zapoznać.
progress:focus-visible {
outline-color: var(--_progress);
outline-offset: 5px;
}
Style niestandardowe w różnych przeglądarkach
Dostosuj style, wybierając elementy elementu <progress>
, z których każdy
co pokazuje przeglądarka. Użycie elementu postępu to pojedynczy tag, a składa się z
elementów podrzędnych, które są wyświetlane przez pseudoselektory CSS. Narzędzia deweloperskie w Chrome
spowoduje wyświetlenie następujących elementów, jeśli włączysz to ustawienie:
- Kliknij stronę prawym przyciskiem myszy i wybierz Zbadaj element, aby wyświetlić Narzędzia deweloperskie.
- Kliknij koło zębate ustawień w prawym górnym rogu okna Narzędzia deweloperskie.
- W nagłówku Elements znajdź i włącz opcję Pokaż cień klienta użytkownika. DOM.
Style w Safari i Chromium
Przeglądarki oparte na silnikach WebKit, takie jak Safari i Chromium, ujawniają
::-webkit-progress-bar
i ::-webkit-progress-value
, które zezwalają na podzbiór
CSS, który ma być używany. Na razie ustaw background-color
za pomocą właściwości niestandardowych
które dostosowują się do oświetlenia i ciemności.
/* Safari/Chromium */
progress[value]::-webkit-progress-bar {
background-color: var(--_track);
}
progress[value]::-webkit-progress-value {
background-color: var(--_progress);
}
Style w przeglądarce Firefox
Firefox wyświetla pseudoselektor ::-moz-progress-bar
tylko na stronie
<progress>
. Oznacza to również, że nie możemy zmienić zabarwienia ścieżki bezpośrednio.
/* Firefox */
progress[value]::-moz-progress-bar {
background-color: var(--_progress);
}
Zwróć uwagę, że kolor ścieżki w przeglądarce Firefox został ustawiony na accent-color
, a w iOS Safari.
ma jasnoniebieską ścieżkę. Tak samo jest w trybie ciemnym: Firefox ma ciemną ścieżkę, ale
jest inny niż ustawiony przez nas kolor niestandardowy i działa w przeglądarkach opartych na pakiecie WebKit.
Animacja
Podczas pracy z wbudowanymi pseudoselektorami w przeglądarce często używa się dopuszczalnych właściwości CSS.
Animacja wypełniania ścieżki
Dodaję przejście do
inline-size
z
element postępu działa w Chromium, ale nie w Safari. Firefox też
nie używaj właściwości przejścia w jego zmiennej ::-moz-progress-bar
.
/* Chromium Only 😢 */
progress[value]::-webkit-progress-value {
background-color: var(--_progress);
transition: inline-size .25s ease-out;
}
Animowanie stanu :indeterminate
Teraz zrobię się nieco bardziej kreatywnie, więc mogę utworzyć animację. Pseudoelement dla Chromium i zostaje zastosowany gradient, dla wszystkich trzech przeglądarek.
Właściwości niestandardowe
Niestandardowe właściwości świetnie sprawdzają się w różnych zastosowaniach, ale jedną z moich ulubionych jest po prostu
nadanie nazwy wartości CSS, która ma inny wygląd. Dalej to już dość
Złożone
linear-gradient
ale z ładną nazwą. Jej cel i przypadki użycia są jasne.
progress {
--_indeterminate-track: linear-gradient(to right,
var(--_track) 45%,
var(--_progress) 0%,
var(--_progress) 55%,
var(--_track) 0%
);
--_indeterminate-track-size: 225% 100%;
--_indeterminate-track-animation: progress-loading 2s infinite ease;
}
Właściwości niestandardowe pomogą również w pozostawieniu kodu DRY, bo po raz kolejny nie możemy pogrupować selektory właściwe dla danej przeglądarki.
Klatki kluczowe
Celem jest uzyskanie nieskończonej animacji, która pojawia się w tę i z powrotem. początek i koniec.
klatki kluczowe zostaną ustawione w CSS. Potrzebna jest tylko 1 klatka kluczowa – środkowa klatka kluczowa.
w 50%
, by utworzyć animację, która wróci do miejsca, w którym się rozpoczęła,
znowu!
@keyframes progress-loading {
50% {
background-position: left;
}
}
Kierowanie na każdą przeglądarkę
Nie każda przeglądarka umożliwia tworzenie pseudoelementów w <progress>
.
lub animowanie paska postępu. Więcej przeglądarek obsługuje
animowanie ścieżki niż pseudoelement, więc uaktualniam pseudoelementy jako
na bazie animacji.
Pseudoelement Chrome
Chromium zezwala na pseudoelement: ::after
używany z pozycją zasłonięcia
elementu. Używane są nieokreślone właściwości niestandardowe, a
że czwarta animacja działa bardzo dobrze.
progress:indeterminate::after {
content: "";
inset: 0;
position: absolute;
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
Pasek postępu w Safari
W przeglądarce Safari właściwości niestandardowe i animacja są stosowane do obiektu pseudoelementowy pasek postępu:
progress:indeterminate::-webkit-progress-bar {
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
Pasek postępu przeglądarki Firefox
W przeglądarce Firefox właściwości niestandardowe i animacja są również stosowane do elementu pseudoelementowy pasek postępu:
progress:indeterminate::-moz-progress-bar {
background: var(--_indeterminate-track);
background-size: var(--_indeterminate-track-size);
background-position: right;
animation: var(--_indeterminate-track-animation);
}
JavaScript
JavaScript odgrywa ważną rolę z elementem <progress>
. Kontroluje to
wysyłaną do elementu wartość i zapewnia, że w parametrze
do czytników ekranu.
const state = {
val: null
}
W wersji demonstracyjnej dostępne są przyciski do kontrolowania postępu. aktualizowanie: state.val
a potem wywołaj funkcję aktualizacji
DOM.
document.querySelector('#complete').addEventListener('click', e => {
state.val = 1
setProgress()
})
setProgress()
Ta funkcja służy do administrowania UI/UX. Zacznij od utworzenia
setProgress()
. Parametry nie są potrzebne, ponieważ ma on dostęp do
Obiekt state
, element postępu i strefa <main>
.
const setProgress = () => {
}
Ustawiam stan wczytywania w strefie <main>
W zależności od tego, czy przetwarzanie został ukończony, czy nie, powiązane <main>
wymaga aktualizacji
aria-busy
.
:
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
}
Wyczyść atrybuty, jeśli ilość wczytywania jest nieznana
Jeśli wartość jest nieznana lub nieskonfigurowana, null
w przypadku tego zastosowania usuń value
i
Atrybuty: aria-valuenow
. Spowoduje to zmianę stanu <progress>
na nieokreślony.
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
}
Rozwiązywanie problemów z matematyką liczb dziesiętnych w JavaScripcie
Zdecydowałam się zachować domyślne maksimum postępu, czyli 1, dlatego wersja demonstracyjna
Funkcje zwiększania i zmniejszania liczby używają wartości dziesiętnych. JavaScript i inne
ale nie zawsze są też świetne
.
Oto funkcja roundDecimals()
, która pozwoli uniknąć nadmiaru informacji matematycznych
wynik:
const roundDecimals = (val, places) =>
+(Math.round(val + "e+" + places) + "e-" + places)
Zaokrąglaj wartość, aby była widoczna i czytelna:
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
}
Ustaw wartość czytników ekranu i stanu przeglądarki
Wartość jest używana w 3 miejscach w modelu DOM:
- Atrybut
value
elementu<progress>
. - Atrybut
aria-valuenow
. - Wewnętrzna zawartość tekstowa w
<progress>
.
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
progress.value = val
progress.setAttribute('aria-valuenow', valPercent)
progress.innerText = valPercent
}
Koncentracja na postępach
Po zaktualizowaniu wartości widzący użytkownicy zobaczą zmianę postępu, ale na ekranie
czytelnicy nie otrzymali jeszcze ogłoszenia o zmianie. Zaznacz
<progress>
, a przeglądarka poinformuje o aktualizacji.
const setProgress = () => {
zone.setAttribute('aria-busy', state.val < 1)
if (state.val === null) {
progress.removeAttribute('aria-valuenow')
progress.removeAttribute('value')
progress.focus()
return
}
const val = roundDecimals(state.val, 2)
const valPercent = val * 100 + "%"
progress.value = val
progress.setAttribute('aria-valuenow', valPercent)
progress.innerText = valPercent
progress.focus()
}
Podsumowanie
Wiesz już, jak to zrobiłem. Jak Ty? 🙂
Z pewnością chcę wprowadzić kilka zmian, jeśli mam jeszcze szansę. Myślę, że jest miejsce na uporządkowanie bieżącego komponentu i stworzenie takiego elementu bez ograniczeń pseudoklasowych elementów <progress>
. Warto się tego przyjrzeć!
Stosujmy różne podejścia i poznajmy sposoby budowania obecności w internecie.
Utwórz wersję demonstracyjną, a potem dodaj linki do funkcji tweetuj mi. znajdziesz poniżej w sekcji z remiksami na karcie Społeczność.