Responzivní, čistě CSS off-canvas hamburger menu

, Author

Posledně aktualizováno 21. ledna 2019.

Čistě CSS off-canvas hamburger menu není nedávným objevem. Vždyť Chris Coyier o této technice psal už v listopadu 2012.

  • Pokud je to pro vás starý trik, tak se mnou chvíli vydržte. Chrisův příklad jsem vylepšil a budu rád za vaši zpětnou vazbu.
  • Pokud je to pro vás novinka, nebojte se. Máte spoustu společnosti, protože to vypadá, že velká část webu se toho vlastně ještě nechytla.

S tím vytvoříme jednoduché, responzivní off-canvas hamburger menu pouze pomocí CSS, které bude snadné začlenit do vašeho vlastního projektu. Ale nejprve…

Co je špatného na JavaScriptu?“

Nic.

Aaron Gustafson vysvětluje význam progresivních vylepšení a roli JavaScriptu ve vývoji webových stránek lépe, než bych to kdy dokázal já. Měli byste si přečíst jeho příspěvek. Ale pro stručnost se to pokusím shrnout:

  • „Základní úkoly lze vždy řešit bez JavaScriptu.“
  • Základní úkoly by se měly řešit na nejstabilnější vrstvě (tj. ne v JavaScriptu).
  • Progresivní vylepšení není proti JavaScriptu. Jde jen o to přijmout správné technologie na správné vrstvě.
  • „Protože existuje určitá šance, že JavaScript nepoběží, musíme s touto šancí vždy počítat.“
  • Nikdy není dobré ignorovat potenciální uživatele.
  • Progresivní vylepšení je prostě dobré inženýrství.

Takže budeme dělat co nejvíc s HTML a CSS. Pak necháme JavaScript kouzlit na vhodnější vrstvě – vylepšovat již existující uživatelské rozhraní.

Krok 1: HTML

Jak možná víte, prvním krokem je vždy napsání solidní, promyšlené základní vrstvy HTML.

Poznámka: Pro ikony v mém příkladu používám Font Awesome.

Krok 1: Úvodní HTML pro čistě responzivní hamburgerovou nabídku CSS

Vypadá to poměrně standardně, že? Máme:

  • Náš nadřazený prvek <header>
  • Ikona hamburgeru („fa-bars“)
  • Hlavní nadpis (nebo případně logo)
  • Navigace v prvku <nav>
  • Ikona zavření („fa-close“) uvnitř navigace (více o tom později)
  • „Pozadí“ za navigací. Proč se jedná o značku kotvy? Vysvětlím později.

Krok 2: Udělejme ji přístupnější

Přístupnost by nikdy neměla být dodatečnou myšlenkou – jako po napsání aplikace. Měla by být plánována od začátku. Přidání několika základních aspektů nyní nejen zlepší celkovou přístupnost vašeho webu, ale poskytne vám (vývojáři) lepší značení, které můžete využít ve svém JavaScriptu!

S tím přidáme několik dalších atributů a několik textů určených pouze pro čtečky obrazovky:

Krok 2: Vylepšení jazyka HTML, aby byl přístupnější.

Tady je rychlý rozpis všech těchto atributů a jejich funkce:

  • Přidali jsme jedinečné ID pro zaměření našich HREFů (více o tom, jak to funguje, později).
  • Zajistili jsme informativní popisek tlačítek pro čtečky obrazovky pomocí .
  • Skryli jsme ikony před čtečkami obrazovky pomocí , protože jsou vizuální reprezentací, a přidali jsme text pouze pro čtečky obrazovky pomocí prvků <span class=“sr-only“>.
  • Odstranili jsme „pozadí“ z indexu tabelátoru pomocí . Je čistě vizuální povahy a nechceme mást naše zrakově postižené uživatele a uživatele, kteří používají pouze klávesnici.
  • Přidali jsme atribut amazing pro nastavení počátečního (a sémantického) stavu „pozadí“. Už žádné smetí – jak vzrušující!“

Tady je zatím výsledek:

Obrázek 1: Výsledné zobrazení HTML po krocích 1 a 2.

Krok 3: Nastylujeme!

Přistoupíme k tomu z hlediska mobilních zařízení, takže vyřadíme mobilní, „hamburgerové“ zobrazení (tu zajímavou část).

Nejprve jen správně rozvrhneme záhlaví (bez interaktivity):

Krok 3: Přidáme nějaké CSS pro stylování záhlaví (zatím bez interaktivity).

Výsledek:

Obrázek 2: Výsledné zobrazení HTML & CSS po kroku 3.

Krok 4: Interaktivita pomocí čistého CSS

Při vytváření interaktivních widgetů pomocí CSS máte několik možností:

  1. Použijte rádia nebo zaškrtávací políčka
  2. Použijte pseudotřídu :target.

Rádia a zaškrtávací políčka fungují úžasně dobře pro většinu widgetů, jako jsou karty, modály, rozbalovací nabídky a harmoniky. Chris Coyier tuto techniku nazval „checkbox hack“. Několik vývojářů tento „hack“ použilo pro své nabídky mimo plátno, například v tutoriálu Paula Lewise pro Chrome Dev Summit nebo v morfující nabídce hamburgeru Luise Manuela.

V tomto případě použití je však pseudotřída :target sémantičtější, protože se přímo zabýváme navigací. Možná s tím nesouhlasíte, a to je zcela v pořádku! Bylo by neuvěřitelně snadné a naprosto přijatelné vyměnit pseudotřídu :target za zaškrtávací políčko.

Obě techniky však mají svá úskalí.

Použití zaškrtávacího políčka:

  • Vyžaduje, aby JavaScript zavřel nabídku mimo plátno, pokud jeden z odkazů v nabídce byl kotevním odkazem na určitou část téže stránky.
  • Vyžaduje, aby <vstupní> pole bylo sourozencem nabídky nebo alespoň sourozencem předka nabídky. Jinými slovy, CSS je trochu složitější. Můžete však mít <štítek> (i více štítků) jinde.
  • Prvek <štítek> nebude přímo zaostřitelný ani tabelovatelný, což vyžaduje trochu složitější CSS pro obsluhu zaostření na zaškrtávací políčko a zároveň změnu viditelného vzhledu <štítku>.
  • Navigace na klávesnici kolem otevření/zavření nabídky bude vrtkavá. Ovlivnění změny stavu zaškrtávacího políčka se provádí prostřednictvím nikoliv klávesy. Zatímco nevidomí uživatelé mohou pochopit, že widget je ovládán zaškrtávacím políčkem, vidící uživatelé klávesnice budou zmateni, protože zaškrtávací políčko není patrné – což jsem v tomto případě použití považoval za problém.

Použití pseudotřídy :target:

  • Přidá otevření/zavření nabídky mimo plátno do historie prohlížeče (odsunutí hashe do adresního řádku). Bude vyžadovat spuštění funkce Event.preventDefault() v JavaScriptu, aby se tomu zabránilo (a potenciálně otravnému přeskakování na začátek stránky).

A možná existují i další výhrady, které jsem přehlédl. Každopádně výběr té které techniky je jednak otázkou preferencí, jednak závisí na požadavcích vašeho projektu. Každopádně jsem odbočil…

Tady je interaktivní část CSS:

Krok 4: Přidejte nějaké CSS pro interaktivitu.

Výsledek po kliknutí:

Obrázek 3: Výsledné zobrazení hamburgerové nabídky po jejím otevření.

Jak to všechno funguje

Pseudotřída :target nám v podstatě poskytuje nový „stav“ pro stylování cílené navigace. Když je hlavní menu cílené (s jeho hashem přidaným do adresy URL), můžeme nyní menu vysunout. Je to něco jako pseudotřída :focus pro cílený prvek (ne pro samotný odkaz).

Povolili jsme také zobrazení „pozadí“, když je navigace cílená.

Všimněte si, že ikona hlavního hamburgeru je spojena s ID navigace, zatímco ikona zavření i tlačítka pozadí jsou spojena s ikonou hlavního hamburgeru. To nám umožňuje kliknutím na ikonu zavřít nebo na pozadí odstranit „focus“ – nebo vlastně :target – z navigace. Kdyby pozadí nebylo odkazem, nebylo by na něj možné kliknout bez JavaScriptu.

Selektory :target jsem také zřetězil spolu s atributem v CSS. To bude nakonec místo, kde budeme postupně vylepšovat hamburgerové menu pomocí JavaScriptu, aby po kliknutí neskákalo do záhlaví – vyhneme se tak výhradě, kterou jsem zmínil dříve. To, že JavaScript unese chování hash prohlížeče, znamená, že pseudotřída :target již nebude fungovat. Až k tomu dojde, využijeme atribut pro stylování přepínání pomocí hodnot true/false podobně, jako jsme to mohli udělat v minulosti s třídami.

Zatím to však krásně funguje bez JavaScriptu.

Přidal jsem dotaz @supports media query, abych poskytl preferovanou pozici:fixed CSS prohlížečům (mobilním i desktopovým), které ji podporují. Jinak chromé prohlížeče a zařízení – dívám se na tebe iOS – dostanou position:absolute.

Krok 5: Styly pro větší obrazovky

Protože nechceme, aby se nabídka hamburgeru zobrazovala na nemobilních zařízeních (nebo obecně na větších obrazovkách), přidáme pro to potřebný dotaz na média. Pak ji nastylujeme tak, aby vypadala jako horizontální navigace:

Krok 5: CSS pro stylování navigace na větších obrazovkách.

Výsledek:

Obrázek 4: Výsledné zobrazení navigace stylizované pro větší obrazovky.

Voila! Máme hotovo!

Složení dohromady

Tady je finální HTML:

Finální HTML pro responzivní hamburgerovou nabídku používající pouze CSS.

Tady je finální CSS:

Finální CSS pro responzivní hamburger menu.

Demo

Vyzkoušejte si můj CodePen na vlastní kůži:
→ Pure CSS Hamburger Menu bez JavaScriptu.

Poznámka: můžete si předvést i verzi menu se zaškrtávacím políčkem.

Chcete přidat JavaScript, aby to bylo svižnější?

Přestože můžeme zajistit, aby menu mimo plátno fungovalo výhradně pomocí CSS – což zlepší jeho výkon a spolehlivost – stále budeme potřebovat JavaScript, který nám nějakým způsobem pomůže zlepšit interaktivitu kolem nevýhod obou technik. JavaScript můžete využít také k tomu, abyste zabránili posouvání stránky, když je nabídka otevřená.

Je třeba také poznamenat, že slušné úrovně (a pravděpodobně nejdůležitější úrovně) přístupnosti lze dosáhnout i bez JavaScriptu. Je však obtížné zajistit solidní úroveň přístupnosti bez schopnosti JavaScriptu manipulovat s DOM (např. správa zaměření, aktualizace atributů ARIA atd.).

Další informace o zlepšování přístupnosti webu pomocí JavaScriptu najdete v následujících článcích:

  • Použití atributů ARIA pro nastavení stavu JavaScriptu &stylování
  • Psaní JavaScriptu s ohledem na přístupnost

Máte další nápady nebo návrhy?

Uvítám vaše připomínky k mému přístupu k čistě hamburgerové nabídce CSS.

Úpravy a pozdější úvahy

21. ledna 2019: Upraven článek a aktualizovány příklady kódu s cílem odstranit zbytečné atributy ARIA a zlepšit přístupnost.

Když jsem se naučil více o používání ARIA a vývoji &testování přístupnosti obecně, uvědomil jsem si několik věcí:

  1. JavaScript má rozhodně své místo a měl by být součástí každého robustního vzoru uživatelského rozhraní pro přístupnost.
  2. S výjimkou orientačních bodů ARIA je pro správné používání ARIA vyžadován JavaScript. A mnoho atributů, které jsem použil, jako je lepší ponechat pro JavaScript, aby je přidal po načtení, místo aby je přidával přímo ve značce. Tento koncept se řídí správnými postupy progresivního vylepšování – stavy a vlastnosti ARIA spolu s JavaScriptem jsou nadstavbou a měly by být řešeny na samostatné vrstvě.
  3. Předtím jsem neřešil správně fokus, protože při postupu přes vizuálně skryté odkazy (při sbalení) fokus mizel. Do menu CSS jsem přidal display: none;, abych to napravil.

Pokud jste tedy implementovali předchozí verzi mého menu Pure CSS Off-Canvas Hamburger Menu, zvažte prosím jeho aktualizaci na tuto jednodušší a přístupnější verzi!

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.