Tworząc aplikacje przeglądarkowe powinniśmy zrobić wszystko, aby użytkownicy korzystający z nich czuli jak największy komfort. Powinno zależeć nam na dobrej optymalizacji skryptów, jak najmniejszej liczbie przeładowań strony oraz prostocie i intuicyjności interfejsu. Nawet jeżeli klient końcowy musi czekać, powinniśmy go o tym informować. Informacja, niezależnie od tego jaka jest, znacznie lepiej wpływa na wewnętrzny spokój aniżeli jej zupełny brak, okraszony białym ekranem przeglądarki obliczającej coś w tle. Z tego więc powodu pokażę Ci jak stworzyć prosty preloader, korzystający tylko i wyłącznie z możliwości CSS3. Do jego działania nie będzie więc potrzebna włączona obsługa Javascriptu, co jest naprawdę (uwierzcie) mile widziane.
Zobacz działanie preloadera na poniższym wideo.
Kod HTML loadera
- Utwórz kontener o klasie loader .
- Umieść w nim kilka niedużych ikon lub innych elementów (np. <div>). Ja użyłem do tego 6 identycznych sygnetów z loga WEBroad.pl
1 2 3 4 5 6 7 8 9 | <h3 id="progress_info">Trwa obliczanie... Proszę czekać.</h3> <div class="loader"> <img src="webroad-mini.png" alt=""> <img src="webroad-mini.png" alt=""> <img src="webroad-mini.png" alt=""> <img src="webroad-mini.png" alt=""> <img src="webroad-mini.png" alt=""> <img src="webroad-mini.png" alt=""> </div> |
Kod CSS loadera
Najpierw ostyluj kontener loader . Oczywiście pozostawiam Ci pełną dowolność. Ja akurat chciałem ustawić go w centrum ekranu z efektem cienia wewnętrznego.
1 2 3 4 5 6 7 8 9 10 11 | .loader { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; box-shadow: inset 0px -5px 3px -3px rgba(0,0,0,0.1), inset 0px 5px 3px -3px rgba(0,0,0,0.1); padding: 10px; overflow: hidden; min-width: 400px; } |
Zajmijmy się teraz ikonkami preloadera. Pokażę Ci w jaki sposób wprawić je w ruch, tak aby spadały z góry, zatrzymywały się na chwilę na środku swojej drogi i w końcu chowały się za dolną krawędzią obszaru ograniczonego przez rodzica.
Stwórz nową animację w CSS3 o nazwie loader .
1 2 3 4 5 6 7 8 9 | @keyframes loader{ 0% {transform: translateY(-150px);} 20% {transform: translateY(30px);} 30% {transform: translateY(-10px);} 40% {transform: translateY(0);} 60% {transform: translateY(0);} 80% {transform: translateY(-20px);} 100% {transform: translateY(150px);} } |
Jeżeli przypiszemy ją do każdej ikonki otrzymamy efekt spadania ale niestety w równej kolejności, co nie wygląda tak efektownie.
1 2 3 4 5 6 | .loader img{ width: 40px; height: 40px; margin: 5px; animation: loader 1.75s infinite ease-in-out; } |
Dla urozmaicenia przygotowałem więc różne style dla co czwartego obiektu. Będzie je różnić tylko i wyłącznie opóźnienie wykonywania animacji. Dzięki temu najpierw „ruszy” ikona pierwsza i w ustalonych odstępach pozostałe.
1 2 3 4 5 6 7 8 9 10 11 12 | .loader img:nth-child(4n+1){ animation-delay: 0ms; } .loader img:nth-child(4n+2){ animation-delay: 200ms; } .loader img:nth-child(4n+3){ animation-delay: 1000ms; } .loader img:nth-child(4n+4){ animation-delay: 1000ms; } |
Dostępność
// Akapit został dodany po dyskusji, która zrodziła się w komentarzach. Dziękuję za odzew.
Aby zapewnić dobrą dostępność powyższego rozwiązania, powinniśmy dodać do kontenera .loader dodatkowe atrybuty:
[role] + [aria-labelledby]
1 | <div class="loader" role="progressbar" aria-labelledby="progress_info">...</div> |
Podsumowanie
Otrzymaliśmy ładny efekt preloadera, który możemy wdrożyć do naszych przyszłych i obecnych projektów. Zachęcam do modyfikacji i podzielenia się nią w komentarzach.
W powyższym przykładzie, dla zmniejszenia ilości kodu nie używałem w tworzeniu animacji przedrostków dla przeglądarek. Pamiętaj, aby je dodać w końcowym projekcie, jeżeli są potrzebne.
Tagi: CSS3 • preloader • promowany
Co do przedrostków – warto zastosować Autoprefixer.
Wielka szkoda, że całkowicie pominąłeś aspekt dostępności, np [aria-label] + [role] dla .loader i puste [alt] dla obrazków.
Myślę, że to trochę szukanie dziury w całym. aria i role każdy doda, kto tego będzie potrzebować no i nic nie zaciemnia meritum wpisu. Preloader można wykorzystać nie tylko na stronach, a na przykład w ekranie ładowania aplikacji mobilnej.
Efekt ciekawy :)
Owszem, byłoby to szukanie dziury w całym, gdyby istniała jakakolwiek świadomość aspektów dostępności w środowisku. Ale nie istnieje i *NIKT* nie doda do kodu [role] i etykietki, bo… 90% webmasterów nawet nie wie o istnieniu tego typu rzeczy. A nie zapominajmy, że na WEBroad niekoniecznie zaglądają profesjonaliści, a po prostu ludzie szukający ciekawego pluginu na stronę. Oni tym bardziej nie będą się przejmować „jakąś dostępnością”.
Tak, efekt wizualny ciekawy, ale to… efekt wizualny – nic więcej. Obecnie rozwiązanie to nie posiada nawet warstwy semantycznej (ok, nagłówek jakoś sprawę ratuje – ale co z obrazkami?). Kontekst użycia nic tutaj nie zmienia – webowe aplikacje mobilne, odpalane przez WebView, to wciąż strony, które przecież dla osób niepełnosprawnych są prezentowane właśnie w taki sposób.
Nie będziemy mieli dostępnej Sieci, jeśli sami o to nie zadbamy. Taka prawda.
W sumie można by to pogodzić i nie wrzucać takich dodatków do głównych listingów (bo nadmiernie rozpychają proste przykłady), ale dodawać ramkę na końcu z dobrymi praktykami odnośnie dostępności…
Cóż… na pewno jest to jakieś kompromisowe rozwiązanie. Co prawda nie do końca by mnie zadowalało, ale przynajmniej byłyby o tym jakieś informacje.
Problem polega na tym, że wg mnie dostępność to podstawa. Pomijam już fakt, że brak [alt] czyni ten HTML po prostu niepoprawny składniowo.
Okej, racja. Dodałem puste [alt], bo zupełnie o nich zapomniałem.
Co do dostępności, dopisałem akapit. Dziękuję.
Intryguje mnie, dlaczego wykorzystujesz ?
Tylko dlatego, aby nie rozbudowywać tu kodu.
W tekście napisałem, że można użyć innych elementów.
A jak takiego loadera użyć w momencie przechodzenia między podstronami? Chodzi mi o to, żeby pierwsze pojawił się loadare, a po wczytaniu całej strony „w tle” dopiero wczytana stronka.
Tricky one ;)
Trzeba najpierw zaimplementować obsługę History API, po czym Ajaksem ciągnąć daną podstronę. Zestawienie żądania = pokazanie loadera, zakończenie żądania = ukrycie loadera
Preloader? Zawsze myślałem, że preloader pokazuje ilość załadowanych danych, które są pobierane progresowo. A tutaj widzę stworzoną animację (co prawda ciekawą) za pomocą CSS.