Od czasu osiągnięcia statusu rekomendacji przez HTML 5.0 minęły ponad dwa lata. Czy warto było czekać? Jakie nowinki nas spotykają (lub spotkają – o tym za chwilę) w zakresie standardu 5.1? Rekomendacja została upubliczniona 1 listopada 2016. Wezmę ją pod lupę w kontekście najistotniejszych rzeczy.

Słowem wstępu

O szczegółach standardu możecie przeczytać na stronie World Wide Web Consortium (W3C). Nie wszystkich jednak przekonuje „e-book” pisany surowym językiem. Te osoby zachęcam do kontynuowania lektury. Pod w/w linkiem znajdziecie oczywiście wszystko, ale tutaj skupię się na najważniejszych rzeczach. Dodatkowo okraszę je przykładami, pokuszę się o subiektywną ocenę, a także w miarę możliwości rozwieję wątpliwości dotyczące wsparcia przez przeglądarki. Czy Microsoft stanie na wysokości zadania?

Zmiany, zmiany

Ciężko zwięźle przedstawić cały standard, ale postaram się. Jeśli wyjdzie karkołomnie, wybaczcie. Za chwilę zatem wypunktuję to, co wprowadza W3C w nowej wersji. Następnie przejdę do omawiania kolejno elementów z listy.

  1. Nowości
    1. Elementy
      1. menu, menuitem, contextmenu
      2. details, summary
      3. dialog
      4. picture
    2. Atrybuty
      1. srcset
      2. sizes
      3. allowfullscreen
      4. autocomplete
      5. inputmode
      6. nonce
    3. Typy
      1. datetime
      2. datetime-local
      3. week
      4. month
    4. Pseudoklasy
      1. :dir()
    5. Metody
      1. forceSpellCheck
      2. reportValidity

 

Teraz ostrzegam, że będzie długo, jednak w zachęcam do dokładnej analizy treści, bowiem nawet dla mnie niektóre wnioski były naprawdę zdumiewające.

W tym wpisie przedstawię wytłuszczone powyżej punkty. Kolejna część będzie zawierała pozostałe elementy, a także zbiorcze podsumowanie.

Testy przeprowadzam na następujących wersjach przeglądarek:

  • Mozilla Firefox 42.0
  • Google Chrome 55.0
  • Opera 41.0

 

Menu, menuitem, contextmenu

Wsparcie 6,82% (wyłącznie częściowe):

  • FF 8+ (wyłącznie contextmenu)
  • Chrome 41+ (częściowe, domyślnie brak)
  • Opera 35+ (częściowe, domyślnie brak)
  • FF for Android 50+ (wyłącznie contextmenu, brak zagnieżdżania menu)

Tutaj szaleństwa w pozytywnym tego słowa znaczeniu nie ma. Widać, że rekomendacja ma posłużyć dopiero to domyślnego wsparcia w w/w przeglądarkach. Nie pytajcie mnie gdzie w tym wszystkim jest Microsoft, bo szkoda strzępić języka. Podobnie zresztą jest z pozostałymi dostawcami przeglądarek.

Elementy te można uznać za ciekawe w perspektywie przyszłości, jednak bazowanie wyłącznie na nich nie ma sensu. Widać to chociażby na wsparciu procentowym, które tylko dzięki FF można z przymrużeniem oka określić na poziomie ~6%. Oczywiście implementacja tych elementów, jako dodatkowych na tak zwaną przyszłości jest w porządku. Mamy rekomendację, więc z tego wywinąć twórcom przeglądarek się już nie da. Tylko pytanie ile będziemy czekać?!

Poniżej znajduje się przykład kodu, który wszem i wobec powinien działać, jednak po powyższej lekturze domyślacie się zapewne, że warto uruchomić go wyłącznie na Firefoxie.

Przykład (fiddle):

<form name="npc">
 <label>Character name: <input name=char type=text contextmenu=namemenu required></label>
 <menu type="context" id="namemenu">
 <menuitem label="Pick random name" onclick="document.forms.npc.elements.char.value = 'test'"></menuitem>
 <menuitem label="Get the value" onclick="window.alert(document.forms.npc.elements.char.value)"></menuitem>
 </menu>
</form>

 

Firefox – contextmenu

 

Zainteresowanych działaniem na Chrome zasmucę. Konieczne jest włączenie przeglądarki w trybie sparametryzowanym. Wystarczy odwiedzić katalog Google Chrome bardzo prawdopodobna ścieżka:

C:\Program Files (x86)\Google\Chrome\Application>

i uruchomić Chrome poleceniem:

chrome.exe --enable-blink-features=ContextMenu

 

Jednak wyżej zaprezentowany przykład nie zadziała. Przynajmniej menu kontekstowe nie pojawi się, gdyż jest przypisane do input:text. Strzelam, że wszystkie inputy będą powiązane z tą niedogodnością (przynajmniej na chwilę obecną), jednak do sprawdzenia tego zachęcam zainteresowanych tematem.

Zmodyfikowany przykład, posiadający przypisanie menu do węzła label jest tutaj (pamiętaj o parametryzacji Chrome!) i prezentuje się jak na załączonym obrazku:

Chrome – contextmenu

 

Uwaga! Mimo, iż dokumentacja stanowi, że węzeł menuitem jest węzłem samozamykającym na Firefoxie konieczne było jawne zamknięcie węzła, by przypadek testowy zadziałał.

Pozwoliłem sobie pominąć część dotyczącą menu typu toolbar, z uwagi na brak implementacji ze strony przeglądarek. To jest totalnie nieodkryty temat.

Podobnie rzecz ma się z buttonem typu menu, do którego rzecz jasna przez atrybut menu można przypisać konkretne menu. Na chwilę obecną zakładam, że to powstanie, gdyż jakkolwiek nie napisałbym kodu testowego ani na FF, ani na Chrome nie chciał zadziałać.

Inne przypadki testowe sprzed kilku miesięcy możecie znaleźć na tej stronie. Sporo się zmieniło od tego czasu, jednak artykuł może posłużyć frontendowcom za podkładkę do sprawdzenia możliwości przeglądarek.

Menuitem pozwala dodatkowo na ustawienie icon (blokowane w Chrome), atrybutu disabledatrybutu checked (dla type: radio lub checkbox), atrybutu radiogroup (dla type: radio), a także atrybutu default.

 

 

Details, summary

Wsparcie 84,87% (pełne):

  • FF 49+
  • Chrome 19+ (pełne 36+)
  • Safari 6+ (bez wsparcia toggle event)
  • Opera 15+ (częściowe, domyślnie brak)
  • iOS Safari 6.1+
  • Android Browser 4+
  • Blackberry Browser 10+
  • Opera Mobile 37+
  • Chrome for Android 54+
  • FF for Android 50+
  • UC Browser for Android 11+ (częściowo)
  • Samsung Internet 4+

Dla tych elementów zaskoczenie jest pozytywne. Jednak widzicie powtarzalne zjawisko, prawda? Ani IE Mobile, ani IE, ani Edge nie wspiera wskazanych elementów w ogóle. Na domiar złego przyszła wersja Edge (15) nie będzie ich wspierała. Chyba nie ma już nadziei 🙂

Wniosek, jaki mnie teraz naszedł – wysokie wsparcie związane jest z trywialnością wdrożenia obsługi elementu. Opisywane obecnie nie są zaawansowane mechanicznie, a po krótkich testach wydają się mieć potencjał – szkoda tylko, że kilka lat za późno. Semantycznych odpowiedników brakowało, więc przez ten czas tworzyło się lub wykorzystywało proste mechanizmy collapse panels. Ha, teraz mamy semantykę, ale czy możemy w pełni nią kontrolować? To dopiero zbadamy przy ewentualnych wdrożeniach. Dokładając do aplikacji bibliotekę shim/shiv zapewniamy kompletne wsparcie, więc do dzieła web deweloperzy.

Przykłady (fiddle1, fiddle2, fiddle3):

<section class="progress window">
 <h1>Copying "Really Achieving Your Childhood Dreams"</h1>
 <details>
 <summary>Copying... <progress max="375505392" value="97543282"></progress> 25%</summary>
 <dl>
 <dt>Transfer rate:</dt> <dd>452KB/s</dd>
 <dt>Local filename:</dt> <dd>/home/rpausch/raycd.m4v</dd>
 <dt>Remote filename:</dt> <dd>/var/www/lectures/raycd.m4v</dd>
 <dt>Duration:</dt> <dd>01:16:27</dd>
 <dt>Color profile:</dt> <dd>SD (6-1-6)</dd>
 <dt>Dimensions:</dt> <dd>320×240</dd>
 </dl>
 </details>
</section>
<details>
 <summary><label for=fn>Name &amp; Extension:</label></summary>
 <p><input type=text id=fn name=fn value="Pillar Magazine.pdf">
 <p><label><input type=checkbox name=ext checked> Hide extension</label>
</details>
<style>
details > summary { transition: color 1s; color: black; }
details[open] > summary { color: red; }
</style>

<details>
 <summary>Automated Status: Operational</summary>
 <p>Velocity: 12m/s</p>
 <p>Direction: North</p>
</details>

 

 

Uwaga! Dodanie wcześniej wspomniane biblioteki shim nie wprowadziło żadnych zmian na testowanym przykładzie w Edge. Należy więc zagłębić się w temat bibliotek tego typu.

 

Gwoli podsumowania. Warto pomyśleć o zastosowaniu elementów detailssummary. Niemal pełne wsparcie na chwilę obecną pozwala uniknąć większych problemów na etapie wdrażania i użytkowania aplikacji. Semantyka ma ogromne znaczenie, bowiem chociażby przeglądarki mobilne mają zaimplementowaną specjalną obsługę mechaniczną, jak i graficzną takich elementów.

 

Dialog

Wsparcie 56,1% (pełne):

  • Opera 24+
  • Chrome 37+
  • Android Browser 53+
  • Opera Mobile 37+
  • Chrome for Android 54+
  • Samsung Internet 4+

Mała sinusoida, bowiem ten element posiada wsparcie wyłącznie dla Chrome, Opera (webkit) oraz Samsung Internet Opera Mobile. Mało, malutko, ale sprawdźmy czy w ogóle warto się interesować elementem.

Uwaga! Z powodu bezowocnego poszukiwania informacji o elemencie dialog w rekomendacji HTML 5.1 wnioskuję, że tuż przed stworzeniem ostatecznej wersji element ten został wyłączony z dokumentu. Jednak pozwolę sobie go zbadać…

Przykład z jakiego skorzystamy zaczerpnąłem z dokumentacji Mozillifiddle.

Element pozwala na natywne uruchamianie okienek modalnych, co samo w sobie jest dobrą ideą. Dodatkowo fenomenalną sprawą jest połączenie obsługi formularza z kontenerem (dialogiem) go zawierającym poprzez atrybut method z wartością dialog węzła form. Ciekawa sprawa. Sprawdźmy zatem, które przeglądarki i jak ją obsługują.

 

Idea perspektywiczna, jednak bardzo niski poziom wsparcia i problemowa symulacja poprzez biblioteki polyfills na razie uniemożliwiają wdrażanie tego typu elementów w systemach multiprzeglądarkowych.

 

Picture

Wspaniała wiadomość dla tworzących strony RWD. Już nie będzie trzeba koniecznie umieszczać obrazka w tle, by móc przyzwoicie skalować go w CSS. Dodatkowo mobilne urządzenia nie będą musiały ściągać nierzadko bardzo ciężkich zdjęć przeznaczonych na ekrany wysokich rozdzielczości. Tak, odtąd mamy element picture.

Wsparcie 74,33% (pełne):

  • Opera 25+
  • Chrome 38+
  • Firefox 38+
  • Safari 9.1+
  • iOS Safari 9.3+
  • Android Browser 53+
  • Opera Mobile 37+
  • Chrome for Android 54+
  • Firefox for Android 50+
  • Samsung Internet 4+
  • Edge 13+

Musiałem wyróżnić Edge 🙂 „Widać postęp w działaniach Microsoftu„. Na IE nie mamy co liczyć podobnie jak na: Blackberry Browser i UC Browser for Android.

Tak naprawdę wydaje się, że możemy śmiało korzystać z tego elementu (o ile shim/polyfills obsłużą zadowalając działanie na IE).

Za podstawowy przykład wykorzystam tutaj znalezisko z sieci – link. Zachęcam do odwiedzenia i zmianę szerokości okna przeglądarki. Mamy teraz semantyczne wsparcie do manipulowania źródłami zasobów graficznych w zależności od rozmiaru ekranu. Na pewno się przyda.

<picture>
 <source media="(min-width: 650px)" srcset="images/kitten-large.png">
 <source media="(min-width: 465px)" srcset="images/kitten-medium.png">
 <!-- img tag for browsers that do not support picture element -->
 <img src="images/kitten-small.png" alt="a cute kitten">
</picture>

 

Zachowanie powyższego kodu w zależności o szerokości ekranu przedstawia poniższa galeria. Zrzuty ekranu zrobione na Operze.

 

Zauważyliście zapewne, że pojawił się atrybut srcset oraz media.

  • media – to nic innego jak określenie rozmiaru viewportu poprzez dobrze znane z CSS ograniczenia media queries
  • srcset – może być jak w powyższym przypadku prymitywną ścieżką do zasobu, ale może występować jako zbiory rozbudowane (temat ściśle połączony z atrybutami sizes oraz deskryptorami lub w – o tym za chwilę)

 

Zacznę tę sekcję może od srcset i tych niezbyt przyjaźnie brzmiących deskryptorów. Podstawowa definicja tego atrybutu to „atrybut obrazu pozwalający umieścić wiele alternatywnych źródeł obrazów różniących się gęstością pikseli – ang. pixel density„. To właśnie przez pixel density twórcy postanowili rozszerzyć zapis o deskryptory. Gęstość jest zależna od urządzenia, na którym uruchomiona jest przeglądarka (oraz zoomu!), więc aby umożliwić szybsze ładowanie zasobów na mniejszych (często wolniejszych urządzeniach) warto skorzystać z tej opcji.

  • deskryptor x – odnosi się bezpośrednio do device-pixel-ratio; urządzenia, które posiadają ratio wysokie, prezentują obraz lepszej jakości, dysponują lepszej rozdzielczości; ratio ulega również zmianie podczas powiększania – czy to w przeglądarce na komputerze stacjonarnym, czy urządzeniu mobilnym – rozmiar kontenera pozostaje taki sam, ale zwiększa się ratio by przybliżyć obraz, czyli pokazać więcej szczegółów; deskryptor ten ściśle wiąże się ze swoim kolegą – deskryptorem w;
  • deskryptor w – określa szerokość obrazu, do którego adresu jest dołączony; dla każdego konkretnego ekranu posiadają wartość deskryptora w możemy określić jego odpowiednik x;

Device-pixel-ratio = device pixels / CSS pixels

CSS pixels zawsze jest mniejsze i to do tej wartości odnoszą się nasze media queries z CSS.

Dla przykładu weźmy Samsung Galaxy S6:

  • rozdzielczość 2560×1440
  • ratio 4
  • rozdzielczość CSS 640×360

Rozmiary wielu urządzeń znajdziecie tutaj.

 

Myślę, że teraz przyda się przykład, który zobrazuje o czym ja tutaj piszę.

<picture>

<source media="(max-width: 20em)" srcset="images/small/needle.jpg 1x,
images/small/needle-2x.jpg 2x, images/small/needle-hd.jpg 3x">

<source media="(max-width: 40em)" srcset="images/medium/needle.jpg 1x,
images/medium/needle-2x.jpg 2x, images/medium/needle-hd.jpg 3x">

<img src="needle.jpg" alt="Space Needle">

</picture>

Dla viewportu <=20em zasoby są ładowane z katalogu small. Powyżej tej wartości do 40em włącznie z katalogu medium. Niedopasowanie media powoduje dołączenie zwykłego img, który to jest dołączany również w przypadku niewspierania elementu picture.

Zbiory źródeł zawierają deskryptory x, co spowoduje uzależnienie wyświetlanego zasobu od device-pixel-ratio.

Tutaj znajduje się fiddle lekko zmodyfikowany w stosunku do powyższego, ale pokazujący możliwości deskryptora x. Przykładu z deskryptorem w nie będę pokazywał, gdyż zabawa jest analogiczna. Pozostawiam ją zainteresowanym.

Uwaga! Operując zoomem na Operze 42 dostrzegłem iż obsługa deskryptorów (przynajmniej x) w ogóle nie istnieje. Może to wersja, może niedopatrzenie. W każdym razie na Firefox działanie wygląda tak jak powinno.

W przypadku Edge – działa 🙂 ale jeśli złapie obrazek dla wyższego ratio to przy powrocie z zoomem nie ładuje poprzedniego – zostaje z tym wyższej rozdzielczości. Uwaga warta odnotowania, gdyż niektórym może zależeć na powrocie obrazka dedykowanego do niższej rozdzielczości (tracimy szczegóły poprzez pozostawienie dużego obrazka – a czasami może nam na nich zależeć).

Wcześniej pisałem o konieczności dołączenie biblioteki polyfill dla picture, by z czystym sumieniem wdrażać element. Ba, nawet powątpiewałem w istnienie i działanie takowej. Jednak jest i działa. Na IE możecie sprawdzić ten fiddle.

Myślę, że temat deskryptorów wyczerpaliśmy. Ale nie nie, to nie jest jeszcze koniec. Pozostaje nam jeszcze atrybut sizes, który dedykowany jest do elementów img oraz source (w picture).

Sizes daje nam to czego jeszcze brakuje – mianowicie możliwość zmiany wymiarów obrazu na ekranie w ogóle, bądź w zależności od media queries.

Prosty przykład:

<img src="images/needle.jpg" sizes="75vw"
    srcset="images/needle.jpg 200w, images/needle-2x.jpg 400w, images/needle-hd.jpg 600w">

Obrazy zawsze będą zajmować 75% szerokości viewportu. Tutaj nie ma co tłumaczyć, a i taki styl można ustawić starym dobrym width w stylach.

Ciekawie zaczyna się robić w poniższym przykładzie. I on stanowi o sensie tego atrybutu.

<img src="images/needle.jpg" sizes="(max-width: 40em) 100vw, 50vw"
    srcset="images/needle.jpg 200w, images/needle-2x.jpg 400w, images/needle-hd.jpg 600w">

Krótko mówiąc – jeśli viewport ma maksimum 40em to obrazek zajmuje całą jego szerokość, w przeciwnym wypadku tylko pół. Reszta zadania przeglądarki polega na wyświetleniu odpowiedniego obrazka w zależności od deskryptora.

 

Jak już wcześniej pisałem, sizes dopełniają także element picture. Zasada działania jest analogiczna. Poniżej przykład:

<picture>
<source media="(max-width: 800px)" sizes="(max-width: 600px) 50vw, 20vw"
srcset="images/needle.png 130w, images/needle-hd-narrow.png 130w">

<source media="(max-width: 1600px)" sizes="(max-width: 1200px) 100vw, 50vw"
srcset="images/needle.png 410w, images/needle-hd.png 410w">

<img src="images/needle-basic.png" alt="Needle">
</picture>

Mamy 3 głównej przedziały media queries:

  • w <=800px
  • 800px < w <= 1600px
  • pozostałe

Pierwszy z nich ma rozgraniczenie dla rozmiaru: 50vw dla szerokości viewportu maksimum 600px oraz 20vw powyżej 600px ale oczywiście nie więcej niż próg główny – 800px.

Drugi rozgranicza rozmiar dla viewportu z przedziału (800px, 1200px] na całą jego szerokość oraz połowę szerokości dla przedziału (1200px, 1600px].

Przy braku dopasowania bazującego na atrybucie media, wyświetlony zostanie obrazek img.

Wszystko wygląda bardzo zachęcająco zwłaszcza w kontekście optymalizacji wagi ładowanych zasobów. W tym momencie nasuwa mi się tylko jedna niedogodność. Jak okiełznać preloader obrazków na stronie korzystającej z picture?!

 

Uff. Dziękuję za wytrwałość. W tej części to na tyle. W ciągu kilku dni pojawi się drugi artykuł wyczerpujący poruszony tutaj temat.

Pozdrawiam!