Progressive Enhancement – zapomniany fundament


10 listopada 2014 / Comandeer


Progressive Enhancement - nieoficjalne logo

Każdy architekt, zapytany o tajemnicę perfekcyjnego domu, bez zająknięcia odpowie, że cała zasługa spływa na porządny fundament. O tej prastarej prawdzie nie mogą także zapomnieć dzisiejsi webmasterzy – architekci stron i aplikacji internetowych.

Warstwy stron (aplikacji) internetowych

Żeby wiedzieć jak zbudować dom, najpierw trzeba wiedzieć z czego się składa! Nie inaczej jest w wypadku stron internetowych. Tak, jak w domu mamy piętra, tak na stronie internetowej możemy wyróżnić poszczególne warstwy:

Wizualne przedstawienie warstw strony internetowej

  • treść
  • semantyka i metadane (HTML lub inny język spełniający jego funkcję)
  • prezentacja (najczęściej CSS)
  • zachowanie (najczęściej JS)

Każda kolejna warstwa nie może istnieć bez poprzedniej (tak, jak nie można zbudować 3. piętra, zapominając najpierw o parterze), lecz równocześnie każda jest całkowicie niezależna (wyobrażacie sobie, że wasz sąsiad z piętra wyżej musi codziennie przechodzić przez wasze mieszkanie?).

Przyjrzyjmy się teraz pokrótce każdej warstwie.

Treść

Treść to… treść. Jest niezbędnym elementem każdej strony internetowej (mimo że niektórzy zdają się twierdzić inaczej) i de facto nic bez niej nie może istnieć. To właśnie dla niej tworzysz stronę, bo chcesz coś ludziom przekazać. Jeśli natomiast tworzysz aplikację internetową, treścią staje się to, co jest w stanie stworzyć w niej użytkownik (zatem dajesz możliwość stworzenia treści, zamiast czegoś gotowego). Zapewne nic nowego nie odkrywam, pisząc te oczywiste oczywistości, lecz warto powiedzieć to głośno i wyraźnie: content is the king. I tyle ;)

Semantyka i metadane

W praktyce ta warstwa jest tak bardzo zrośnięta z treścią, że być może sensowniejsze byłoby traktowanie ich jako jedną, nierozłączną całość. Mimo wszytko, ze względów czysto „technicznych” (ok, za dużo ostatnio naczytałem się strukturalistów…) postanowiłem ją wydzielić.

Warto się bowiem zastanowić czemu warstwa semantyki i metadanych ma służyć. Jej rodowód wywodzi się z najbardziej podstawowych założeń Internetu, jako Sieci dokumentów połączonych wzajemnymi relacjami. Relacjami na tyle skomplikowanymi, że nie biegną w żaden linearny sposób, lecz mogą się rozgałęziać, przecinać, odsyłać do siebie samych, cofać użytkownika do już odwiedzonych stron czy po prostu zapędzając w kozi róg. Ot, magia hipertekstualności. Nie jest zaskoczeniem, że w tak skomplikowanej sieci wzajemnych powiązań sama treść nie wystarcza. Internet samego tekstu byłby całkowicie niestrawny, stąd potrzeba technicznego sposobu na dodatkowe oznaczenie tego, co w treści znaczy. I tutaj na scenę wkracza najczęściej HTML (lub XML, lub – w mniejszym stopniu – Markdown, BBCode itd.).

Pierwszymi odbiorcami, którzy mogą skorzystać z dobrodziejstw HTML-a, są oczywiście użytkownicy. Dzięki niemu możliwe są tak podstawowe czynności, jak przejście na inną podstronę czy wyświetlenie pewnych danych w seksownej tabelce. Jest to o tyle ważne, że najbardziej na dobrze oznaczonej semantycznie stronie skorzystają użytkownicy niepełnosprawni – głównie niewidomi i niedowidzący, korzystający z czytników ekranowych. Dla nich nawet tak podstawowe rzeczy, jak dodanie poprawnych [alt] do obrazków może diametralnie poprawić ich komfort korzystania ze strony. Dlatego, mimo powolnej agonii starego, dobrego semantycznego HTML-a, należy go stosować (bo raczej nie chcemy być zimnymi dupkami, którzy z góry skreślają niepełnosprawnych, czyż nie?) – nawet jeśli jest to zajęcie nudne i czasochłonne.

A jeśli ten argument nikogo już dzisiaj nie rusza, to warto też zwrócić uwagę na to, że semantykę serwowaną użytkownikom reużywają także wyszukiwarki, w tym de facto monopolistyczny Google. Zatem to, co jest dobre dla naszych użytkowników, zwykle jest także dobre dla Wujka G.

Oczywiście oprócz samej semantyki i dodatkowych metadanych, HTML zapewnia całkowicie podstawową funkcjonalność stron internetowych, jak np. prymitywne sposoby przesyłania danych na serwer (formularze!) czy właśnie legendarne dziś już linki. Zatem używając tylko i wyłącznie sam HTML, można przygotować sensowny fundament dla naszej strony.

Prezentacja

Obecnie każda strona internetowa musi wyglądać ładnie, żeby przyciągnąć internautów (wszak widzieli już wszystko, prawda?). W tym celu do naszej treści należy dołożyć dodatkowo jakiś ładny, efektowny (ale nie niepotrzebnie efekciarski) wygląd. Praktycznie w każdym wypadku osiąga się to przy pomocy języka CSS. Oczywiście jest on wspomagany przez całą gamę narzędzi i zasobów, takich jak preprocesory CSS, animacje, obrazki itp. Im bardziej użytkownicy stają się wymagający, tym bardziej CSS staje się skomplikowany, ale równocześnie pozwala tworzyć coraz ładniejsze strony internetowe.

Jeśli HTML określa to, co chcemy przekazać, to CSS określa jak chcemy to przekazać.

Zachowanie

Warstwa zachowania to ostatnia z warstw, leżąca nad zarówno treścią, jak i prezentacją. Najczęściej jest implementowana przy pomocy języka JavaScript (a mówiąc jeszcze dokładniej: przy pomocy API DOM, które jest udostępniane przez przeglądarki). Najprościej ją wyjaśnić na podstawie prostego przykładu: w HTML definiujemy przycisk przy pomocy znacznika button, w CSS określamy, że ma być okrągły i czerwony, w JS natomiast mówimy przeglądarce, że po kliknięciu w niego ma się wyświetlić komunikat o nękaniu naszej strony internetowej.

JS pozwala na dodanie całkowicie nowego poziomu interaktywności do naszej strony. Przyciski w końcu będą coś robić, dane się będą przesyłać w tle a filmik będzie miał super wypasiony odtwarzacz.

Progressive Enhancement – ale że co?

I właśnie tutaj, w miejscu, w którym zdefiniowaliśmy warstwy strony internetowej, trzeba powiedzieć o technice, która łączy je w jedną, spójną całość: Progressive Enhancement – owy legendarny fundament Sieci, o którym niestety bardzo często się zapomina. A jego zasady są bardzo proste i nietrudne do wprowadzenia w życie.

Niezależność warstw

Na stronie każda z warstw powinna być od innej całkowicie oddzielna: treść + semantyka nie powinna wiedzieć nic o prezentacji a prezentacja nie powinna nawet uświadamiać sobie istnienia warstwy zachowania. Ta wiedza w innych dziedzinach programowania (czy nawet wśród programistów stricte JS-owych) jest ogólnie znana i zawarto ją w haśle loose coupling.

O co chodzi? W skrócie chodzi o to, że każda warstwa istnieje tylko i wyłącznie dla samej siebie, wykonując ściśle określone zadanie. Semantyka ma być semantyką i nie wchodzić w paradę warstwie zachowania. JS powinien jedynie zmieniać stan elementów strony (np zaznaczać która pozycja w menu aplikacji jest aktywna), ale nie mieć zielonego pojęcia jak ta aktywna pozycja wygląda (w tym wypadku takie połączenie JS ze stroną często jest także określane bardziej precyzyjnym pojęciem, jakim jest unobtrusive JS). Każdy logicznie myślący człowiek zdaje sobie sprawę z tego, że co prawda można zmieszać różne gatunki alkoholu (a nawet wypić je na pusty żołądek!), jednak prawie zawsze kończy się to dla nas źle. Nie inaczej jest w przypadku tworzenia stron i aplikacji internetowych. Początkowo mieszanie JS i HTML czy HTML i CSS (a nawet JS i CSS!) nie gryzie. Ba, do pewnego momentu jest wręcz przyjemne! A później nadchodzi potrzeba wprowadzenia jakiejś zmiany i wychodzi na to, że wygląd naszego przycisku jest definiowany w 3 różnych miejscach (w arkuszu stylów rzecz jasna, ale także w HTML przy pomocy [style] i w JS, przy pomocy elem.style) – co zmusza nas do wykonania 3 razy większej pracy. Jeśli warstwy byłyby całkowicie rozdzielone od siebie, ten problem by nie istniał (po prostu wygląd byłby całkowicie ustalony przy pomocy arkusza stylów i tyle).

Technicznie rzecz biorąc sprowadza się to do porzucenia takich wynalazków, jak atrybuty [style] i niesławne [on] w HTML czy elem.style w JS. Oczywiście musi istnieć jakiś sensowny sposób na komunikację między poszczególnymi warstwami (w bloku po prostu otwieramy okno i krzyczymy do sąsiada z góry czy z dołu; no, chyba że znamy ich numer telefonu lub pukamy miotłą w sufit). W przypadku stron internetowych takim krzykiem (telefonem) są klasy. Zmyślnie ich używając, można stworzyć swoisty system komunikacji pomiędzy HTML ↔ CSS ↔ JS. Klasa, którą nadamy elementowi w HTML (np. .button-submit) przekazuje wiadomość dalej. W tym momencie CSS już wie, że ten przycisk należy pokolorować na zielono i dodać animację mrugania, żeby użytkownik się nim zainteresował a JS już do niego dodało żądanie Ajaksem. Oczywiście to komunikacja dwustronna (no, chyba że wszyscy nasi sąsiedzi są głuchoniemi), zatem JS może zmienić stan tego przycisku nadając/usuwając mu jakąś klasę (np .button-submit--disabled), co powiadomi CSS o tym, że w tej chwili należy zmienić kolor przycisku na czerwony. Najlepszym przykładem jak dobrze tego typu komunikacja może działać, jest architektura BEM.

Małe kroczki

Drugim koniecznym warunkiem PE jest to, czemu zawdzięcza swoją nazwę: wychodzenie od rzeczy najprostszych do najbardziej złożonych. Innymi słowy mówiąc: nie można nigdy zakładać, że warstwa wyższa od najniższej istnieje.

Tak, wiem, że teraz co bardziej rozgarnięty czytelnik popuka się w czoło i stwierdzi: „JS działa zawsze”. Owszem, JS działa zawsze, chyba że nie działa.

Wyobraźmy sobie stronę internetową jako obrazek. Treść + semantyka to właśnie nasze bezcenne płótno, które chcemy chronić. Dlatego nanosimy na nie warstwę bezbarwnego lakieru (prezentacji), żeby chronić i uwidocznić wszystkie jego kolory. Następnie, w celu maksymalnej ochrony, całość dodatkowo chronimy za szkłem pancernym (warstwa zachowania). Dopiero tak zabezpieczony obraz wieszamy w muzeum. Owszem, nic się nie stanie, gdy zdejmiemy zarówno szkło pancerne, jak i warstwę lakieru (o ile nasi zwiedzający nie zapragną podpalić płótna) – obraz będzie tak samo ładny i przyjemny w odbiorze. Problem pojawia się, gdy lakier wgryzie się w płótno lub dodatkowo szkło pancerne się do niego przyklei. I choć początkowo problem ten można całkowicie zignorować, to brak zdecydowanej reakcji doprowadzi do zniszczenia naszego bezcennego obrazu (czy kiedykolwiek próbowaliście oderwać warte miliardy dolarów średniowieczne płótno od szyby?!). Te warstwy ochronne mają za zadanie ułatwiać odbiór dzieła, bez jakiejkolwiek ingerencji w nie. Właśnie tak działa PE.

Jak powyższe statystyki pokazują, co prawda osób bez JS jest ciut ponad 1%, jednakże najciekawsze są przyczyny braku obsługi tego języka. Aż 0.9% to ludzie, których przeglądarki JS obsługują, lecz nie są w stanie uruchomić skryptów na tej konkretnej stronie. Przyczyn tego stanu rzeczy może być dużo – najczęstsze to bug w nowej wersji przeglądarki czy po prostu pad naszego serwera, który dosyła nam pliki JS. Tylko 0.2% osób świadomie wyłącza JS. Co to oznacza? Że każdy może nie mieć JS – nawet ty czy ja! I to nie z naszej winy. Bardzo łatwo wyobrazić sobie sytuację podróży pociągiem i przeglądania Internetu na smartphonie. Wystarczy, że w chwili otwierania mega wypasionej super hiper pro strony wjedziemy do tunelu i tym samym na chwilę zabraknie Sieci. I co? I nie mamy JS. Taka sama sytuacja może dotyczyć także CSS.

W tym artykule przytoczyłem już przykład całkowicie czytelnej strony, zbudowanej tylko i wyłącznie przy użyciu semantycznego HTML-a. Jak widać, dało się jej używać – mimo że nie była ani piękna, ani nie dociągała tony JS. Tak wyglądają normalne strony WWW, odarte ze wszystkich dodatków. Kiedy już zaserwujemy użytkownikowi to, co go najbardziej interesuje (treść!), możemy się pomartwić o to, by była piękna (prezentacja!) i aby dodatkowo była całkiem interaktywna (warstwa zachowania!). Tym sposobem przechodzimy od rzeczy najprostszych (ale i najważniejszych!) do rzeczy najbardziej skomplikowanych (których jedynym zadaniem jest poprawa UX strony): treść → prezentacja → warstwa zachowania. Dzięki takiemu podejściu do projektowania, naturalne staje się to, że chcemy coś przekazać a nie to jak chcemy to zrobić. To, co filozofowie wiedzą od stuleci, webmasterzy zdają się wciąż dopiero odkrywać.

Rozważmy prosty przykład funkcjonalności, do której można zastosować PE: wgrywanie avatara. Podstawową funkcjonalnością, jaką należy dostarczyć użytkownikowi jest… możliwość wgrania avatara. Nie trzeba tu jakoś specjalnie dużo kombinować – to jest po prostu zwykły formularz w HTML, z polem input[type=file].

Tyle – zrobiliśmy wgrywanie avatara. Mając tę całkowicie podstawową czynność, można zająć się jej udoskonalaniem. Dodajemy zatem do naszego przycisku wysyłania fajny styl z zaokrąglonymi rogami i gradientem przy pomocy CSS.

A już szczytem spełnienia dla naszego formularza jest to super fajne wysyłanie całości przez Ajaksa.

Voilla! Prosty formularz wysyłki avatara, który rozbudowaliśmy na wszystkich warstwach. W taki sam sposób można z powodzeniem tworzyć każdy element strony. Podstawową funkcjonalność zapewniamy w HTML, do tego dodajemy ładny wygląd w CSS i wszystkie wodotryski w JS. Tym sposobem stare przeglądarki i mobilne sprzęty ze słabym netem dostaną zwykły formularz a wypasione Chrome na wypasionych Macach mega upload Ajaksem. Każdemu według potrzeb i możliwości!

I to tyle?!

Tak, to tyle. Założenia PE są proste i nietrudne do spełnienia a są w stanie znacząco przyspieszyć proces tworzenia aplikacji internetowej oraz ją samą. Jest to na tyle pewny sposób tworzenia stron, że działa równie dobrze w przypadku zaawansowanych aplikacji internetowych. GMaila da się obsługiwać bez JS, czego doskonale dowodzi istniejąca wersja bez JS (którą Google pokazało jak bardzo nie zna PE i jak bardzo lubi dokładać se roboty ;)). Bardzo mało jest przykładów aplikacji, które nie są w stanie nic zrobić bez JS (Photoshop online? Zaawansowane komunikatory?), więc PE po prostu się opłaca. Lepiej coś użytkownikowi pokazać niźli odesłać go z kwitkiem.

PE jest znane od bardzo dawna, niemniej wciąż się o nim zapomina. Przeszło porządną ewolucję, wykształciło lepsze narzędzia i wciąż stanowi podstawę tworzenia Sieci przyjaznej wszystkim.

Bądźmy dobrymi architektami – nie zapominajmy o fundamentach!


Tagi: