Responsive, Pure CSS Off-Canvas Hamburger Menu

, Author

Ostatnia aktualizacja 21 stycznia 2019 r.

Pure CSS off-canvas hamburger menus nie są niedawnym odkryciem. W końcu Chris Coyier napisał o tej technice jeszcze w listopadzie 2012 roku.

  • Jeśli jest to dla ciebie stara sztuczka, to powiesić się ze mną na trochę. Ulepszyłem przykład Chrisa i chciałbym poznać twoje opinie.
  • Jeśli jest to dla ciebie nowość, nie martw się. Masz dużo towarzystwa, jako że wydaje się, że duża część sieci jeszcze tego nie załapała.

W ten sposób zbudujemy proste, responsywne menu hamburgerowe poza kanwą, używając tylko CSS, które łatwo będzie włączyć do twojego własnego projektu. Ale najpierw…

Co jest nie tak z JavaScriptem?

Nic.

Aaron Gustafson wyjaśnia znaczenie Progressive Enhancements i rolę JavaScript w tworzeniu stron internetowych lepiej niż ja kiedykolwiek mogłem. Powinieneś przeczytać jego post. Ale dla zwięzłości, postaram się go podsumować:

  • „Podstawowe zadania zawsze można wykonać bez JavaScriptu.”
  • Podstawowe zadania powinny być wykonywane na najbardziej stabilnej warstwie (tj. nie JavaScript).
  • Progresive Enhancements nie jest anty-JavaScript. Chodzi tylko o zastosowanie właściwych technologii na właściwej warstwie.
  • „Ponieważ istnieje jakaś szansa, że JavaScript nie będzie działał, musimy zawsze brać pod uwagę tę szansę.”
  • Nigdy nie jest dobrym pomysłem ignorowanie potencjalnych użytkowników.
  • Progressive Enhancements to po prostu dobra inżynieria.

Więc, zrobimy tyle, ile się da z HTML i CSS. Następnie niech JavaScript zrobi swoją magię na bardziej odpowiedniej warstwie – poprawiając już istniejący UI.

Krok 1: HTML

Jak być może wiesz, pierwszym krokiem jest zawsze napisanie solidnej, dobrze przemyślanej, bazowej warstwy HTML.

Uwaga: Używam Font Awesome dla ikon w moim przykładzie.

Krok 1: Początkowy HTML dla czystego CSS responsywnego menu hamburgera

Wygląda raczej standardowo, prawda? Mamy:

  • Naszego rodzica <element header>
  • Ikonę hamburgera („fa-bars”)
  • Główny nagłówek (lub potencjalnie logo)
  • Nawigację w elemencie <nav>
  • Ikonę zamknięcia („fa-close”) wewnątrz nawigacji (więcej na ten temat później)
  • Ikona „backdrop” po nawigacji. Dlaczego jest to znacznik anchor? Wyjaśnię później.

Krok 2: Uczyńmy ją bardziej dostępną

Dostępność nigdy nie powinna być czymś po fakcie – jak po napisaniu aplikacji. Powinna być zaplanowana od samego początku. Dodanie kilku podstawowych uwag teraz nie tylko poprawi ogólną dostępność twojej strony, ale zapewni tobie (deweloperowi) lepszy znacznik do wykorzystania w twoim JavaScript!

W związku z tym, dodamy jeszcze kilka atrybutów i trochę tekstu przeznaczonego tylko dla czytników ekranu:

Krok 2: Ulepszenie HTML, aby był bardziej dostępny.

Tutaj jest szybki podział wszystkich tych atrybutów i jak one działają:

  • Dodaliśmy unikalne identyfikatory do kierowania naszych HREFów (więcej o tym jak to działa później).
  • Zapewniliśmy informacyjną etykietę przycisków dla czytników ekranu za pomocą .
  • Ukryliśmy ikony przed czytnikami ekranu za pomocą , ponieważ są one wizualnymi reprezentacjami, i dodaliśmy tekst tylko dla czytników ekranu za pomocą elementów <span class=”sr-only”>.
  • Wyjęliśmy „tło” z indeksu tabulacji za pomocą . Jest to czysto wizualna natura i nie chcemy dezorientować naszych niedowidzących i używających klawiatury użytkowników.
  • Dodaliśmy atrybut amazing, aby ustawić początkowy (i semantyczny) stan „tła”. Koniec ze śmieciami – jakże ekscytujące!

Oto dotychczasowy rezultat:

Rycina 1: Wynikowe wyświetlanie HTML po krokach 1 i 2.

Krok 3: Wystylizujmy to!

Podejdziemy do tego mobile-first, więc zlikwidujmy widok mobilny, „hamburgerowy” (interesująca część).

Najpierw zajmiemy się tylko poprawnym układem nagłówka (bez interaktywności):

Krok 3: Dodaj trochę CSS do stylizacji nagłówka (na razie bez interaktywności).

Wynik:

Rysunek 2: Wynik wyświetlania HTML & CSS po kroku 3.

Krok 4: Interaktywność za pomocą czystego CSS

Przy tworzeniu interaktywnych widżetów za pomocą CSS, masz kilka opcji:

  1. Użyj radia lub checkboxów
  2. Użyj pseudo-klasy :target.

Radia i checkboxy działają zadziwiająco dobrze dla większości widżetów, takich jak zakładki, moduły, dropdowns i akordeony. Chris Coyier nazwał tę technikę „the checkbox hack”. Kilku programistów użyło tego „hacka” do swoich menu poza kanwą, jak w tutorialu Paula Lewisa na Chrome Dev Summit lub w morfującym menu hamburgerowym Luisa Manuela.

Jednakże, pseudoklasa :target jest bardziej semantyczna w tym przypadku użycia, ponieważ mamy do czynienia bezpośrednio z nawigacją. Możesz się nie zgodzić, i to jest całkowicie w porządku! Byłoby niewiarygodnie łatwo i całkowicie do zaakceptowania zamienić pseudoklasę :target na checkbox.

Każda z tych technik ma jednak swoje zastrzeżenia.

Użycie pola wyboru:

  • Wymaga JavaScript do zamknięcia menu off-canvas jeśli jeden z linków w menu był linkiem zakotwiczonym do konkretnej sekcji tej samej strony.
  • Wymaga aby pole <input> było rodzeństwem menu lub przynajmniej rodzeństwem przodka menu. Innymi słowy, CSS jest nieco bardziej skomplikowany. Możesz mieć <label> (nawet wiele etykiet) gdzie indziej, chociaż.
  • Element <label> nie będzie bezpośrednio focusowalny lub tab-able, wymagając nieco bardziej skomplikowanego CSS do obsługi fokusu na polu wyboru przy jednoczesnej zmianie widocznego wyglądu <label>.
  • Nawigacja klawiaturowa wokół otwierania/zamykania menu będzie niemiła. Zmiana stanu pola wyboru jest dokonywana za pomocą klawisza, a nie klawisza. Podczas gdy niewidomi użytkownicy mogą zrozumieć, że widżet jest obsługiwany przez pole wyboru, widzący użytkownicy klawiatury będą zdezorientowani, ponieważ pole wyboru nie jest widoczne – coś, co uważałem za wyłącznik w tym przypadku użycia.

Użycie pseudoklasy :target:

  • Dodaje otwarcie/zamknięcie menu off-canvas do historii przeglądarki (przesuwając hash do paska adresu). Będzie wymagać JavaScript, aby uruchomić Event.preventDefault(), aby tego uniknąć (i potencjalnie irytujące przeskakiwanie na górę strony).

I mogą być inne zastrzeżenia, które przegapiłem. Tak czy inaczej, wybór, która technika jest zarówno kwestią preferencji, jak i podlega wymaganiom twojego projektu. W każdym razie, odbiegam od tematu…

Oto interaktywna część CSS:

Krok 4: Dodaj trochę CSS dla interaktywności.

Wynik po kliknięciu:

Rycina 3: Wynik wyświetlania menu hamburgera po jego otwarciu.

Jak to wszystko działa

Podsumowując, pseudo-klasa :target daje nam nowy „stan” do stylizacji docelowej nawigacji. Kiedy main-menu zostało namierzone (z jego hashem dodanym do URL), możemy teraz wysunąć menu. Jest to trochę jak pseudoklasa :focus dla elementu docelowego (nie dla samego linku).

Pozwoliliśmy także na wyświetlanie „tła”, gdy nawigacja jest docelowa.

Zauważ, że ikona głównego hamburgera jest powiązana z ID nawigacji, podczas gdy zarówno ikona zamknięcia jak i przyciski tła są powiązane z ikoną głównego hamburgera. To pozwala nam kliknąć ikonę zamknięcia lub tło, aby usunąć „fokus” – lub naprawdę :target – z nawigacji. Gdyby tło nie było linkiem, nie byłoby klikalne bez JavaScript.

Połączyłem także selektory :target wraz z atrybutem w CSS. To ostatecznie będzie miejsce, gdzie stopniowo wzmocnimy menu hamburgera za pomocą JavaScript, aby nie przeskakiwało do nagłówka po kliknięciu – unikając zastrzeżenia, o którym wspomniałem wcześniej. Posiadanie JavaScriptu porywającego zachowanie hash przeglądarki oznacza, że pseudo-klasa :target nie będzie już działać. Kiedy to się stanie, skorzystamy z atrybutu, aby stylizować przełączanie za pomocą wartości true/false, tak jak mogliśmy to zrobić w przeszłości z klasami.

W międzyczasie jednak, działa to pięknie bez JavaScriptu.

Dodałem zapytanie medialne @supports, aby dostarczyć preferowane position:fixed CSS do przeglądarek (zarówno mobilnych jak i desktopowych), które je obsługują. W przeciwnym razie, kiepskie przeglądarki i urządzenia – patrzę na ciebie iOS – dostaną position:absolute.

Krok 5: Style dla większych ekranów

Ponieważ nie chcemy, aby menu hamburgera wyświetlało się na urządzeniach niemobilnych (lub ogólnie na większych ekranach), dodamy niezbędne media query. Następnie wystylizujemy je tak, aby wyglądało jak pozioma nawigacja:

Krok 5: CSS do stylizacji nawigacji na większych ekranach.

Wynik:

Rycina 4: Wynikowy wygląd nawigacji stylizowanej na większe ekrany.

Woila! Skończyliśmy!

Podsumowanie

Tutaj jest końcowy HTML:

Finalny HTML dla responsywnego menu hamburgerów używającego tylko CSS.

Tutaj jest końcowy CSS:

Finalny CSS dla responsywnego menu hamburgera.

Demo

Wypróbuj mój CodePen dla siebie:
→ Czyste CSS Hamburger Menu bez JavaScript.

Uwaga: możesz również zademonstrować wersję menu z polem wyboru.

Chcesz dodać JavaScript, aby było zgrabniejsze?

Mimo iż możemy sprawić, że menu poza kanwą będzie działało całkowicie przy użyciu CSS – poprawiając jego wydajność i niezawodność – nadal będziemy potrzebowali JavaScript, aby w jakiś sposób pomóc w poprawieniu interaktywności otaczającej wady obu technik. Można również wykorzystać JavaScript, aby zapobiec przewijaniu strony, gdy menu jest otwarte.

Warto również zauważyć, że przyzwoity poziom (i prawdopodobnie najważniejszy poziom) dostępności można osiągnąć bez JavaScript. Jednakże, trudno jest zapewnić solidny poziom dostępności bez zdolności JavaScript do manipulowania DOM (np. zarządzanie fokusem, aktualizacje atrybutów ARIA, itp.)

Aby uzyskać więcej informacji na temat zwiększania dostępności witryny za pomocą JavaScript, zapoznaj się z następującymi artykułami:

  • Używanie atrybutów ARIA do ustawiania stanu JavaScript& stylizacja
  • Pisanie JavaScript z myślą o dostępności

Masz inne przemyślenia lub sugestie?

Chciałbym usłyszeć Twoje komentarze na temat mojego podejścia do menu hamburgerów w czystym CSS.

Edity i późniejsze ruminacje

21 stycznia 2019: Edytowany artykuł i zaktualizowane przykłady kodu, aby usunąć niepotrzebne atrybuty ARIA i poprawić dostępność.

Jak dowiedziałem się więcej o używaniu ARIA i rozwijaniu & testowania pod kątem dostępności w ogóle, zdałem sobie sprawę z kilku rzeczy:

  1. JavaScript zdecydowanie ma swoje miejsce i powinien być częścią każdego solidnego wzorca UI dostępności.
  2. Z wyjątkiem punktów orientacyjnych ARIA, JavaScript jest wymagany do prawidłowego korzystania z ARIA. I, wiele atrybutów, których użyłem, jak są lepiej pozostawione dla JavaScript, aby dodać je po załadowaniu, zamiast dodawać je bezpośrednio w znaczniku. Ta koncepcja jest zgodna z dobrymi praktykami Progressive Enhancement – stany i właściwości ARIA wraz z JavaScriptem są uaktualnieniem i powinny być obsługiwane na osobnej warstwie.
  3. Poprzednio nie obsługiwałem poprawnie fokusu, ponieważ fokus znikałby w miarę przechodzenia przez wizualnie ukryte linki (gdy są zwinięte). Dodałem display: none; do CSS menu, aby to naprawić.

Więc, jeśli zaimplementowałeś poprzednią wersję mojego Pure CSS Off-Canvas Hamburger Menu, proszę rozważ aktualizację do tej prostszej i bardziej dostępnej wersji!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.