Element progress

26 października 2013
1 gwiadka2 gwiazdki3 gwiazdki4 gwiazdki5 gwiazdek

Podstawowa składnia elementu progress:

<progress></progress>

Zgodnie ze specyfikacją W3C element progres reprezentuje postęp wykonywania zadania. Musi mieć znacznik otwierający (<progress>) i zamykający (</progress>), mimo że wygląda jak tzw. element zastępowany (podobnie jak elementy input). Jest to niezwykle pomocne przy stosowaniu pomocniczej treści, którą zastosujemy później.

Obok głównych atrybutów, element <progress> może mieć jeszcze dwa inne:

  • max – wskazuje jak dużo zostało do wykonania, aby uznać proces za skończony. Jeśli nie zostanie określony, domyślna wartość wynosi 1.0
  • value – określa obecny stan postępu. Musi być większy bądź równy 0.0 i mniejszy lub równy 1.0 lub mieć wartość atrybutu max (jeśli również został zdefiniowany).

Stany paska postępu

Pasek postępu może mieć dwa stany – nieokreślony i określony.

Stan nieokreślony

Nieokreślony stan paska postępu w Chrome 29 na Mac OS 10.8:

Nieokreślony stan paska postępu w Chrome 29 na Mac OS 10.8

W zależności od przeglądarki i systemu operacyjnego, pasek postępu może mieć różny wygląd. Zoltan „Du Lac” Hawryluk opisuje w swoim artykule (warto przeczytać) zachowania elementu progress w różnych przeglądarkach. Wufoo ma zrzuty ekranu paska postępu w różnych systemach operacyjnych.

Bardzo łatwo jest znaleźć i sformatować nieokreślony pasek postępu, ponieważ wiemy że nie ma on atrybutu value. Do formatowania możemy użyć pseudoklasy :not().

progress:not([value]) {
   /* Formatowanie*/
}

Stan określony

W tym artykule skupimy się wyłącznie na formatowniu określonego stanu paska postępu. Zmieńmy więc jego stan poprzez dodanie atrybutów max i value.

<progress max="100" value="80"></progress>

Tak wygląda pasek postępu w Chrome 29 w systemie Mac OS 10.8, pozbawiony stylów CSS.

Określony stan paska postępu w Chrome 29 na Mac OS 10.8

Określony stan paska postępu w Chrome 29 na Mac OS 10.8

Pamiętaj, że dodanie atrybutu max nie zmieni stanu paska postępu, ponieważ przeglądarka nie wie jaką wartość ma przedstawiać.

To wszystko co możemy zrobić za pomocą HTML, resztą zajmie się CSS. W tym miejscu nie martwmy się o obsługę omawianego elementu przez starsze przeglądarki, które go nie rozpoznają.

Formatowanie paska postępu

Możemy namierzyć określony pasek postępu, korzystając z selektora progress[value]. Sam progress też może być, jeśli wiadomo, że w kodzie nie ma żadnych nieokreślonych pasków postępu. Będę korzystał z pierwszej metody, ponieważ lepiej rozróżnia te dwa stany. Tak jak każdemu innemu elementowi , paskowi postępu można nadać wymiary przy użyciu własności width i height:

progress[value] {
  width: 250px;
  height: 20px;
}

Tu kończy się przyjemna część i zaczynają się problemy, ponieważ każda kategoria przeglądarek formatuje pasek postępu przy użyciu innych pseudoklas. Uprościmy sprawę i nie będziemy specjalnie przejmować się tym, która wersja przeglądarki obsługuje element progress. Wszystkie niedogodności rozwiążemy stosując rozwiązanie pomocnicze. Wyróżniamy następujące rodzaje przeglądarek:

  • WebKit/Blink
  • Firefox
  • Internet Explorer

WebKit/Blink (Chrome, Safari, Opera)

Google Chrome, Apple Safari, a także najnowsza wersja Opery (16+) należą do jednej kategorii. Jest to oczywiście zasługa stylów CSS przeglądarek Webkit, które używają własności -webkit-appearance: progress-bar do określania wyglądu elementu progress.

Arkusz stylów przeglądarek opartych na webkit

Arkusz stylów przeglądarek opartych na webkit

Do resetowania stylów użyjemy własności -webkit-appearance z wartością none.

progress[value] {
  /* Nadpisywanie domyślnych stylów */
  -webkit-appearance: none;
   appearance: none;

  width: 250px;
  height: 20px;
}
Domyślny wygląd paska postępu

Domyślny wygląd paska postępu

Podczas dalszej inspekcji elementu progress w narzędziach deweloperskich Chrome, możemy zobaczyć jak zostało to zaimplementowane.

Zrzut ekranu narzędzi deweloperskich chrome

Zrzut ekranu narzędzi deweloperskich chrome

Webkit/Blink mają dwie pseudoklasy do formatowania elementu progress:

  • -webkit-progress-bar – pseudoklasa formatująca kontener elementu progress. W tym przykładzie zmienimy kolor tła, obramowanie i dodamy wewnętrzny cień dla kontenera.
  • -webkit-progress-value – pseudoklasa formatująca wartość paska postępu. Własność background-color domyślnie ustawiona jest na green, co możemy sprawdzić w narzędziach deweloperskich. W tym przykładzie stworzymy efekt przesuwającychy się pasków za pomocą gradientu liniowego we własności background-image.

Najpierw nadamy styl kontenerowi przy użyciu własności -webkit-progress-bar:

progress[value]::-webkit-progress-bar {
  background-color: #eee;
  border-radius: 2px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}
Kontener paska postępu z nadanym stylem

Kontener paska postępu z nadanym stylem

Następnie dodamy styl dla paska przy użyciu własności -webkit-progress-value, definiując kilka gradientów tła. Jeden dla pasków, cienie na górze i na dole, przejścia kolorów z prawej do lewej. Skorzystamy z prefiksu -Webkit dla gradientów, ponieważ używamy go także dla samego paska postępu.

progress[value]::-webkit-progress-value {
  background-image:
	   -webkit-linear-gradient(-45deg, 
	                           transparent 33%, rgba(0, 0, 0, .1) 33%, 
	                           rgba(0,0, 0, .1) 66%, transparent 66%),
	   -webkit-linear-gradient(top, 
	                           rgba(255, 255, 255, .25), 
	                           rgba(0, 0, 0, .25)),
	   -webkit-linear-gradient(left, #09c, #f44);

    border-radius: 2px; 
    background-size: 35px 20px, 100% 100%, 100% 100%;
}
Pasek z nadanymi stylami

Pasek z nadanymi stylami

Animacje

W czasie pisania tego artykułu tylko przeglądarki oparte na silniku Webkit/Blink obsługiwały animacje elementu progress. Dodamy animację wykorzystując własność -webkit-progress-value i zmieniając pozycję tła.

@-webkit-keyframes animate-stripes {
   100% { background-position: -100px 0px; }
}

@keyframes animate-stripes {
   100% { background-position: -100px 0px; }
}

Zastosujemy tę animację do selektora -webkit-progress-value:

-webkit-animation: animate-stripes 5s linear infinite;
        animation: animate-stripes 5s linear infinite;

Pseudoelementy

W czasie pisania tego artykułu tylko przeglądarki oparte na silniku Webkit/Blink obsługiwały pseudoelementy ::before i ::after dla elementu progress. Poprzez samo spojrzenie na pasek postępu nie ma możliwości odczytania jego wartości. Możemy rozwiązać ten problem wyświetlając jego wartość na samym końcu paska za pomocą pseudoelementów ::before i ::after.

progress[value]::-webkit-progress-value::before {
  content: '80%';
  position: absolute;
  right: 0;
  top: -125%;
}
Pseudoelement w akcji

Pseudoelement w akcji

Niestety content: attr(value) nie działa na elemencie progress. Zadziała jednak, jeśli jawnie określisz tekst wewnątrz atrybutu. Nie udało mi się ustalić, jaka jest tego przyczyna. Działa to tylko w przeglądarkach opartych na silniku Webkit/Blink, więc nie ma powodu do osadzania zawartości w pseudoelementach, przynajmniej na razie.

Za pomocą pseudoelementu ::after możemy utworzyć ładne zakończenie paska postępu. Przedstawione metody są w stanie eksperymentalnym i nie są zalecane jeśli zależy Ci na zgodności z wieloma przeglądarkami.

progress[value]::-webkit-progress-value::after {
  content: '';
  width: 6px;
  height: 6px;
  position: absolute;
  border-radius: 100%;
  right: 7px;
  top: 7px;
  background-color: white;
}

Firefox

Podobnie jak Webkit/Blink, Firefox także korzysta z własności -moz-appearence: progressbar do wyświetlania elementu progress.

Zrzut ekranu z Firebuga

Zrzut ekranu z Firebuga

Korzystając z własności appearence: none pozbędziemy się domyślnych wytłoczeń i skosów. Niestety, takie działanie zostawia w Firefoksie delikatne obramowanie. Możemy się go pozbyć za pomocą ustawienia border: none. Rozwiązuje to także problem z obramowaniem w Operze 12.

progress[value] {
  /* Nadpisywanie domyślnych stylów */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  
  /* Usuwanie domyślnego obramowania w Firefoxie */
  border: none;
  
  /* Rozmiar */
  width: 250px;
  height: 20px;
}
Delikatne obramowanie w Firefoksie i Operze

Delikatne obramowanie w Firefoksie i Operze

Firefox ma tylko jedną pseudoklasę (-moz-progress-bar), za pomocą której może odwoływać się do paska postępu. Oznacza to, że nie nadamy stylów kontenerowi w tej przeglądarce.

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, 
      #09c, 
      #f44
    );

  border-radius: 2px; 
  background-size: 35px 20px, 100% 100%, 100% 100%; 
}

Firefox nie obsługuje pseudoklas ::before i ::after dla elementu progress, a także nie pozwala na użycie keyframe animation w pasku postępu.

Internet Explorer

Internet explorer w wersji 10+ standardowo obsługuje pasek postępu, ale tylko częściowo. Pozwala na zmianę koloru wartości paska. Internet Explorer implementuje wartość paska postępu jako atrybut color, a nie background-color.

progress[value]  {
  /* Nadpisywanie domyślnych stylów */
     -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;

  /* Usuwanie domyślnego obramowania w Firefoksie */
  border: none;

  /* Rozmiar */
  width: 250px;
  height: 20px;

  /* IE10 */
  color: blue; 
}

Co ze starymi przeglądarkami

Element progress jest standardowo obsługiwany przez przeglądarki Firefox 16+, Opera 11+, Chrome oraz Safari 6+. IE10+ obsługuje go częściowo. Jeżeli chcesz zapewnić obsługę dla starszych przeglądarek, masz dwa wyjścia.

Wypełniacz elementu progress Lea Verou

Świetny wypełniacz Lea Vearou sprawia, że element progress jest prawie w pełni obsługiwany przez przeglądarki Firefox 2.5-15, Opera 10.5-10.63 oraz IE9-10. Częściowa obsługa zapewniona jest także w IE8. Wystarczy dodać plik progress-polyfill.js do pliku HTML, a także selektory CSS, których używa skrypt. Jeżeli chcesz dowiedzieć się więcej na temat jego używania, sprawdź kod źródłowy na stronie projektu.

Pomocniczy HTML

Jest to mój ulubiony sposób. Skorzystamy z powszechnie znanej techniki, która jest wykorzystywana przy stosowaniu elementów audio i video.

<progress max="100" value="80">
    <div class="progress-bar">
        <span style="width: 80%;">Progress: 80%</span>
    </div>
</progress>

Zasymulujemy wygląd paska postępu za pomocą znaczników div i span wewnątrz znacznika progress. Nowsze przeglądarki ignorują zawartość wewnątrz znacznika progress. Starsze przeglądarki, które nie rozpoznają elemementu progress zignorują go i wyświetlą wewnętrzny kod.

.progress-bar {
  background-color: whiteSmoke;
  border-radius: 2px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;

  width: 250px;
  height: 20px;
  
  position: relative;
  display: block;
}
  
.progress-bar > span {
  background-color: blue;
  border-radius: 2px;

  display: block;
  text-indent: -9999px;
}

Obie techniki są często stosowane i na dodatek bezpieczne nawet na stronach produkcyjnych. Mając styl do jednego paska, kolejne możemy formatować korzystając z klas.

Autor: Chris Coyier

Źródło: http://css-tricks.com/html5-progress-element/

Tłumaczenie: Piotr Janczukowicz

Dyskusja

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *