Responsywne menu

Ostatnio poprawiliśmy wygląd naszego menu a dzisiaj zrobimy je responsywne.

 

Nasze menu będzie klasycznym „hamburgerem” i jego zrobienie możemy wykonać na kilka sposobów. Możemy np. zrobić za pomocą samego CSS i skorzystać z „ukrytego” elementu checkbox albo np. skorzystać z JS. Myślę, że nie ma sensu bawić się w kombinowanie z checkboxem (lub jeszcze innymi „trikami”) a zaczniemy poznawać JS 🙂

 

Wprowadzenie

Jak w ogóle pracować nad responsywnością? Przede wszystkim, jeśli nie chcecie ciągle przesyłać kodu na serwer i testować/sprawdzać na telefonie/tablecie to warto korzystać z takich narzędzi jak Dev Tools (narzędzia programistyczne/narzędzia dla programistów) dostępne w przeglądarkach. W chrome dostępne w Menu -> Więcej narzędzi -> Narzędzia dla programistów a np. w Firefoxie w Menu -> Narzędzia -> Inspektor. Następnie musimy włączyć widok responsywny (dalsze przykłady będą bazować na Google Chrome)

Google Chrome
Firefox

 

Otrzymamy coś takiego:

 

Teraz przeciągając „belki” (po prawej stronie i na dole) albo wpisując na górze możemy zmieniać rozmiar strony. Niestety w tej chwili przy zmniejszaniu rozmiaru strony tekst się zmniejsza (skaluje). Dzieje się tak dlatego, że domyślnie strona jest generowana jak na komputery (po więcej szczegółów odsyłam do strony Google – nie, nie wyszukiwarki 😉 ) Aby to naprawić wystarczy w sekcji <head> dodać

https://codepen.io/morawcik/pen/NjJaoj

 

Guzik menu

Zaczniemy od utworzenia buttona, który będzie otwierał i zamykał menu (oczywiście na początek bez tej funkcji, do tego dojdziemy).

Na początek musimy określić w jakim rozmiarze strony będzie pojawiało się responsywne menu a zarazem wspomniany button. Jak to określić? Można tak zmniejszać szerokość okna aż menu zacznie się zawijać do nowej linii (lub do momentu aż prawy odstęp od krawędzi strony nie zacznie się zmniejszać) albo samemu ustalić nieco większy rozmiar. U nas będzie to 600px ale zanim przejdziemy do implementacji tego to stworzymy button, który będzie cały czas widoczny.

Stworzymy go jako odnośnik z wykorzystaniem ikony oferowanej przez FontAwesome (jest to zbiór wielu ikon, który w łatwy sposób można wykorzystać na stronie). Dlaczego będziemy z tego korzystać? W tej chwili to tylko jedna ikona ale przy rozbudowie bloga pojawi ich się więcej i dzięki temu nie musimy szukać każdej ikony osobno, pobierać jako obrazek i wrzucać na stronę.

Aby skorzystać z FA musimy w <head> dodać odwołanie do pliku css z FA. My wykorzystamy do tego BootstrapCDN. Co to jest CDN? W skrócie jest to system do którego dostarcza się jakąś treść (jak FA) i który powiela tą treść na wiele swoich serwerów rozsianych po świecie a gdy użytkownik będzie się do tego odwoływał (wyświetlenie strony) to dostaje treść z tego serwera, który zapewni najszybszy dostęp (najczęściej ten zlokalizowany najbliżej użytkownika). Przy następny odwołaniu użytkownik dostaje wersję z cache co jeszcze bardziej przyśpiesza wczytanie treści.

 

Wystarczy dodać do <head>

a następnie dodajemy nasz button, który będzie odnośnikiem:

Element <i> to właśnie nasza ikona, która ma dwie klasy: „fa”, która ustawia ogólne style dla ikon z FontAwesome oraz „fa-bars”, która odpowiada za wygląd konkretnej ikony (w naszym przypadku ikony „hamburgera”). Klasa „menu-icon” w odnośniku posłuży nam do nadania odpowiedniego wyglądu temu buttonowi.

Dodajemy zaraz na początku elementu <nav>

https://codepen.io/morawcik/pen/bWZYLv

 

Oczywiście, to nie jest to czego oczekujemy – musimy zająć się jego wyglądem.

Najpierw dostosujemy go do wyglądu reszty odnośników w menu dlatego do reguł „nav li a” i „nav li:hover a” dodajemy nasz przycisk

Dzięki temu, nie musimy pisać tego dwa razy a w razie chęci zmiany wyglądu menu mamy mniej pracy.

https://codepen.io/morawcik/pen/YVgeyd

 

Następnie musimy umieścić go w odpowiednim miejscu. Myślę, że może być tak jak zaczyna się odnośnik do strony głównej.

Dlaczego dodałem „display: inline-block”? Dla pokazania gdzie będzie się znajdował przycisk, który będzie widoczny gdy szerokość strony będzie mniejsza niż 600px.

https://codepen.io/morawcik/pen/qmvxpQ

 

Media queries

Na koniec pozostaje nam tylko ukryć menu i pokazać przycisk jeśli szerokość strony jest poniżej 600px i na odwrót (pokazać menu i ukryć przycisk jeśli jest > 600px). Do tego potrzebujemy użyć media query, które pozwalają określić jak ma się zachować dany element przy danej rozdzielczości.

Domyślnie nasz przycisk powinien być ukryty dlatego w „nav .menu-icon” zamieniamy „display” na ten właściwy

https://codepen.io/morawcik/pen/BRbYGL

 

Teraz możemy dodać media queries. Jak to zrobić? Dodając do CSS coś takiego:

„@media” informuje przeglądarkę, że style zawarte w nawiasach klamrowych będzie używał media queries. „max-width: 600px” informuje natomiast, że te style mają działać tylko jeśli szerokość strony będzie nie większa niż 600px. Oczywiście to podstawowa wersja media queries. Na stronie można używać wiele różnych media queries o różnym stopniu „skomplikowania” ale tym zajmiemy się w przyszłości.

Teraz wystarczy tylko wstawić tam odpowiednie style. Musimy nakazać aby nasze menu się schowało. Zrobimy to zmieniając „display” na „none”

https://codepen.io/morawcik/pen/ZKPrdR

 

Przy zmniejszeniu rozmiaru strony poniżej 600px zobaczycie, że nasz pasek z menu zniknął ale bez obaw – w tej chwili nic się w nim nie pojawia więc nie wie jak wysoki ma być i dlatego się „ukrył” (ma height/wysokość 0px). Musimy teraz pokazać nasz przycisk zmieniając mu „display” na „inline-block” – tak jak miał na początku do „testowania”.

Dodatkowo zwiększyłbym temu przyciskowi wielkość czcionki ustawiając „font-size” na 22px – wstawione do zwykłej reguły a nie w media queries

https://codepen.io/morawcik/pen/bWZvEr

 

Przy zmienianiu szerokości tak by przeskakiwać z pełnego menu do przycisku zauważycie, że obie „wersje” różnią się nieznacznie wysokością paska menu. Dzieje się tak dlatego, że wysokość odnośników razem z marginesami i paddingiem jest większa niż wysokość przycisku z jego marginesami. Mamy dwa wyjścia: albo zostawić tak jak jest – w końcu mobilne ekrany mają mniej miejsca i pasek menu mniej by zajmował albo można zmienić margines dla przycisku. Wybór zostawiam Wam a razem przejdziemy do kolejnej części.

 

Menu mobilne

Przedostatnim etapem jest odpowiedni wygląd menu, które pojawi się po kliknięciu w przycisk i dlatego tymczasowo zmienimy w menu (<ul>) „display” na „block”

https://codepen.io/morawcik/pen/PmLRWm

 

Myślę, że wystarczy jak sprawimy, że w wersji mobilnej odnośniki (a raczej elementy listy <li> w których są umieszczone) będą się wyświetlały jeden pod drugim dodając do media queries:

co sprawi, że nadamy im styl blokowy – wyświetla się tylko jeden element w linii

https://codepen.io/morawcik/pen/oWVqZX

 

Aby nie przeciągać to na tym skończymy stylowanie menu więc na koniec musimy przywrócić „display: none” dla menu w wersji < 600px

 

Klikamy (JS)

Ostatnim etapem jest sprawienie, by po kliknięciu w przycisk menu się pokazywało lub ukrywało i do tego wykorzystamy JS. Bez obaw, to będą podstawy i wszystko wytłumaczę 🙂

Jak można dodać kod JavaScript na stronę? Są dwie opcje:

1. Tworzymy kod w osobnym pliku z rozszerzeniem .js i wstawiamy:

gdzie „sciezka/do/pliku.js” to ścieżka do pliku w projekcie – np. „obok” pliku index.html (lub jakiegokolwiek, który macie) albo w jakim katalogu – np. „js” (lepsza opcja – wtedy mam pliki JS umieszczone w jednym miejscu i nie wymieszane z innymi plikami) albo gdzieś w internecie – np. w jakimś CDN.

Gdzie to wstawiamy? Mamy dwie możliwości: albo w sekcji <head> albo na samym dole strony zaraz przed </body>. Polecane jest aby wstawiać przed </body> gdyż w trakcie wczytywania strony przeniesiemy moment wczytywania pliku na sam koniec i użytkownik wcześniej zobaczy zawartość strony.

 

2. Możemy umieścić kod bezpośrednio w tagach

I tak samo jak w przypadku użycia osobnego pliku możemy stawić w <head> lub w dowolnym miejscu w <body> (ponownie najlepiej przed </body>).

To rozwiazanie jest dobre jeśli kodu jest mało – z kilkoma linijkami nie będzie problemu ale jeśli kod JS będzie się rozrastał to warto go oddzielić od kodu HTML.

 

My zaczniemy od opcji numer dwa 🙂 Na początek:

„var button” to deklaracja zmiennej o nazwie „button” dzięki temu możemy później odwoływać się do tej zmiennej zamiast przepisywać ciagle document.getElementsByClassName(„menu-icon”)

document.getElementsByClassName(„menu-icon”)[0] – ten fragment można podzielić na dwie części „dokument” i .getElementsByClassName(„menu-icon”):

  • „dokument” określa, że będziemy pracować na dokumencie czyli stronie
  • .getElementsByClassName(„menu-icon”) – to wywołanie funkcji getElementsByClassName z parametrem „menu-icon” na obiekcie „dokument. Można po ludzku? Pewnie – wywołujemy funkcję „getElementsByClassName”, która pobiera wszystkie elementy na stronie, które mają nadaną klasę „menu-icon”.getElementsByClassName zwraca wszystkie elementy w postaci tablicy i dodanie na końcu „[0]” informuje, że chcemy pobrać tylko pierwszy taki element i jest to odwołanie do tablicy (więcej w przyszłych częściach)

 

Następnie musimy „powiedzieć” JS, że chcemy, żeby coś zrobić po kliknięciu na button. Służą do tego eventy (np. kliknięcie, najechanie myszką, naciśnięcie klawisza – wrócimy do nich w przyszłości). Tak możemy zadeklarować event dla naszego buttona

Po kliknięciu („onclick”) na „button” (gdzie „przechowywany” jest nasz odnośnik) wykonaj anonimową (bez nazwy) funkcję (function() {})

 

Zacznijmy od dodania do naszego menu klasy „menu”

Teraz musimy tylko zadbać o to aby w tej funkcji był kod odpowiedzialny za pokazywanie/ukrywanie menu. Utworzymy sobie nową klasę, którą dodamy do CSS

Jeśli dodamy klasę „show” do menu to nasze menu się pojawi na stronie. Wystarczy nakazać JS aby po kliknięciu dodawał lub usuwał tą klasę:

W pierwszej linijce w naszej funkcji najpierw pobieramy pierwszy element, który ma klasę „menu” (czyli nasze <ul class=”menu”>) następnie pobieramy z tego elementu wszystkie klasy „classList” i wywołujemy funkcję „toggle”, która „przełącza” klasę „show” w tym elemencie (w menu). Co to znaczy? Jeśli funkcja „toogle” nie znajdzie w menu klasy „show” to tą klasę doda, natomiast jeśli ją znajdzie to usunie.

https://codepen.io/morawcik/pen/VbRXMa

 

I gotowe!

Jeśli coś jest dla Was niezrozumiałe albo chcecie o coś zapytać to piszcie śmiało 🙂

 

PS Ktoś się pokusi na własne eksperymenty z menu?


Post 7 z 11 z serii Blog od podstaw