Nastoletni
Programiści

Logo Nastoletnich Programistów

Rozwijane menu mobilne w czystym CSSie

Witajcie! W tym poradniku pokażę wam w jaki sposób przy użyciu czystego CSSa zrobić rozwijane menu, będące jednym z najpospolitszych rozwiązań nawigacji na urządzeniach mobilnych.

Zaprezentowany sposób nada się także do podobnych zastosowań, jak chociażby znany z for internetowych [spoiler]

Zasada działania

Cała filozofia działania opiera się na input[type="checkbox"] wraz z label‚em. Checkbox chowamy, label stylujemy na przycisk lub odnośnik, a w CSSie pokazujemy i chowamy zawartość menu przy użyciu pseudoklasy :checked oraz selektora rodzeństwa ~.

Dla checkboxa warto profilaktycznie dodać atrybut autocomplete z wartością off, aby zapobiec przeglądarce wczytywaniu mu zaznaczenia z historii wypełnianych formularzy. Gwoli dostępności, nadamy checkboxowi aria-hidden="true", aby czytniki ekranowe go ignorowały.

Podrasuję graficznie nasze menu, aby na potrzeby poradnika rzeczywiście przypominało menu, a nie było paroma szeryfowymi linijkami tekstu:

Coś milszego dla oka

Menu działa, jednak pojawia się od razu, bez żadnej animacji. Animację można oczywiście zrobić w JSie. Prawda? Oczywiście, że można, ale my to zrobimy w CSSie. Bo można i to od dawna.

Załóżmy, aby animacja była taka sama jak na stronie na której to teraz czytasz w momencie pisania tego posta. Czyli obok tekstu „Rozwiń menu” dwa trójkąty wskazujące kierunek w który podąży menu przy kliknięciu. W dół gdy jest zwinięte i w górę gdy rozwinięte. Do tego niech rozsuwa się nie w jednej klatce, a interpoluje w, załóżmy, pół sekundy.

Na początek dodam pseudoelementami :before i :after oraz atrybutem content te trójkąciki. Jest to zwykły znak Unicode, możesz go skopiować: ▼.

Gdy checkbox jest zaznaczony (a więc menu rozsunięte) trójkącik powinien mieć wierzchołek zwrócony ku górze. Możemy po prostu zmienić content na inny trójkącik, albo, co jest IMO milsze dla oka, obrócić go ku górze, również interpolując rotacją przez pół sekundy. Zrobimy to przez nadanie transform: rotate(180deg) oraz -180deg odpowiednio dla :before oraz :after. Aby transformacja ta była animowana, dodajmy transition: transform .5s linear.

Animowanie rozsuwania się menu jest natomiast w czystym CSSie rzeczą ciut trudniejszą do osiągnięcia. Aby interpolować między dwiema wartościami, obie muszą być ustalone. A więc height gdy checkbox nie jest zaznaczony powinien mieć wartość 0, natomiast gdy zaznaczony – no właśnie, jaką powinien mieć wartość? Do wartości autoinherit czy initial nie można interpolować, a z poziomu CSSa nie znamy wysokości tego elementu. Ja widzę w tym przypadku jedno wyjście. Animować nie heightmax-height, gdzie tą drugą wartość należy ustawić na taką, która będzie realną górną granicą wysokości tego elementu. Im większa będzie różnica między wartością max-height a realną wysokością elementu nawigacji, tym większy będzie odstęp czasu między końcem animacji a osiągnięciem przez nawigacji pełnej długości.

To wszystko opakowane w kod prezentuje się następująco:

Jeżeli macie jakieś pytania zadajcie je w komentarzu, postaram się odpowiedzieć na każde 🙂

Albert

Główny admin Nastoletnich Programistów. Czuje się dobrze w webdeveloperce. Lubi jeździć na rowerze. Na co dzień uczeń technikum informatycznego.

Zobacz wszystkie posty tego autora →

Komentarze