O nagłówkach słów kilka
Mam już dość powtarzania wciąż na nowo i nowo bzdur odnośnie wykorzystania nagłówków w HTML5, co wręcz prowadzi do “poprawiania” dobrych materiałów w Sieci. Dlatego dzisiaj słów kilka o nagłówkach.
Aktualizacja 2022-10-30: w końcu poprawiłem linki do specyfikacji HTML i dodałem informacje o hgroup
w sekcji o podtytułach.
Nagłówki – czyli co?
Na sam początek warto zastanowić się, czym są nagłówki. Jeśli ktoś o nich wspomina w kontekście SEO, to najlepiej go nie słuchać. Mit o tym, że mają większe znaczenie dla Google od “normalnych” tagów, wziął się z prawdziwej roli nagłówków.
Treść na stronie internetowej powinna być podzielona na sensowne części. Na najbardziej podstawowym poziomie będą to oczywiście akapity, niemniej taki podział jest najczęściej niewystarczający. Dlatego też poszczególne akapity grupuje się w sekcje. Wyznacznikiem sekcji jest właśnie nagłówek.
W jaki sposób poznać, czy strona jest poprawnie podzielona na sekcje, a tym samym – czy nagłówki są wykorzystane poprawnie? To proste: nagłówki powinny stworzyć hierarchię treści (ang. outline), czyli, mówiąc kolokwialnie, spis treści. Przykład takiego spisu treści można zobaczyć w moim tutorialu o semantycznym HTML-u. Co ciekawe, jest on faktycznie generowany z nagłówków.
Znaczenie nagłówków
Jeśli już wiemy, do czego nagłówki są wykorzystywane, zastanówmy się, jakie mają znaczenie w procesie tworzenia stron WWW. Jak już było to wspomniane, przedstawiają całą strukturę treści na stronie, a zatem: relacje i zależności pomiędzy poszczególnymi sekcjami na stronie. Tutaj na scenę wkracza tzw. poziom nagłówka, a zatem cyferka znajdująca się obok literki “h” w nazwie poszczególnych tagów.
Poziom nagłówka nie oznacza żadnej mocy ani innego dziwnego voodoo, o którym powtarza się w kontekście SEO. Poziom nagłówka oznacza tylko i wyłącznie jego relację w stosunku do innych elementów na stronie. Spójrzmy na przykład:
<h1>Gatunki kotów</h1>
<h2>Gatunki europejskie</h2>
<h3>Dachowiec angielski</h3>
<h3>Kanałowiec polski</h3>
<h2>Gatunki azjatyckie</h2>
<h3>Smok</h3>
Z tego przykładu wiemy, że cała strona dotyczy gatunków kotów. Tak bowiem mówi nagłówek najwyższego poziomu (tag h1
). Powinien on być tylko jeden na stronie i określać jej tematykę. Następnie dostrzegamy, że strona podzielona jest na 2 duże sekcje: gatunków europejskich i azjatyckich (tagi h2
). Te sekcje zawierają podsekcje (tagi h3
) poświęcone poszczególnym gatunkom kota. Oczywiście te podsekcje mogą mieć swoje podsekcje (tagi h4
), które dalej dzieliłyby na części opisy poszczególnych gatunków (np. “Występowanie”, “Sposób pielęgnacji” itd.).
Nagłówki a dostępność
Jak widać, taka struktura jest niezwykle przejrzysta i logiczna. I to już samo w sobie powinno stanowić odpowiedź na pytanie, czemu należy wykorzystywać poszczególne poziomy nagłówków zgodnie z przeznaczeniem. Niemniej jest ważniejszy powód: dostępność.
Niemal wszystkie czytniki ekranowe traktują nagłówki jako punkty nawigacyjne, pomiędzy którymi można przeskakiwać, wykorzystując odpowiedni skrót klawiszowy. To sprawia, że poprawne wykorzystanie nagłówków staje się jeszcze istotniejsze. Wprowadzenie więcej niż jednego nagłówka najwyższego poziomu może wprowadzić niepotrzebne zamieszanie u użytkownika (przypadek podobny do wielokrotnego main
). Tak samo takie zamieszanie może wprowadzić używanie niepoprawnych poziomów nagłówków czy pomijanie poziomów. Tylko prosta, czysta i sensowna struktura nagłówków na stronie ma jakikolwiek sens z pragmatycznego punktu widzenia.
I tutaj ważna uwaga: jak już wspominałem w artykule o tworzeniu czytnika ekranowego, technologia asystująca wie tyle, ile powie jej przeglądarka. Jak poszczególne nagłówki są oznajmiane technologii asystującej, można zobaczyć np. w narzędziach programistycznych przeglądarki Chrome w zakładce “Accessibility”:
Jak widać, nagłówek h2
jest przedstawiany jako element o roli heading
(nagłówek) i poziomie 2 – zatem wszystko się zgadza.
Nagłówki a HTML5
HTML5 wprowadził nowe znaczniki dzielące stronę na sekcje (tzw. znaczniki sekcjonujące), m.in. section
czy article
. W specyfikacji HTML5 pojawił się także zarys nowego algorytmu definiującego hierarchię treści. W skrócie: nieważny był poziom nagłówka, a jedynie poziom jego “zagłębienia”, czyli body > h2
będzie wyżej niż body > section > h1
.
Tak brzmiała teoria. Rzeczywistość okazała się brutalna, bo żadna przeglądarka nie dodała wsparcia dla tego algorytmu. Algorytm stał się niebezpieczną fikcją, która powodowała problemy z dostępnością. Okazało się bowiem, że body > h2
było nagłówkiem niższego rzędu niż body > section > h1
. A z racji tego, że technologia asystująca nie wie o stronie nic ponad to, co dostarczy jej przeglądarka, nie powinno się korzystać z nowego sposobu definiowania nagłówków
Łatwo to sprawdzić empirycznie. Gdyby nowy algorytm działał, h1
w poniższym kodzie powinien być przedstawiony czytnikowi ekranowemu jako nagłówek drugiego poziomu:
<body>
<section>
<h1>Test</h1>
</section>
</body>
Zobaczmy zatem, czy Chrome faktycznie tak przedstawia ten nagłówek technologii asystującej:
Jak widać, nagłówek wewnątrz sekcji wciąż jest przedstawiany jako nagłówek pierwszego stopnia. To oznacza, że wykorzystanie kilku nagłówków h1
na stronie (mimo stosowania równolegle tagów sekcjonujących) tworzy płaską hierarchię treści. Tego typu hierarchia jest całkowicie nieprzydatna z punktu widzenia użytkownika – zwłaszcza takiego, który posługuje się dodatkowo technologią asystującą.
Prawda ta jest znana od zawsze i w końcu ma odzwierciedlenie w specyfikacji HTML – algorytm outline’u został usunięty i już oficjalnie jedynym poprawnym sposobem na tworzenie hierarchii treści jest wykorzystywanie wszystkich poziomów nagłówków.
W kontekście HTML5 powstaje zatem zasadne pytanie: czy jest sens stosować znaczniki sekcjonujące skoro i tak wypada stosować nagłówki po staremu? Uważam, że tak, bo tagi te sprawiają, że kod staje się przejrzystszy. Sekcje są oznaczone już nie tylko przez sam nagłówek, ale przez wyraźny tag section
bądź article
. Tym sposobem kod jest bardziej semantyczny.
Główny nagłówek
Warto też przez chwilę zastanowić się nad określaniem głównego nagłówka strony. Jak już wiemy, powinno to być h1
. Niemniej pytanie brzmi, co w tym h1
powinno się zawierać?
#1 – nagłówek opisujący podstronę
Przez lata powtarzałem, że w przypadku większości stron głównym nagłówkiem strony powinno być logo. Niestety, podgląd ten nie jest mocno popularny wśród użytkowników czytników ekranowych. Większość z nich (ponad 50%) twierdzi, że h1
powinno być tytułem danej podstrony. 30% użytkowników dopuszcza za to istnienie dwóch h1
: dla tytułu całej witryny oraz dla tytułu danej podstrony. Jedynie około 12% uważa, że h1
powinno oznaczać tytuł całej witryny.
Tego typu wyniki doprowadziły do stworzenia techniki, w której logo/nazwa witryny jest nagłówkiem h1
wyłącznie na stronie głównej. Na poszczególnych podstronach logo stanowi już tylko link, natomiast w znaczniku h1
znajduje się tytuł podstrony. Ta technika jest była wykorzystywana m.in. na stronie Internet Bez Barier. Warto porównać kod strony głównej z kodem dowolnej podstrony:
<!-- strona główna nagłówek -->
<div class="heading clearfix">
<img src="http://internet-bez-barier.com/wp-content/themes/internet-bez-barier/images/globe3.png" alt="" />
<div class="heading-inner">
<h1 class="site-title">Internet bez barier</h1>
<p class="site-description">blog na temat dostępności stron internetowych</p>
<a class="skip" href="#main">Przejdź do głównej treści</a>
</div>
</div>
<!-- podstrona nagłówek -->
<div class="heading clearfix">
<img src="http://internet-bez-barier.com/wp-content/themes/internet-bez-barier/images/globe3.png" alt="" />
<div class="heading-inner">
<a class="home-link" href="http://internet-bez-barier.com/" title="strona główna" rel="home">
<span class="site-title">Internet bez barier</span>
</a>
<p class="site-description">blog na temat dostępności stron internetowych</p>
<a class="skip" href="#main">Przejdź do głównej treści</a>
</div>
</div>
[…]
<h1 class="entry-title">Tabele HTML</h1>
Jak widać, na stronie głównej nazwa witryny jest wewnątrz tagu h1
i nie jest linkiem (bo znajdujemy się na stronie głównej). Na podstronie z kolei h1
w nazwie witryny jest zastąpione przez link powrotny do strony głównej, a w h1
umieszczono tytuł wpisu. Wydaje mi się, że tego typu podejście jest na chwile obecną najlepsze, niemniej brakuje jakichś większych badań na temat nawigowania przy pomocy nagłówków.
W przypadku stron typu one-page problemu nie ma. Tutaj w sumie jedynym sensownym wzorcem (moim zdaniem rzecz jasna) jest ten z logo/nazwą witryny w h1
.
#2 – nagłówek poza nawigacją
Istnieje jeszcze jeden wzorzec, o którym warto wspomnieć, a który proponuje np. Heydon Pickering: logo strony jest pierwszą pozycją menu nawigacyjnego strony:
<nav role="navigation" aria-label="site links">
<div class="menu-menu-1-container">
<ul id="menu-menu-1" class="menu">
<li id="menu-item-4" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-4">
<a title="HeydonWorks latest blog articles" href="http://www.heydonworks.com">HeydonWorks</a>
</li>
[…]
</ul>
</div>
</nav>
W tym modelu nawigacja i nagłówek strony są osobnymi bytami. Trzeba przyznać, że jest to dość sensowne rozwiązanie i stosuje je m.in. Smashing Magazine. Wydaje mi się, że ten wzorzec najbardziej sprawdziłby się w przypadku aplikacji, w której nagłówki określałyby po prostu kolejne widgety/komponenty, lub na stronach reklamowych, gdzie występuje tzw. hero section.
#3 – nagłówek witryny
No i nie można zapomnieć o najstarszej technice, czyli h1
jako tytule witryny. Choć nie jest to kardynalny błąd, może wprowadzać pewne zamieszanie dla użytkownika czytnika ekranowego. Istnieje wówczas rozbieżność pomiędzy nawigacją przy pomocy tzw. landmarków (main, nav, article
) a nawigacją nagłówkami. Teoretycznie nawigowanie do main
powinno dać ten sam rezultat, co nawigowanie do h1
.
Nagłówki kontekstualne?
Nowy algorytm nagłówków w HTML5 miał rozwiązać problem, który od dawna martwi osoby tworzące bardziej skomplikowane aplikacje internetowe: nie zawsze wiadomo, gdzie nasz komponent wyląduje. Wyobraźmy sobie, że robimy sobie w Reactcie komponent “Pogoda” (Weather
), który ma taki kod HTML:
<section>
<h2>Pogoda</h2>
<!-- Tu pogoda wczytana skądś tam -->
</section>
Ten komponent następnie ma trafić jako podsekcja sekcji “Inne wiadomości”:
<section>
<h2>Inne wiadomości</h2>
<Weather />
</section>
I tu pojawia się problem: hierarchia treści pokaże komponent “Pogoda” jako osobną sekcję, sąsiadującą z sekcją “Inne wiadomości” (bo i tu, i tu mamy nagłówek drugiego stopnia). Gdyby algorytm hierarchii treści z HTML5 działał, wówczas nagłówek w “Pogodzie” byłby przedstawiany technologii asystującej jako nagłówek trzeciego poziomu lub niższego. Niemniej algorytm nie działa i jest problem…
Poziomy nagłówków w HTML-u są bowiem globalne. Nie zależą w żaden sposób od miejsca występowania tagu. h2
zawsze będzie nagłówkiem drugiego poziomu, a h6
– szóstego. W czasach, gdy HTML był językiem tworzenia dokumentów hipertekstowych, nie sprawiało to praktycznie żadnego problemu. W chwili, gdy HTML stał się językiem do tworzenia aplikacji internetowych, brak nagłówków kontekstualnych (zależnych od swojego miejsca występowania) staje się problemem. Zwłaszcza, gdy myślimy o całości aplikacji jako o zbiorze niezależnych komponentów. Wówczas często nie wiemy, gdzie dana rzecz ostatecznie się znajdzie, a co za tym idzie – nie jesteśmy w stanie dobrać sensownie poziomu nagłówka.
Na chwilę obecną problem ten najlepiej rozwiązać tworząc… komponent nagłówka, który za pomocą magii ARIA ([aria-level]
czy [role=heading]
) ustali swój faktyczny poziom. A w przyszłości być może doczekamy się tego w HTML-u, dzięki elementowi h
.
Podtytuły
Została ostatnia kwesia. Podtytytułów nie robi się na nagłówkach. Jest to bowiem dodatkowa informacja do już wstawionego nagłówka. Umieszczanie tego w nagłówku niepotrzebnie komplikowałoby hierarchię treści. Dodatkowo byłoby to utrudnieniem dla użytkowników czytników ekranowych, umieszczając dwa punkty nawigacyjne praktycznie w tym samym miejscu.
Na szczęście standard HTML dochrapał się ostatnio oficjalnego sposobu oznaczania nagłówków. Po usunięciu algorytmu outline’u trzeba było zrobić coś z elementem hgroup
, który nie miał już dłużej sensu. No więc zmieniono jego znaczenie i teraz służy właśnie do grupowania nagłówka wraz z jego podtytułem:
<hgroup>
<h1>Pan Tadeusz</h1>
<p>czyli ostatni zajazd na Litwie</p>
</hgroup>
Komentarze
Przejdź do komentarzy bezpośrednio na Githubie.
Dawne komentarze
Ten blog wcześniej korzystał z systemu komentarzy Disqus. Jednakże pożegnaliśmy się i postanowiłem, że zaimportuję do nowej wersji stare komentarze z niego. Cóż, jego system eksportu na wiele nie pozwala…
Bardzo ciekawy wpis, dzięki!
dobrze wyjaśnione!
Bardzo fajnie, że poruszyłeś ten temat. Sam kiedyś byłem zwolennikiem wielu H1 na stronie w zależności od kontekstu, czyli sekcji czy artykułu. Niestety, twórcy przeglądarek uznali ten pomysł za niedopracowany, więc musiałem zmienić swoje podejście i stosuję już h1 i h2 jako tytuł strony/tytuł tekstu zamiennie.
Świetny wpis !
Świetny art! Nareszcie ktoś oficjalnie rozprawił się z algorytmem outline na polskiej scenie.
Autor nie ma za grosz pojęcia o optymalizacji pod kątem SEO... algorytmy w znaczący sposób analizują nagłówki Hx ponieważ to właśnie one w dużej części określają sens strony.
Polecam zainteresować się tematem zamiast wciskać kit.
A ja polecam czytać ze zrozumieniem. Fakt, że nagłówki w jakikolwiek sposób wpływają na SEO jest skutkiem ubocznym ich roli. Tylko tyle i aż tyle. Optymalizowanie nagłówków pod wyszukiwarkę jest głupotą.
Hej Comandeer. Tworzę swoje pierwsze portfolio. Uczę się html5 z dokumentacji oraz z Twoich stron, artykułów jak ten wyżej i Twoich postów na facebooku. Napotkałem na jeden problem i chciałbym się Ciebie zapytać o Twoją opinię. Nie jestem w stanie podać linku do kodu, ale jest to Twój kod z codepena, na facebooku kiedyś go komuś wysłałeś by pokazać jak powinno wyglądać dostępne menu i przycisk, wyglądało to tak: jsfiddle To jest tylko html, był do tego jeszcze css i js. Ja stworzyłem takie menu według Twojego kodu i mam problem z hierarchią nagłówków i dostępnością. Na stronie główniej nie mam tego problemu bo nagłówek h1 jest na samej górze, ale np. na innej stronie w moim przypadku jest to strona 404, dokładnie tutaj moja strona 404.html gdzie nagłówek h1 jest poniżej nagłówka h2 menu i jak sprawdzam outline tej strony tutaj validator.w3.org to pokazuje, że nagłówek h1 is missing, ale on tam jest tylko niżej. Szukałem na innych stronach by sprawdzić jak to robią inni i na Twoich stronach, nie masz w żadnym menu nagłówka h2 Menu dlatego outline jest w porządku. Sprawdzałem strony, które uważają się za "dostępne" i np. tacy widzialni.org na głównej stronie outline jest w porządku, ale jeśli wczytamy jakiś artykuł to by obejść ten problem o którym wspomniałem wyżej, stosują na samej górze nagłówek h1, który jest praktycznie taki sam jak tytuł artykułu, który znajduje się w nagłówku h2 i wygląda to mniej więcej tak:
h1 Ministerstwo Cyfryzacji opublikowało wzór deklaracji dostępności - Fundacja Widzialni
....
...
h2 Ministerstwo Cyfryzacji opublikowało wzór deklaracji dostępności
Uważam, że jest to średnie rozwiązanie. Kolejna strona na którą patrzyłem to webaim.org i u nich czy strona główna czy artykuł to jest tak samo jak u mnie na stronie 404.html, czyli pierwsze jest ten brakujący nagłówek, czyli h1 is missing, potem h2 Menu i dopiero później jest nagłówek h1. Chciałem się Ciebie zapytać, które rozwiązanie jest według Ciebie lepsze? Może od momentu kiedy napisałeś ten kod, zmieniły się już wytyczne co do nagłówka h2 w menu i umieszczanie go nie jest już dobrym rozwiązaniem. Mam też Twój kod, który zamieściłeś w komentarzu pod filmem Jak stworzyć hamburger menu i sidebar od Hello Roman tutaj i tam nie zamieściłeś już nagłówka h2.
Prawdę mówiąc nie widzę większego problemu z tym, że nagłówek w menu jest wyżej od głównego nagłówka strony. Stanowi on przede wszystkim dodatkowy sposób na nawigację do menu (nawigacja do nav, nawigacja po nagłówkach, czasami też nawigacja przez skip linki itd.) oraz identyfikuje, z jakim dokładnie elementem nawigacyjnym mamy do czynienia.
Niemniej można się zastanawiać właśnie nad tym, czy taki nagłówek nie jest nadmiarowy i nie da się go zastąpić właśnie przez samo nav i skip linki. Zwłaszcza, że nazwę dla menu można dodać przy pomocy np. [aria-label], a i przydaje się głównie wtedy, gdy na stronie mamy kilka elementów nav i trzeba je jakoś odróżniać. Stąd w nowszych materiałach nie umieszczałem nagłówka w menu. Wstawienie tam nagłówka nie jest jednak błędem i być może wkrótce zmieni się specyfikacja HTML, usuwając wymóg umieszczania h1 na samej górze i zamieniając go na wymóg po prostu posiadania h1.
Co do rozwiązania z dodawaniem dodatkowego h1: jak dla mnie to zły pomysł. Zwłaszcza, że psuje to nawigację przy pomocy nagłówków. Przeskakując do h1, przeskoczymy tak naprawdę na sam początek strony.
Dzięki :)
Comandeer widzisz mój komentarz jaki tutaj dodałem? Nie ten tylko jeszcze inny. Dasz radę go tutaj przywrócić, bo dwa razy został oznaczony jako spam przez Disqus
Przywrócone.