Dwupoziomowe rozwijane menu CSS

W poprzedniej części kursu CSS utworzyliśmy rozwijane poziome menu CSS, natomiast w tej części kursu CSS zajmiemy się jego rozbudową.

Naszym celem będzie utworzenie następującego poziomego menu CSS, które będzie miało dwa rozwijane poziomy:

Do kodu HTML, jaki poznaliśmy w poprzedniej części kursu CSS, musimy dodać kolejną listę HTML (tym razem tą listą będzie lista ol), dzięki czemu będziemy mogli utworzyć kolejny poziom rozwijanego menu, tam gdzie będziemy chcieli, czyli w elemencie li, który należy do pierwszego poziomu naszego rozwijanego menu.

Ponadto do głównego elementu ol dodamy atrybut id o przykładowej wartości menu, dzięki czemu łatwiej nam będzie tworzyć odpowiednie selektory, ponieważ dany selektor będzie odwoływał się do poszczególnych elementów umieszczonych w naszym menu, a nie do wszystkich ewentualnych elementów ol, które miałyby pojawić się na naszej stronie.

Cała omówiona operacja została przedstawiona w kodzie HTML, który znajduje się poniżej:

<body>

  <ol id="menu">
    <li><a href="#">dział - 1</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
            <li><a href="#">dodany - 6</a></li>
          </ol>
        </li>

        <li><a href="#">link - 3</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
          </ol>
        </li>

        <li><a href="#">link - 4</a></li>
        <li><a href="#">link - 5</a></li>
      </ul>
    </li>

    <li><a href="#">dział - 2</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
          </ol>
        </li>

        <li><a href="#">link - 3</a></li>
      </ul>
    </li>

    <li><a href="#">dział - 3</a></li>

    <li><a href="#">dział - 4</a>
      <ul>
        <li><a href="#">link - 1</a></li>
        <li><a href="#">link - 2</a></li>
        <li><a href="#">link - 3</a></li>
        <li><a href="#">link - 4</a></li>
      </ul>
    </li>
  </ol>

</body>

Rezultat:

W poprzedniej części kursu CSS tworzyliśmy selektory CSS za pomocą selektora dziecka i nadal konsekwentnie będziemy trzymać się tego zapisu.

Tworzymy selektor #menu > li > ul > li > ol, który będzie odwoływał się do każdego elementu ol, który został umieszczony kolejno w elementach li, ul, li oraz w elemencie z atrybutem id o wartości menu. Elementem ol wskazanym przez wspomniany selektor jest ten element ol, który dodaliśmy do kodu HTML, który z kolei został przedstawiony przeze mnie parę linijek wyżej.

Każdy taki element ol w naszym układzie elementów HTML będzie głównym elementem stanowiącym drugi rozwijany poziom w naszym menu. Za pomocą właściwości width:150%; sprawimy że będzie on o półtora raza szerszy od swojego elementu rodzica, czyli elementu li.

Aby odwołać się do każdego elementu li, który znajdzie się w drugim poziomie rozwijanego menu, tworzymy następujący selektor #menu > li > ul > li > ol > li. Do tych elementów li dodamy jakiś przykładowy kolor tła, np. jeden z odcieni koloru szarego, czyli właściwość background-color:#CCC;

Wszystkie omówione właściwości CSS oraz selektory, zostały przedstawione w kodzie HTML, który znajduje się poniżej:

#menu > li > ul > li > ol {
  width:150%;
}

#menu > li > ul > li > ol > li {
  background-color:#CCC;
}

Rezultat:

Czas sprawić, aby część, która stanowi drugi poziom rozwijanego menu, układała się w odpowiedni sposób, obok elementu a. Inaczej mówiąc, przyszedł czas "pobawić się" właściwością position oraz jej wartościami relative oraz absolute.

Dla przypomnienia:

  • elementy HTML pozycjonowane absolutnie (czyli te elementy, do których dodamy właściwość position wraz z wartością absolute) możemy kontrolować za pomocą właściwości top, right, bottom lub left, czyli możemy określać pozycję takiego elementu i będzie ona liczona względem krawędzi okna przeglądarki internetowej lub względem pierwszego elementu przodka (danego elementu pozycjonowanego absolutnie), który nie będzie posiadał w sobie domyślnej pozycji statycznej
  • element posiadający w sobie właściwość position wraz z wartością absolute nie przesuwa swoim rozmiarem, marginesami, obramowaniem itd. innych sąsiednich elementów HTML oraz nie pozostawia po sobie żadnej pustej przestrzeni, w miejscu swojej pozycji początkowej

Jeżeli ktoś zrozumiał zasady, które zostały opisane powyżej, to będzie wiedział, że nasz drugi poziom rozwijanego menu będzie musiał być pozycjonowany absolutnie względem swojego elementu rodzica, czyli element ol będzie musiał posiadać w sobie właściwość position:absolute; a jego rodzic, czyli element li, właściwość position:relative; dzięki czemu oba elementy będą na siebie oddziaływać w odpowiedni sposób, czyli pozycja elementu ol będzie liczona względem elementu li.

Gdy do takiego elementu ol dodamy, np. właściwość left, która odsunie go (od lewej krawędzi elementu li) o daną wartość, to będziemy mogli uzyskać efekt, tak jakby element ol układał się obok elementu a, lecz tak naprawdę będzie on odsunięty od lewej krawędzi swojego elementu rodzica.

Wartością, którą należy podać razem z właściwością left, jest wartość 100%, dzięki czemu element stanowiący drugi rozwijany poziom menu, odsunie się o 100% szerokości swojego elementu rodzica i zostanie ustawiony obok niego, dokładnie co do piksela.

Wszystkie opisane właściwości CSS zostały dodane do naszych reguł CSS:

#menu > li > ul > li {
  position:relative;
  background-color:#EEE;
}

#menu > li > ul > li > ol {
  position:absolute;
  left:100%;
  width:150%;
}

Selektor #menu > li > ul > li odwołuje się do elementu li, który jest rodzicem elementu ol, do którego z kolei odwołuje się selektor #menu > li > ul > li > ol.

Rezultat:

Czas sprawić, aby druga rozwijana część naszego menu CSS stała się niewidoczna. Z poprzedniej części kursu CSS wiemy, że aby uzyskać taki efekt możemy dodać do naszego elementu ol właściwość display:none;

Natomiast jeżeli chcemy, aby nasz element ol ponownie stał się widoczny, w momencie gdy najedziemy kursorem myszki na jego rodzica, czyli na element li, to musimy skorzystać z selektora :hover oraz właściwości display:block;.

Cały poprawny zapis został przedstawiony w kodzie znajdującym się poniżej:

#menu > li > ul > li > ol {
  display:none;
  position:absolute;
  left:100%;
  width:150%;
}

#menu > li > ul > li:hover > ol {
  display:block;
}

Rezultat:

Po sprawdzeniu w jaki sposób wyświetla się drugi poziom naszego rozwijanego menu, możemy dojść do wniosku, że nie wszystko jest ok, ponieważ nie ustawia się on idealnie obok prawej strony elementu a. Dlatego musimy dodać do naszego elementu ol właściwość margin-top:-2em; dzięki czemu cały drugi rozwijany blok zostanie przesunięty w górę o wartość 2em, którą użyliśmy w poprzedniej części kursu CSS, do ustalenia wysokości wierszy w naszym menu CSS, dzięki czemu element ol przesunie się w górę o wartość dokładnie odpowiadającą wartości wysokości jednego wiersza.

#menu > li > ul > li > ol {
  display:none;
  position:absolute;
  left:100%;
  margin-top:-2em;
  width:150%;
}

Rezultat:

Czas zająć się wyglądem elementów a, które znajdują się w drugim poziomie rozwijanego menu CSS. Dodamy do nich białe obramowanie po lewej i górnej stronie danego elementu, dzięki wartości 1px solid #FFF oraz właściwością border-left oraz border-top.

Za pomocą selektora #menu > li > ul > li > ol > li > a:hover oraz właściwości color:#09C; sprawimy że kolor tekstu w danym elemencie a, zmieni się, gdy najedziemy na taki element kursorem myszki.

Dodatkowo sprawimy, za pomocą właściwości border-radius:6px; oraz selektora #menu li, #menu a, że wszystkie elementy li oraz a, w naszym menu, będą posiadały zaokrąglone rogi.

#menu > li > ul > li > ol > a {
  border-top:1px solid #FFF;
  border-left:1px solid #FFF;
}

#menu > li > ul > li > ol > a:hover {
  color:#09C;
}

#menu li, #menu a {
  border-radius:6px;
}

Rezultat:

Jedyne co nam pozostało to dodać do naszego menu CSS, strzałki, które będą podpowiadać nam czy dana część jest rozwijana, czy też nie. Wykorzystamy do tego jakąś prostą grafikę.

  • strzałka w dół
  • strzałka w prawo

Do elementów li, w naszym kodzie HTML, które zawierają w sobie pierwszy lub drugi poziom rozwijanego menu, musimy dodać atrybut class o przykładowej wartości dol (dla elementów li, które posiadają rozwijaną część menu, po dolnej stronie) oraz prawo (dla elementów li, które posiadają rozwijaną część menu, po prawej stronie), dzięki czemu będziemy mogli utworzyć, dla wspomnianych elementów li, odpowiednie reguły CSS, które będą dodawać, do danych elementów li, tło obrazkowe w postaci odpowiedniej strzałki.

Cała operacja została przedstawiona w kodzie HTML, który znajduje się poniżej:

<body>

  <ol id="menu">
    <li class="dol"><a href="#">dział - 1</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li class="prawo"><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
            <li><a href="#">dodany - 6</a></li>
          </ol>
        </li>

        <li class="prawo"><a href="#">link - 3</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
          </ol>
        </li>

        <li><a href="#">link - 4</a></li>
        <li><a href="#">link - 5</a></li>
      </ul>
    </li>

    <li class="dol"><a href="#">dział - 2</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li class="prawo"><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
          </ol>
        </li>

        <li><a href="#">link - 3</a></li>
      </ul>
    </li>

    <li><a href="#">dział - 3</a></li>

    <li class="dol"><a href="#">dział - 4</a>
      <ul>
        <li><a href="#">link - 1</a></li>
        <li><a href="#">link - 2</a></li>
        <li><a href="#">link - 3</a></li>
        <li><a href="#">link - 4</a></li>
      </ul>
    </li>
  </ol>

</body>

Teraz wystarczy, że utworzymy następujące reguły CSS:

#menu .dol {
  background-image:url('http://webkod.pl/images/down.png');
  background-repeat:no-repeat;
  background-position:98% center;
}

#menu .prawo {
  background-image:url('http://webkod.pl/images/right.png');
  background-repeat:no-repeat;
  background-position:right center;
}

Właściwość background-image odpowiada za dodanie tła obrazkowego do danego elementu HTML. Właściwość background-repeat odpowiada za sposób powtarzania danego tła obrazkowego. Właściwość background-position odpowiada za określenie pozycji tła obrazkowego w danym elemencie HTML.

Nasze menu CSS wygląda jak to, które zostało zaprezentowane na początku tej części kursu CSS.

Kod całego dokumentu HTML, wraz z komentarzami, został przedstawiony poniżej:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Darmowy Kurs CSS</title>

    <style>
      /* ------------------------CZĘŚĆ-GÓRNA-MENU------------------------ */

      /* usunięcie domyślnych właściwości CSS z elementów - ol - oraz - ul */
      #menu, #menu ul, #menu ol {
        list-style-type:none;
        padding:0;
        margin:0;
      }

      /* wygląd głównego elementu - ol */
      #menu {
        background-color:#FFF;
        font-size:18px;
        height:2em;
        line-height:2em;
        text-align:center;
      }

      /* wygląd wszystkich elementów - a - znajdujących się w elemencie - ol */
      #menu a {
        display:block;
        text-decoration:none;
        color:#000;
        padding:0 5px;
      }

      /* wygląd elementów - li - wszystkich dzieci elementu - ol */
      #menu > li {
        float:left;
        width:150px;
        margin-left:1px;
        background-color:#FDD700;
        height:2em;
      }

      /* wygląd elementu - li - pierwszego dziecka elementu - ol */
      #menu > li:first-child {
        margin-left:0;
      }

      /* wygląd elementów - li - wszystkich dzieci elementu - ol - po najechaniu kursorem myszki na element - li */
      #menu > li:hover {
        background-color:#EEE;
      }

      /* wygląd elementu - a - dziecka elementu - li - będącego dzieckiem elementu - ol - po najechaniu kursorem myszki na element - li */
      #menu > li:hover > a {
        color:#09C;
      }

      /* wygląd elementu - ul - dziecka elementu - li - będącego dzieckiem elementu - ol - po najechaniu kursorem myszki na element - li */
      #menu > li:hover > ul {
        display:block;
      }

      /* ------------------------CZĘŚĆ-ROZWIJANA-MENU-POZIOM-1----------------------- */

      /* wygląd głównych rozwijanych elementów - ul */
      #menu > li > ul {
        display:none;
      }

      /* wygląd elementu - li - w części rozwijanej */
      #menu > li > ul > li {
        position:relative;
        background-color:#EEE;
      }

      /* wygląd elementu - a - w części rozwijanej */
      #menu > li > ul > li > a {
        border-top:1px solid #FFF;
      }

      /* wygląd elementu - li - w części rozwijanej, po najechaniu kursorem myszki na dany element - li */
      #menu > li > ul > li:hover {
        background-color:#DDD;
      }

      /* wygląd elementu - a - w części rozwijanej, po najechaniu kursorem myszki na element - li */
      #menu > li > ul > li:hover > a {
        color:#09C;
      }

      /* ------------------------CZĘŚĆ-ROZWIJANA-MENU-POZIOM-2----------------------- */

      /* wygląd głównego elementu - ol - w drugiej części rozwijanej */
      #menu > li > ul > li > ol {
        display:none;
        width:150%;
        position:absolute;
        left:100%;
        margin-top:-2em;
      }

      /* wygląd głównego elementu - ol - w drugiej części rozwijanej, po najechaniu kursorem myszki na jego rodzica - li */
      #menu > li > ul > li:hover > ol {
        display:block;
      }

      /* wygląd elementów - li - w drugiej części rozwijanej */
      #menu > li > ul > li > ol > li {
        background-color:#CCC;
      }

      /* wygląd elementów - a - w drugiej części rozwijanej */
      #menu > li > ul > li > ol > li > a {
        border-top:1px solid #FFF;
        border-left:1px solid #FFF;
      }

      /* wygląd elementu - a - w drugiej części rozwijanej, po najechaniu kursorem myszki */
      #menu > li > ul > li > ol > li > a:hover {
        color:#09C;
      }

      /* ------------------------WSPÓLNE----------------------- */

      /* zaokrąglone rogi wszystkich elementów - li - oraz - a */
      #menu li, ol a {
        border-radius:6px;
      }

      /* strzałka w prawo */
      #menu .dol {
        background-image:url('http://webkod.pl/images/down.png');
        background-repeat:no-repeat;
        background-position:98% center;
      }

      /* strzałka w dół */
      #menu .prawo {
        background-image:url('http://webkod.pl/images/right.png');
        background-repeat:no-repeat;
        background-position:98% center;
      }
    </style>

  </head>

<body>

  <ol id="menu">
    <li class="dol"><a href="#">dział - 1</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li class="prawo"><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
            <li><a href="#">dodany - 6</a></li>
          </ol>
        </li>

        <li class="prawo"><a href="#">link - 3</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
          </ol>
        </li>

        <li><a href="#">link - 4</a></li>
        <li><a href="#">link - 5</a></li>
      </ul>
    </li>

    <li class="dol"><a href="#">dział - 2</a>
      <ul>
        <li><a href="#">link - 1</a></li>

        <li class="prawo"><a href="#">link - 2</a>
          <ol>
            <li><a href="#">dodany - 1</a></li>
            <li><a href="#">dodany - 2</a></li>
            <li><a href="#">dodany - 3</a></li>
            <li><a href="#">dodany - 4</a></li>
            <li><a href="#">dodany - 5</a></li>
          </ol>
        </li>

        <li><a href="#">link - 3</a></li>
      </ul>
    </li>

    <li><a href="#">dział - 3</a></li>

    <li class="dol"><a href="#">dział - 4</a>
      <ul>
        <li><a href="#">link - 1</a></li>
        <li><a href="#">link - 2</a></li>
        <li><a href="#">link - 3</a></li>
        <li><a href="#">link - 4</a></li>
      </ul>
    </li>
  </ol>

</body>
</html>

W następnej części kursu CSS dowiemy się czym są duszki CSS.