HTML5 & CSS3

Rozwijane menu wielopoziomowe w CSS3

Wiele już razy otrzymywałem zapytania od Was na temat tworzenia nawigacyjnego menu, które rozwija się w kilku poziomach. Odnośnie tej kwestii dyskusja rozwinęła się w komentarzach do dwóch poprzednich wpisów (rozwijane menu i rozwijane menu w CSS3), gdzie padło kilka propozycji ku rozwiązaniu tego problemu, jednak wszystkie one pisane były „z palca”. W takim więc razie postanowiłem utworzyć nowy, osobny tutorial, zbiorczo podsumowujący wielopoziomowe nawigacje na stronach www. Oczywiście to tylko jeden sposób na osiągnięcie wymierzonego celu. Jeżeli posiadacie swoje techniki, bardzo chętnie się im przyjrzę.

Podstawowy schemat

Zaczynamy standardowo od przygotowania naszego menu za pomocą listy wypunktowanej w HTML5.

<ul id="mainmenu">
    <li><a href="#">Strona główna</a></li>
    <li><a href="#">Informacje</a><i class="arrow"></i>
        <ul>
            <li><a href="#">Witaj na poziomie #2</a></li>
            <li><a href="#">Witaj na poziomie #2</a></li>
            <li><a href="#">Witaj na poziomie #2</a></li>
        </ul>
    </li>
    <li><a href="#">Galeria</a>
        <ul>
            <li><a href="#">Witaj na poziomie #2</a></li>
            <li><a href="#">Przejdź do poziomu #3</a><i class="arrow"></i>
                <ul>
                    <li><a href="#">Witaj na poziomie #3</a></li>
                </ul>
            </li>
            <li><a href="#">Witaj na poziomie #2</a></li>
        </ul>
    </li>
    <li><a href="#">Kontakt</a></li>
</ul>

Zagnieżdżanych list chyba nie muszę nikomu tłumaczyć (jeżeli tak, to zapraszam z pytaniami na nasze forum webmasterskie). Aby uwidocznić możliwość rozwijania, przy każdym elemencie, który jest „rodzicem” i posiada elementy na niższych poziomach dodałem znacznik <i>, którego oczywiście jeszcze nie widać, ale tym zajmiemy się w części związanej z formatowaniem powyższego kodu.

Spójrzmy teraz na zrzut ekranu, który przedstawia nam obecny stan naszego kodu. Jeżeli macie podobnie, możemy przejść do kolejnej części.

Podstawowe formatowanie w CSS3

W podstawowej sekcji dodamy ukrywanie i pojawianie się danych poziomów oraz odnośniki główne ułożymy horyzontalnie.

#mainmenu, #mainmenu ul {list-style: none; margin: 0; padding: 0;}
#mainmenu ul {width: 160px;}
#mainmenu ul li {clear: both;}
#mainmenu > li {float: left; margin-right: 10px; position: relative;}
#mainmenu > li li {position: relative;}
#mainmenu > li ul {position: absolute; left: 0;}
#mainmenu > li ul li ul {position: absolute; left: 160px; top: 0px;}
ul ul {display: none;}
ul li:hover > ul {display: block;}

Dzięki powyższemu zabiegowi każdy kolejny poziom, jaki dołozymy do naszej struktury menu, będzie ukryty dopóki, doputy nie najedziemy kursorem na jego „rodzica„, czyli element nadrzędny <li> (a w nim <a>). Na tę chwilę uzuskaliśmy następujący efekt:

Upiększamy menu – formatowanie rozszerzone

Jako, że nasz schemat menu już działa, nadszedł czas na dostosowanie go do ciekawszych standardów wizualnych. Przecież nikt nie chce mieć na witrynie surowego zbioru linków. Najpierw sformatujemy wygląd linków osobno na poziomie pierwszym jak i na pozostałych poziomach.

/*POZIOM 1*/
#mainmenu {margin: 50px 50px; font-family: calibri; tahoma, arial;}
#mainmenu > li > a {padding: 8px; border-radius: 3px; text-align: center; text-decoration: none; color: #84c5f7;}
#mainmenu > li:hover > a {background: #eee; color: #0090ff;}

/*POZIOMY NIŻSZE*/
#mainmenu ul {font-size: 12px; border-radius: 3px; background: #eee;}
#mainmenu ul li > a {color: #999; display: block; padding: 5px; border-radius: 3px; text-decoration: none;}
#mainmenu ul li:hover > a {color: #eee; background: #aaa;}

Nasz panel nawigacyjny ogląda się już duzo przyjemniej.

Nie widzimy jednak strzałek, informujących nas o tym, czy dany rodzic posiada jeszcze niższe poziomy. W tym celu wykorzystamy również możliwości CSS.

.arrow {display: inline-block; margin: 0 5px 0; height: 0; vertical-align: top; content: ""; position: absolute;}
#mainmenu > li > a > .arrow {top: 17px; right: 0; margin-right: -8px; border-top: 3px solid #333; border-right: 3px solid transparent; border-left: 3px solid transparent;}
ul ul .arrow {top: 10px; right: 0; border-top: 3px solid transparent; border-right: 3px solid transparent; border-left: 3px solid #333; border-bottom: 3px solid transparent;}

A oto efekt, który udało nam się uzyskać.

Podsumowanie tematu

Menu, które stworzyliśmy możemy rozbudowywać o kolejne poziomy. Uzyte przez nas formatowanie zapewni ku temu odpowiednią strukturę. Mam nadzieję, że dzisiejszym wpisem wyjaśniłem co niektórym zasadę budowania nawigacji w stylu „multilevel„.

Możesz podejrzeć przykład on-line lub pobrać menu na swój komputer:

Zobacz DEMO Pobierz plik źródłowy

Grafika z zajawki: freedigitalphotos.net

komentarze 22

  • Awatar
    Kacper Donat

    17 marca 2013 19:46

    Ja bym proponował jeszcze użyć płynnych przejść dla lepszego efektu :)

    Odpowiedz
    • Awatar
      Michał Kortas

      18 marca 2013 09:31

      Chodziło mi o jak największe uproszczenie kodu, aby Ci początkujący nie musieli gubić się pośród kolejnych linii. Dla bardziej doświadczonego webmastera dodanie do tego płynnych przejść nie powinno być problemem. Nie mniej jednak, w razie czego, zapraszam na nasze forum webmasterskie.

      Odpowiedz
  • Awatar
    Guest

    17 marca 2013 23:43

    No to już twoja własna koncepcja, którą możesz umieścić u siebie :) Tutaj mamy tylko super przygotowany szablon, dzięki :P

    Odpowiedz
  • Awatar
    Kacper

    19 marca 2013 00:01

    Nie wiem czy to działanie zamierzone czy nie ale ostatnio na webroad nie mogę otwierać stron w nowych kartach przez kliknięcie rolką myszki.

    Odpowiedz
    • Awatar
      Michał Kortas

      19 marca 2013 09:36

      Hmmm. Jaka przeglądarka/system? U mnie nie ma problemów, więc to pewnie pojedynczy przypadek (Win7/Chrome/FF/Opera/IE9).

      Odpowiedz
      • Awatar
        ziomeq

        19 marca 2013 10:12

        Mam to samo, WIn7, Firefox 20 beta

        Odpowiedz
      • Awatar
        Michał Kortas

        19 marca 2013 10:19

        Ok, widzę, że jednak w Firefox są problemy. Dziękuję za zgłoszenie.

        Odpowiedz
      • Awatar
        Stefan

        19 marca 2013 10:15

        u mnie to samo – FF

        Odpowiedz
  • Awatar
    Guest

    24 marca 2013 20:26

    i do zrobienia strzałki? Ten tag jest przestarzały i w ogóle nie służy do tego celu. Powinien się tam znaleźć div lub span.

    Odpowiedz
  • Awatar
    Arek

    27 marca 2013 23:28

    O ile dobrze zauważyłem to wydaje mi się, że element powinien znajdować się wewnątrz elementu np. Informacje a nie na zwewnątrz Informacje przy tym formatowaniu CSS. Bynajmniej w moim przypadku umieszczenie wewnątrz spowodowało, że strzałeczki się pokazały. Po za tym to bardzo ciekawy i praktyczny przykład menu. Dziękuję ;)

    Odpowiedz
    • Awatar
      feamoignargfaionakfj9ajfopamjv

      28 marca 2013 09:12

      Bynajmniej != przynajmniej ;)

      Odpowiedz
  • Awatar
    Piotr

    25 kwietnia 2013 15:01

    Witam,
    a u mnie pojawił się problem że po rozwinieciu menu tworzy się taki odstep z lewej strony szerokosci 40px (skopiowalem stad) jak to usunac? ten odstep z lewej strony?

    Odpowiedz
    • Awatar
      Piotr

      25 kwietnia 2013 15:04

      Ok, juz działa, nie skopiowala sie pierwsza linijka :)

      Odpowiedz
  • Awatar
    Smok

    7 maja 2013 18:56

    Witam.

    #mainmenu > li {float: left; margin-right: 10px; position: relative;}

    Co oznacza w powyższym fragmencie znak „>” pomiędzy „#mainmenu” a „li”?
    Szukam w google’ach, ale nie mogę znaleźć.

    Pozdrawiam

    Odpowiedz
    • Awatar
      Michał Załęcki

      7 maja 2013 19:45

      Dokładnie to „>” oznacza element, który występuje dokładnie po #mainmenu. Zrozumiesz na przykładzie: http://cdpn.io/DKgyq

      Odpowiedz
      • Awatar
        Mr.Mr

        7 maja 2013 22:13

        Jednak nie mylić z „+”. „>” nazywany jest selektorem dziecka i takie określenie jest chyba najbardziej wyraziste.

        Odpowiedz
    • Awatar
      Michał Kortas

      7 maja 2013 20:49

      Dokładnie tak, jak wspomniał @michal_zalecki:disqus. To tak zwany selektor. Więcej o nich możesz przeczytać na stronie znanego kursu HTML. Pozdrawiam!

      Odpowiedz
  • Awatar
    Ursmar

    2 listopada 2013 13:34

    Witam,
    Mam takie pytanko:
    Jak, gdzie dodawać tworzyć takie (czy jakieś (jakkolwiek) inaczej sformatowane menu), aby nie powielać go/ich na każdej podstronie, do której odsyłają poszczególne poziomy menu??

    Odpowiedz
    • Awatar
      chudym

      7 listopada 2013 23:14

      jedynie php, poszukaj dokładniej w internecie a na pewno znajdziesz ;-)

      Odpowiedz
      • Awatar
        Ursmar

        8 listopada 2013 03:37

        Dzięki za odpowiedź… tak wstępnie już trochę szukałem i natknąłem się właśnie na takie rozwiązanie z zastosowaniem php. Wygląda to nawet jak dla mnie bardzo, bardzo początkującego w tym temacie prosto i przejrzyście..
        Ale słyszałem też, że można to zrobić przy pomocy znacznika – iframe – ?
        Co powiesz o taki rozwiązaniu… ja się niestety na tym nie znam.. a chciałbym od bardziej doświadczonych otrzymać opinię czy warto? korzystać z tego sposobu..?
        Czy tak jak już wcześniej pisałeś jedynie php? ;)

        Odpowiedz
      • Awatar
        Mr.Mr

        8 listopada 2013 10:12

        Żadnych iframe’ów ;-)

        Odpowiedz
  • Awatar
    Marcin

    11 stycznia 2014 16:29

    Mam następujący problem z tym menu: przy trzecim poziomie menu jest przesunięte i nie da się na niego najechać myszą (znika). Czy może mi ktoś pomóc z tym? Sprawdzałem na różnych przeglądarkach, wklejałem „czysty” kod menu z tej strony i to samo. Moja strona jest w cakePHP i myślę, że to może być problemem, niestety nie wiem jak go rozwiązać.
    Screen jak to wygląda:
    http://voila.pl/index.php?f=1777489

    Odpowiedz

Zostaw odpowiedź