Rozbalovací navigační menu - Jak na přístupnost

Popis vzoru

Rozbalovací navigační menu je prvek nejčastěji umístěný v záhlaví nebo na boku webové stránky, Který sestává z několika hierarchicky uspořádaných skupin tlačítek nebo odkazů. Odkazy v tomto menu slouží zpravidla jako rozcestník pro navigaci na jiné webové stránky, přičemž ve výchozím stavu se zobrazují jen rozbalovací tlačítka na nejvyšší úrovni, které až po aktivaci odkryjí příslušné odkazy úrovně nižší. Na webu se setkáváme nejčastěji s následujícími dvěma přístupnými variantami rozbalovacích navigačních menu:

  • Varianta A: Na nejvyšší úrovni menu se vyskytují pouze rozbalovací tlačítka, přičemž odkazy na stránky této nejvyšší úrovně jsou dostupné jako první podpoložka až po rozbalení příslušného tlačítka.

  • Varianta B: Na nejvyšší úrovni menu se kromě zmíněných rozbalovacích tlačítek zobrazují rovnou i příslušné odkazy na stránky nejvyšší úrovně.

Ovládání pomocí klávesnice

  • Pro umožnění ovládání navigačního menu pomocí klávesnice je důležité, aby jak rozbalovací tlačítka, tak všechny odkazy menu byly zaměřitelné prostřednictvím tabulátoru. V praxi to znamená, že tlačítka by měla být realizována pomocí elementu <button type=“button“> a odkazy pomocí elementu <a>, přičemž na těchto elementech nesmí být nastaven atribut tabindex se zápornou hodnotou. Pro položky menu je možné použít i jiný element, např. <div> nebo <span>, avšak v takových případech je nutné na nich nastavit atribut tabindex=“0“, čímž jejich zaměřitelnost tabulátorem zajistíte.

  • V momentě, kdy je fokusem zaměřeno rozbalovací tlačítko, by mělo být možné odkrýt nebo skrýt jemu náležící Podpoložky stisknutím mezerníku nebo Enteru.

Požadavky na přístupnost

  • Tlačítka rozbalující podpoložky menu by měla být realizována následovně:

    • Jestliže rozbalovací tlačítko není pojmenováno jako příkaz, např. „Naše služby“ nebo „O nás“, tak by toto tlačítko mělo dynamicky nastavovat atribut aria-expanded na hodnotu „true“ nebo „false“ podle toho, jestli je právě rozbaleno nebo ne. Tento atribut zajistí, že odečítač ohlásí příslušný stav rozbalení sám, není tedy nutné jako součást pojmenování tlačítka uvádět i jeho stav.

    • Jestliže rozbalovací tlačítko jako příkaz pojmenováno je, např. „Rozbalit Naše služby“ nebo „Sbalit Naše služby“ (dle stavu rozbalení), tak by na něm atribut „aria-expanded“ nastaven být neměl.

    • Jestliže je pro rozbalovací tlačítko použita pouze ikona nebo obrázek v podobě elementu <img>, tak by tento element měl být správně pojmenován pomocí atributu alt.

    • Jestliže je pro rozbalovací tlačítko použita pouze ikona nebo obrázek v podobě elementu <svg>, tak by tento element měl být správně pojmenován pomocí atributu aria-label nebo aria-labelledby a dále také pomocí SVG elementu <title> tak, jak je ukázáno níže v sekci „Zdrojový kód“ pro variantu B.

    • Rozbalovací tlačítko by mělo mít nastaveno atribut aria-controls odkazující na element se seznamem odkazů, které toto tlačítko odkrývá.

  • Odkaz v menu, který odpovídá stránce, na níž se uživatel zrovna nachází, by měl mít nastaven atribut aria-current=“true“.

  • Tlačítko nebo odkaz v menu, na kterých je zrovna fokus klávesnice, by prostřednictvím CSS pseudotřídy :focus měly být správně zvýrazněny s ohledem na uživatele, jež pro ovládání nepoužívají myš či jiné polohovací zařízení.

  • Rozbalované seznamy odkazů by měly být implementovány pomocí elementu pro nečíslovaný seznam <ul> s položkami <li> a měly by se v HTML kódu nacházet ihned za tlačítkem, které příslušný seznam odkrývá, tak, aby uživatel při sekvenčním procházení stránky pomocí kurzoru odečítače mohl na daný seznam odkazů snadno přejít.

  • Pokud je v kódu více než jedna navigační oblast, tak by element <nav> měl být pojmenován pomocí atributu „aria-label“ nebo „aria-labelledby“.

Časté chyby

  • Podmenu by se nemělo samovolně rozbalovat při fokusu rozbalovacího tlačítka pomocí klávesnice (tj. při události „onFocus“ na rozbalovacím tlačítku). Takové chování totiž způsobuje, že uživatel klávesnice musí projít všechny rozbalené položky druhé nebo vyšší úrovně, aby se dostal k další položce na úrovni první. Rozbalování podpoložek by se mělo dít výlučně pomocí mezerníku a Enteru.

  • Rozbalovací navigační menu by nemělo mít nastaveno atribut role=“menu“ ani role=“menubar“. Položky menu by dále neměly mít atribut role=“menuitem“. Tyto role se totiž standardně nepoužívají pro navigační menu na webových stránkách, nýbrž pro webové aplikace, kde se často jedná o menu s příkazy nebo funkcemi dané aplikace. Navíc v případě použití těchto rolí je nutné, aby programátor ručně zajistil vlastní ovládání menu pomocí klávesnice s využitím JavaScriptu. Samotná přítomnost těchto rolí totiž ovládání menu nezajišťuje. Jestliže ovládání menu programátor neimplementuje a pouze použije zmíněné role, tak může být navigace na webu pro uživatele klávesnice znemožněna.,

  • Jestliže na rozbalovacích tlačítkách používáte atribut „aria-expanded“, tak dejte pozor na to, aby byl tento atribut na příslušných tlačítkách nastaven na správnou hodnotu už ve výchozím stavu po načtení stránky. Častou chybou totiž je, že atribut „aria-expanded“ je nastavován pomocí JavaScriptu až při interakci s rozbalovacím tlačítkem.

  • Rozbalovací tlačítka by neměla mít nastavený atribut aria-haspopup. Ten se v navigačních menu nepoužívá a je využíván spíše ve webových aplikacích.

Funkční ukázka

Zdrojový kód

HTML

Varianta A

<nav role="navigation">
    <ul class="disclosure-nav">
      <li>
        <button type="button" aria-expanded="true" aria-controls="about-menu">
          O univerzitě
        </button>
        <ul id="about-menu">
          <li>
            <a href="#mythical-page-content">
              Přehled
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Vedení
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Fakta
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Prohlídky kampusu
            </a>
          </li>
        </ul>
      </li>
      <li>
        <button type="button" aria-expanded="true" aria-controls="admissions-menu">
          Přijímací řízení
        </button>
        <ul id="admissions-menu">
          <li>
            <a href="#mythical-page-content">
              Žádost
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Školné
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Návštěva
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Prohlídka fotografií
            </a>
          </li>
        </ul>
      </li>
      <li>
        <button type="button" aria-expanded="true" aria-controls="academics-menu">
          Studium
        </button>
        <ul id="academics-menu">
          <li>
            <a href="#mythical-page-content">
              Školy a fakulty
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Studijní programy
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Online kurzy
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Přehled kurzů
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Harmonogram akademického roku
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Transkripty
            </a>
          </li>
        </ul>
      </li>
    </ul>
  </nav>

Varianta B

<nav role="navigation">
    <ul class="disclosure-nav">
      <li>
        <a href="#mythical-page-content" class="main-link">
          O univerzitě
        </a>
        <button type="button" aria-controls="about-menu" data-expanded="false">
          <svg role="img" width="18" height="16" aria-labelledby="about-button-title" style="forced-color-adjust: auto">
            <title id="about-button-title" data-expanded-label="Sbalit O univerzitě">
              Rozbalit O univerzitě
            </title>
            <polygon stroke-width="0" fill-opacity="0.75" fill="currentcolor" points="3,6 15,6 9,14">
            </polygon>
          </svg>
        </button>
        <ul id="about-menu">
          <li>
            <a href="#mythical-page-content">
              Přehled
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Vedení
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Fakta
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Prohlídky kampusu
            </a>
          </li>
        </ul>
      </li>
      <li>
        <a href="#mythical-page-content" class="main-link">
          Přijímací řízení
        </a>
        <button type="button" aria-controls="admissions-menu" data-expanded="false">
          <svg role="img" width="18" height="16" aria-labelledby="admissions-button-title"
            style="forced-color-adjust: auto">
            <title id="admissions-button-title" data-expanded-label="Sbalit Přijímací řízení">
              Rozbalit Přijímací řízení
            </title>
            <polygon stroke-width="0" fill-opacity="0.75" fill="currentcolor" points="3,6 15,6 9,14">
            </polygon>
          </svg>
        </button>
        <ul id="admissions-menu">
          <li>
            <a href="#mythical-page-content">
              Žádost
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Školné
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Návštěva
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Prohlídka fotografií
            </a>
          </li>
        </ul>
      </li>
      <li>
        <a href="#mythical-page-content" class="main-link">
          Studium
        </a>
        <button type="button" aria-controls="academics-menu" data-expanded="false">
          <svg role="img" width="18" height="16" aria-labelledby="academics-button-title"
            style="forced-color-adjust: auto">
            <title id="academics-button-title" data-expanded-label="Sbalit Studium">
              Rozbalit Studium
            </title>
            <polygon stroke-width="0" fill-opacity="0.75" fill="currentcolor" points="3,6 15,6 9,14">
            </polygon>
          </svg>
        </button>
        <ul id="academics-menu">
          <li>
            <a href="#mythical-page-content">
              Školy a fakulty
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Studijní programy
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Online kurzy
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Přehled kurzů
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Harmonogram akademického roku
            </a>
          </li>
          <li>
            <a href="#mythical-page-content">
              Transkripty
            </a>
          </li>
        </ul>
      </li>
    </ul>
  </nav>

Zdrojový kód ke stažení

Související kritéria úspěšnosti WCAG

Výše popsané implementace rozbalovacích navigačních menu splňují především následující kritéria úspěšnosti Pokynů pro zpřístupnění webového obsahu WCAG (Web Content Accessibility Guidelines):

Použité zdroje informací

Autor: Adam Samec