HTML5 & CSS3

Jak w prosty sposób stworzyć responsywną nawigację?

Czytając w sieci publikacje na temat tego jak projektować nawigacje stron responsywnych natknąłem się na mnóstwo dziwnych i trudnych metod, które miały niezorientowanym przybliżyć sposób na stworzenie responsywnej nawigacji. Wiele z nich były zwykłym przerostem formy nad treścią, więc postanowiłem opisać jak szybko stworzyć nawigację strony, która będzie ergonomiczna również na urządzeniach mobilnych.

1. Wprowadzenie

Założenie jest proste. Chcemy aby nawigacja strony w wersji desktopowej wyświetlała się ergonomicznie i estetycznie również na urządzeniach mobilnych. Oczywiście chcielibyśmy też aby zachowała swoją funkcjonalność jednocześnie stając się intergralną częścią strony dostosowanej do wyświetlaczy urządzeń mobilnych.

Zadanie to możemy osiągnąć dzięki wykorzystaniu mediaqueries, dzięki którym buduje się strony responsywne. Mając je do dyspozycji „wystarczy” zmienić wygląd menu i użyć odrobiny JavaScriptu aby zmienić funkcjonowanie menu. Ten ostatni fragment jest szczególnie ważny ponieważ na urządzeniach mobilnych miejsce jest jeszcze cenniejsze niż na konwencjonalnych stronach. Dlatego dla zapewnienia funkcjonalności musimy zmienić nasze statyczne menu w coś trochę bardziej dynamicznego. W tym celu wykorzystamy znany schemat…

2. HTML

Przypuśćmy, że struktura naszego kodu HTML wygląda w ten sposób:

<section class="container">

<header>
<a href="#" class="btn open-menu">MENU</a>
  <nav class="clearfix">
    <a href="#" class="btn hide">« Zamknij</a>
    <a href="#" class="btn">Główna</a>
    <a href="#" class="btn">O nas</a>
    <a href="#" class="btn">Klienci</a>
    <a href="#" class="btn">Portfolio</a>
    <a href="#" class="btn">Kontakt</a>
  </nav>
</header>

  <article>
    <h1>Przykładowa strona</h1>  
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce dignissim sapien ipsum, ac tempor purus vulputate eget...</p>  
  </article>

</section>

Głównie interesować będzie nas element nav oraz link o klasie .open-menu. Te dwa elementy będziemy zmieniać przy pomocy mediaqueries. Reszta strony nas właściwie nie interesuje.

3. CSS

Dla uproszczenia przyjmiemy, że wszystko cos znajduje się poniżej szerokości 960px jest urządzeniem mobilnym. W tym przykładzie wprowadzimy, więc dwie wersje menu, aczkolwiek stosując większą ilość tzw. breakpointów (wyznaczanych przez mediaqueries) możecie stworzyć nawet kilka wersji nawigacji.

Kod CSS dla menu w wersji desktopowej jest następujący:

nav {margin:10px 0;}
  
    .btn {
      display: block;
      float:left;
      position:relative;
      padding:10px 20px;  
      margin-right: 5px;
      border-radius:5px;
      color:white;
      text-align: center;
      text-decoration: none;
      background: #da1b23; /* Old browsers */
      background: -moz-linear-gradient(top,  #da1b23 0%, #bc1e23 100%); /* FF3.6+ */
      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#da1b23), color-stop(100%,#bc1e23)); /* Chrome,Safari4+ */
      background: -webkit-linear-gradient(top,  #da1b23 0%,#bc1e23 100%); /* Chrome10+,Safari5.1+ */
      background: -o-linear-gradient(top,  #da1b23 0%,#bc1e23 100%); /* Opera 11.10+ */
      background: -ms-linear-gradient(top,  #da1b23 0%,#bc1e23 100%); /* IE10+ */
      background: linear-gradient(to bottom,  #da1b23 0%,#bc1e23 100%); /* W3C */
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#da1b23', endColorstr='#bc1e23',GradientType=0 ); /* IE6-9 */
    }
    .btn:hover {box-shadow:2px 2px 15px rgba(50, 50, 50, 0.47) inset;}
    .btn:active {top:2px;}
      
      .btn.hide {display:none;}
      .btn.open-menu {display:none;}

Jak widać mamy tutaj bardzo prostą strukturę CSS. Linki z klasami .hide i .open-menu ukrywamy ponieważ nie są one potrzebne użytkownikom komputerów.

W dalszej kolejności ustalamy wygląd menu poniżej 960px. To w większości wystarczy aby otrzymać zadowalający efekt, ale my pójdziemy o jeden krok dalej. Kod CSS wygląda następująco:

@media only screen and (max-width: 960px) {

  nav {
    display:none;
    position:absolute;
    margin:0;
    top:0;
    width:100%;
    background:#fff;
    padding:10px 0;
    background:url('noisy_net.png');
  }

    .btn {
      width:100%;
      float:none;
      padding:20px 0;
      margin:5px 0;
      border-radius:0;
      }
      
       .btn.hide {display:block;}
       .btn.open-menu {display:block;}    

}

Najważniejsze w powyższych deklaracjach są następujące aspekty:

  1. Wyłączamy wyświetlanie elementu nav co będzie nam potrzebne z punktu widzenia interakcji obsługiwanej przez kod JavaScript
  2. Nadajemy elementowi nav pozycję absolutną tak aby nachodził na inne elementy strony.
  3. Zmieniamy szerokość linków o klasie .btn na 100%
  4. Linkom o klasach .open-menu i .hide nadajemy wyświetlanie blokowe tak aby stały się widoczne na stronie

W ten sposób nasza domyślna nawigacja znika, a zamiast niej pojawia się guzik (link o klasie .open-menu) służący do wysuwania nawigacji.

4. Interakcja z menu

Teraz wystarczy, że napiszemy kod, który sprawi, iż kliknięcie w link o klasie .open-menu otworzy naszą nawigację. Zrobimy to przy użyciu jQuery, które i tak pewnie będziecie używać ;)

$(document).ready(function(){
  $('.open-menu, .hide').click(function(){
    $('nav').toggleClass('show');  
  });//open click
});//document ready end

Dzięki zastosowaniu mediaqueries, pośród linków w menu pojawił się link o klasie .hide. Kliknięcie go zamyka nawigacje.

Jedną nowością jest dodanie klasy .show. To dynamiczne przypisywanie jej i usuwanie w związku z wydarzeniem kliknięcie linków .hide i .open-menu powoduje, że nawigacja pojawia się i znika. Deklaracja klasy .show jest banalnie prosta:

nav.show {display:block;}

5. Podsumowanie

Jak widać stworzenie otwieranej nawigacji, które wyświetla się ergonomicznie na urządzeniach mobilnych można zrobić w sposób prosty i szybki. Wystarczy znajomość arkuszy stylów ;) i jQuery, dlatego nie widzę sensu w rozwiązaniach „na około”, które czasami można znaleźć w internecie…

Demo zostanie zaktualizowane w najbliższym czasie.

Zobacz demo on-line Pobierz pliki źródłowe

Image courtesy of Stuart Miles at FreeDigitalPhotos.net

komentarzy 14

  • Awatar
    Marcin Jagielnicki

    16 sierpnia 2013 12:22

    Po akcjach w takiej kolejności: zmniejszenie rozdzielczości, otwarciu i zamknięciu nawigacji a następnie zwiększeniu rozdzielczości, menu znika.

    Odpowiedz
    • Awatar
      Mr.Mr

      16 sierpnia 2013 13:46

      Faktycznie. Zmieniłem trochę sposób wyświetlania menu i działa.

      Dzięki za informację.

      Demo będzie dostępne jak Michał je wrzuci :P

      Odpowiedz
  • Awatar
    DMati

    16 sierpnia 2013 14:12

    Dorzuciłbym pozostałe mediaqueries z bootstrapa, albo jedynie dla width max 600px mobilne a dla max 960px „w pół drogi”.

    Odpowiedz
    • Awatar
      Mr.Mr

      17 sierpnia 2013 10:45

      W artykule jest jedynie przykład zastosowania. W prawdzimy projekcie powinno się wyznaczyć co najmniej 4 breakpointy.

      Odpowiedz
      • Awatar
        Adam

        20 sierpnia 2013 13:32

        W prawdziwym projekcie wystarczy jeden breakpoint, a stronę zakodować jako liquid layout.

        Odpowiedz
      • Awatar
        Mr.Mr

        20 sierpnia 2013 13:44

        To duże uproszczenie. Mimo wszystko strony liquid nie są lekarstwem na każde zło. Najczęściej dużo lepsze efekty otrzymuje się stosują podejście RWD w stylu serwowania róznych wersji strony przy różnych breakpointach.

        Odpowiedz
  • Awatar
    Guest

    19 sierpnia 2013 16:34

    mega spoko dzięki:)

    Odpowiedz
  • Awatar
    Krzysiek

    30 sierpnia 2013 12:47

    Pomysł jest dobry, ale jak zwykle można ciut inaczej.

    Ja zrobiłem responsywne menu zmieniające się z pomocą mediaqueries i oczywiście z jquery. Menu to jest oparte o menu i odpowiednio sformatowane. Gdy rozdzielczość jest mniejsza niż 768 px zwykłe menu zamieniam w select i sprawdza się to doskonale. Pozwolę sobie przytoczyć przykład jaki umieściłem na stronie http://www.elbox.info. Jak by było zainteresowanie mogę napisać krótki tutorialek.

    Odpowiedz
    • Awatar
      Mr.Mr

      30 sierpnia 2013 14:08

      nie ma semantycznie nic wspólnego z nawigacją. To duża wada takich rozwiązań.

      Odpowiedz
  • Awatar
    Damian

    31 marca 2015 15:11

    W momencie, gdy mam włączone rozwijane menu dla rozdzielczości mniejszej niż 960px, chciałbym aby po kliknięciu na daną pozycję Menu zamykało się automatycznie. Da się zrobić coś takiego?

    Odpowiedz
  • Awatar
    Szyszka

    25 lipca 2016 00:40

    Odpaliłam pliczek, by zobaczyć, jak to wygląda, i w ani desktopowym firefoxie, ani w desktopowej operze nie reaguje na kliknięcie na menu (obie najnowsze wersje). Wrzuciłam link do opery mobilnej i na telefonie wyszło cacy. Pytanie następuje: czemu nie chce działać normalnie? Spotkał się ktoś z tym problemem?

    Odpowiedz

Zostaw odpowiedź