Autor publikacji
Virtual Patriot - Administrator

Animowanie rozwijanej części poziomego menu CSS

Data publikacji
Ostatnio edytowano

Nasze poziome menu CSS stało się bardziej zaawansowane, ponieważ dodaliśmy do niego części rozwijane. Czas na to, aby wspomniane menu CSS stało się jeszcze bardziej ciekawe, dlatego w tej części kursu CSS dowiemy się w jaki sposób sprawić, aby części rozwijane naszego menu CSS były animowane.

Końcowy efekt został zaprezentowany poniżej.

Aby móc zrozumieć tę część kursu CSS należy sobie przypomnieć informacje, które zostały zawarte w dziale pierwszym - Poznajemy właściwości efektu przejścia - transition CSS3 oraz Przekształcenie elementu HTML w przestrzeni 2D - transform CSS3.

W jednej z poprzednich części kursu CSS dowiedzieliśmy się o mechanizmie pokazywania i ukrywania rozwijanej części naszego menu CSS. Mechanizm ten działa w ten sposób, że gdy najedziemy kursorem myszki na obszar elementu li staje się widoczny jego element dziecko, czyli element ul, który tworzy część rozwijaną w danym menu CSS. Zmiana wyglądu elementu poprzez najechanie kursorem myszki na jego obszar jest możliwa, dzięki selektorowi :hover, o czym również mogliśmy dowiedzieć się z poprzednich części tego działu.

Na razie zapominamy o naszym menu CSS i jego częściach rozwijanych. Stworzymy animację, którą później dodamy do naszego menu CSS. Wspomnianą animację wykonamy na elemencie dziecku przykładowego elementu HTML. Przykładowo tworzymy następujący układ elementów HTML:

<div id="rodzic">
  element rodzic (tak samo jak element - li - w naszym menu)
  <div>element dziecko (tak samo jak element - ul - w naszym menu)</div>
</div>

Do przykładowego układu elementów HTML dodajemy następujące reguły CSS:

#rodzic {
  padding:15px;
  background-color:#FEC;
}

#rodzic > div {
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Nasz przykładowy układ elementów HTML nie zawiera w sobie niczego szczególnego. Widzimy w nim dwa elementy div umieszczone jeden w drugim, dla których zostały ustalone przykładowe właściwości CSS (kolor tła, marginesy, obramowanie). Tworzymy jeszcze jedną regułę CSS:

#rodzic:hover > div {
  background-color:#0FF;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Reguła CSS określona za pomocą selektora #rodzic:hover > div doda nowy kolor tła (background-color:#0FF;) do elementu dziecka typu div w momencie, gdy najedziemy kursorem myszki na jego element rodzic, który posiada atrybut id o wartości rodzic. Ta zmiana koloru tła odbywa się momentalnie, jednak możemy w dość łatwy sposób sprawić, aby zmiana koloru tła odbywała się nieco wolnej, dzięki czemu o danym tle elementu HTML będziemy mogli powiedzieć, że jego zmiana koloru jest animowana. Dodajemy właściwość transition-duration wraz z wartością 250ms do elementu HTML, dla którego chcemy, aby zmiana jego jakiejkolwiek właściwości CSS, która może być animowana, trwała 250ms, czyli jedną czwartą sekundy.

#rodzic > div {
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Od tej pory zmiana koloru tła elementu dziecka, gdy najedziemy kursorem myszki na jego element rodzic, trwa 250ms. Jest to przejście koloru czerwonego w kolor niebieski i na odwrót, gdy kursor myszki opuści obszar elementu rodzica wspomnianego elementu dziecka.

My chcemy, aby nasza animacja, gdy najedziemy kursorem myszki na element rodzic, pokazywała w jakiś sposób interesujący nas element HTML, gdy jest on niewidoczny. Pierwsze co może przyjść nam do głowy - Wykorzystajmy do tego celu właściwość height. Określmy zerową wysokość danego elementu, a następnie zmieńmy tą wartość wysokości w naszej animacji.

#rodzic > div {
  height:0;
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  height:100%;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Rozwiązanie na pewno jest logiczne, lecz nie działa tak jak należy.

Po pierwsze nie widzimy żadnej animacji, tylko momentalną zmianę wysokości interesującego nas elementu HTML. Dzieje się tak dlatego, że wartość właściwości height określona w procentach nie może być animowana, jeżeli nie określiliśmy wartości właściwości height dla elementu rodzica danego elementu HTML, który chcemy, aby był animowany. Określmy więc tą wartość i zobaczmy co się stanie.

#rodzic {
  height:100px;
  padding:15px;
  background-color:#FEC;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Rozwiązanie może i działa, lecz nie pasuje do naszego poziomego menu CSS i jego części rozwijanych, ponieważ każda taka część ma inną wartość wysokości niż jej element rodzic, a więc wartość height:100%; odpada.

Cofnijmy się o krok do tyłu i określmy wartość właściwości height w pikselach.

#rodzic > div {
  height:0;
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  height:50px;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Rozwiązanie może i dobre, lecz nie uniwersalne, ponieważ każda część rozwijana naszego menu CSS będzie miała różną wartość wysokości, więc obliczanie wartości wysokości dla każdej części osobno mija się z naszym celem, ponadto jak zdążyliśmy już zauważyć właściwość height:0; nie gwarantuje nam tego, że dany element HTML będzie miał zerową wysokość całkowitą (właściwość height:0; nie uwzględnia obramowania oraz marginesów zewnętrznych i wewnętrznych danego elementu HTML).

Efekt, do którego dążymy może nam ułatwić funkcja scaleY() właściwości transform. Funkcja scaleY() skaluje, czyli pomniejsza lub powiększa (w zależności jaką wartość podamy) dany element HTML względem jego wymiaru wysokości. Wartość scaleY(1) oznacza domyślny rozmiar wysokości danego elementu HTML (uwzględniając wszystkie właściwości CSS, obramowanie i marginesy również). Wartość scaleY(0) oznacza, że dany element HTML ma zerową wysokość. Zobaczmy jak będzie wyglądała nasza animacja, gdy wykonamy ją na właściwości transform oraz funkcji scaleY().

#rodzic > div {
  transform:scaleY(0);
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  transform:scaleY(1);
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Od tej pory nasz przykładowy element HTML posiada animację, która zmienia jego zerowy rozmiar wysokości (scaleY(0)) na jego domyślny rozmiar wysokości (scaleY(1)). Wspomniana animacja (skalowanie za pomocą funkcji scaleY()) odbywa się względem domyślnego punktu, który znajduje się na środku elementu HTML. Nasza animacja skaluje dany element HTML w górę i w dół względem wspomnianego punktu. Gdy przesuniemy ten punkt na środek górnej krawędzi elementu HTML, który ma być animowany, za pomocą właściwości transform-origin oraz wartości 50% 0, animacja zmieni wygląd na ten, do którego dążymy.

#rodzic > div {
  transform-origin:50% 0;
  transform:scaleY(0);
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  transform:scaleY(1);
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Od tej pory animacja skalowania rozmiaru wysokości interesującego nas elementu HTML odbywa się względem punktu, który znajduje się na na środku górnej krawędzi wspomnianego elementu HTML, dlatego jego rozmiar wysokości jest pokazywany od tego punktu w dół, a nie w obie strony (góra i dół), ponieważ górna krawędź elementu HTML stanowi jeden z początków rozmiaru jego wysokości (określa ona wysokość danego elementu w dół).

Udało się nam stworzyć animację, która pozwoli sprawić, aby części rozwijane naszego menu CSS stały się animowane, lecz należy pamiętać o jednej rzeczy. Nie wszystkie przeglądarki internetowe muszą interpretować właściwości transform oraz transition-duration, dlatego ukrywanie oraz pokazywanie elementu HTML za pomocą funkcji scaleY() nie może być jedynym mechanizmem w naszym układzie elementów HTML.

Jak wiemy nasze menu CSS posiada mechanizm pokazywania i ukrywania elementów HTML za pomocą właściwości display, jej wartości none oraz block. Mechanizm ten jest obsługiwany przez wszystkie przeglądarki internetowe. Spójrzmy co się stanie, gdy do naszych przykładowych elementów HTML dodamy wspomniany mechanizm oparty na właściwości display.

#rodzic > div {
  display:none;
  transform-origin:50% 0;
  transform:scaleY(0);
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  display:block;
  transform:scaleY(1);
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Rezultat może nas nieco rozczarować, ponieważ nasz układ elementów HTML stracił animację. Przyczyną jest właściwość display. Zanim wyjaśnimy sobie z jakiej przyczyny właściwość display "psuje" nam animację, spójrzmy jeszcze raz na naszą animację (opartą na funkcji scaleY()), gdy do elementów HTML nie jest dodana właściwość display wraz z wartością none oraz block.

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Jak możemy zauważyć w naszym przykładowym układzie elementów HTML, element dziecko na starcie posiada właściwość transform wraz z wartością scaleY(0) oznacza to, że rozmiar wysokości wspomnianego elementu HTML jest przeskalowany do wartości 0, JEDNAK w miejscu, w którym znajduje się wspomniany element powstaje pusta przestrzeń takich samych rozmiarów, jakie posiada wspomniany element HTML, gdy jego rozmiar wysokości nie jest przeskalowany za pomocą funkcji scaleY(0), dlatego przeglądarka internetowa wie do jakiej wartości ma wykonać animację opartą na funkcji scaleY(1).

Jak już zdążyliśmy zauważyć, gdy dodamy do naszego przykładowego układu elementów HTML mechanizm ukrywania oraz pokazywania oparty na właściwości display:none; oraz display:block; naszym oczom ukaże się następujący rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Od tej pory przeglądarka internetowa nie wie do jakiej wartości ma zostać wykonana animacja za pomocą właściwości scaleY(1), ponieważ właściwość display wraz z wartością none nie wyświetla danego elementu HTML (rozmiar pustej przestrzeni danego elementu również jest ukrywany), dlatego wspomniana animacja jest pomijana przez przeglądarkę internetową.

Jak wiemy nasze dotychczasowe menu CSS posiada mechanizm ukrywania oraz pokazywania oparty na właściwości display, która jest interpretowana przez wszystkie przeglądarki internetowe, natomiast animacja, którą chcemy dodać do naszego menu CSS jest oparta na właściwościach transition-duration oraz transform, które mogą być nieobsługiwane przez starsze wersje przeglądarek internetowych, dlatego nie możemy tak sobie usunąć mechanizm oparty na właściwości display z naszego menu CSS, ponieważ może doprowadzić to do sytuacji, że użytkownik, który odwiedzi naszą stronę internetową pierwsze co zobaczy to rozwinięty poziome menu, które nie może się zwinąć (brak właściwości display w regułach CSS, przeglądarka nie obsługuje właściwości transform oraz funkcji scaleY()).

Z powyższych akapitów możemy wywnioskować, że mamy sprzeczną sytuację, ponieważ nie możemy usunąć właściwości display (ze względu na starsze przeglądarki internetowe, które nie interpretują właściwości transform), jednak nieusunięcie jej spowoduje, że nasze menu CSS nie będzie posiadało efektu animacji, do którego dążymy (właściwość display wraz z wartością none wyklucza działanie funkcji scaleY()). Jednak my się nie poddajemy i szukamy naszego rozwiązania.

Na chwilę zapomnijmy o właściwości display (która jest lub była najczęściej wykorzystywana do ukrywania oraz pokazywania rozwijanych części menu CSS). W języku CSS istnieje inna właściwość CSS, za pomocą której możemy ukryć dany element HTML, jednak posiada ona jedną wadę, ponieważ w miejscu ukrycia danego elementu HTML pozostaje pusta przestrzeń takich samych rozmiarów jaką zajmowałby dany element HTML, gdyby nie był on ukryty (jednak wada ta w tym momencie stanie się dla nas zaletą). Mowa tu o właściwości visibility, jej wartości hidden oraz visible.

Zobaczmy jak będzie wyglądał nasz przykładowy układ elementów HTML, gdy dodamy do niego mechanizm ukrywania oraz pokazywania oparty na właściwości visibility.

#rodzic > div {
  visibility:hidden;
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
}

#rodzic:hover > div {
  visibility:visible;
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Od tej pory interesujący nas element HTML jest niewidoczny, jednak wciąż możemy zobaczyć pustą przestrzeń, która określa rozmiar wspomnianego elementu HTML. Gdy dodamy animację do naszego przykładowego układu elementu HTML uzyskamy szukany efekt (animację opartą na właściwości transition-duration oraz transform).

#rodzic > div {
  visibility:hidden;
  transform-origin:50% 0;
  transform:scaleY(0);
  margin-top:15px;
  padding:15px;
  border:3px solid #FFF;
  background-color:#F00;
  transition-duration:250ms;
}

#rodzic:hover > div {
  visibility:visible;
  transform:scaleY(1);
}

Rezultat:

element rodzic (tak samo jak element - li - w naszym menu)
element dziecko (tak samo jak element - ul - w naszym menu)

Jeżeli ktoś chciałby rozwiązać dany problem poprzez połączenie właściwości height oraz visibility to nie jest to możliwe, ponieważ mimo tego że przeglądarka internetowa wie jaką wartość rozmiaru wysokości zajmuje dany element HTML (na podstawie wspomnianej pustej przestrzeni) to właściwość height wraz z wartością procentową (np. 100%) jest obliczana na podstawie wysokości rodzica danego elementu HTML, a nie wysokości interesującego nas elementu HTML.

Na podstawie wszystkich informacji jakie zostały zaprezentowane w tej części kursu CSS możemy rozpocząć dodawanie odpowiednich właściwości CSS, które sprawią, że części rozwijane w naszym poziomym menu CSS będą animowane.

Na początek usuniemy dwa mechanizmy z naszego menu CSS. Jeden odpowiadający za ukrywanie oraz pokazywanie rozwijanych części menu CSS (właściwość display). Drugi odpowiadający za to, że rozwijane części naszego menu CSS wyświetlają się ponad innymi elementami CSS (właściwość position:absolute;), dzięki czemu wkrótce będziemy mogli coś zauważyć.

#menu > li > ul {
  width:100%;
  display:none; /* DO USUNIĘCIA */
  position:absolute; /* DO USUNIĘCIA TYMCZASOWEGO */
  z-index:1;
  margin:0;
  padding:0;
  list-style-type:none;
  background-color:#FFF;
}

#menu > li:hover > ul {
  display:block; /* DO USUNIĘCIA */
}

Rezultat:

Dodajemy do części rozwijanych (czyli elementów ul) właściwość visibility wraz z wartością hidden, dzięki czemu wspomniane elementy ul zostaną ukryte, a w ich miejscu obszaru szerokości oraz wysokości pozostanie pusta przestrzeń takich samych rozmiarów, jakie mają dane elementy ul, gdy nie są ukryte (łatwiej nam zauważyć wspomnianą przestrzeń ze względu na kolorowe tło elementu rodzica każdego elementu ul).

#menu > li > ul {
  width:100%;
  visibility:hidden;
  z-index:1;
  margin:0;
  padding:0;
  list-style-type:none;
  background-color:#FFF;
}

Rezultat:

Dodajemy właściwość visibility wraz z wartością visible do reguły CSS, która określa wygląd elementów ul, gdy najedziemy kursorem myszki na element rodzic li danego elementu ul, dzięki czemu został utworzony nowy mechanizm pokazywania oraz ukrywania części rozwijanych naszego menu CSS (jego elementów ul).

#menu > li:hover > ul {
  visibility:visible;
}

Rezultat:

Dodajemy właściwość transform wraz z wartością scaleY(0) do każdego elementu ul, dzięki czemu rozmiar wysokości każdego elementu ul zostanie przeskalowany do zera. Dodajemy również właściwość transform wraz z wartością scaleY(1) do reguły CSS, która odpowiada za wygląd elementu ul, gdy najedziemy kursorem myszki na element rodzic li wspomnianego elementu HTML, dzięki czemu rozmiar wysokości danego elementu ul zostanie przeskalowany do domyślnego rozmiaru. Gdy dodamy właściwość transition-duration wraz z wartością 250ms do reguły CSS, która odpowiada za wygląd elementu ul to zmiana jego wartości jakiekolwiek właściwości CSS, która może być animowana, będzie trwała 250ms (jedna czwarta sekundy).

#menu > li > ul {
  width:100%;
  visibility:hidden;
  transform:scaleY(0);
  transition:250ms;
  z-index:1;
  margin:0;
  padding:0;
  list-style-type:none;
  background-color:#FFF;
}

#menu > li:hover > ul {
  visibility:visible;
  transform:scaleY(1);
}

Rezultat:

Skalowanie rozmiaru wysokości części rozwijanych w naszym menu CSS odbywa się względem środka danego elementu ul, a nie jego górnej krawędzi, dlatego przesuwamy punkt odpowiadający za wygląd animacji tworzonych za pomocą właściwości transform na środek górnej krawędzi każdego elementu ul za pomocą właściwości transform-origin oraz wartości 50% 0.

#menu > li > ul {
  width:100%;
  visibility:hidden;
  transform:scaleY(0);
  transform-origin:50% 0;
  transition:250ms;
  z-index:1;
  margin:0;
  padding:0;
  list-style-type:none;
  background-color:#FFF;
}

Rezultat:

Jedyne co nam pozostało w tym momencie to ukryć pustą przestrzeń elementów ul oraz sprawić, aby były one wyświetlane ponad innymi elementami HTML. Oba wspomniane problemy rozwiązuje wcześniej poznana właściwość position wraz z wartością absolute, ponieważ gdy element HTML zawiera w swojej zawartości element wyświetlony w pozycji absolutnej (position:absolute;), element wyświetlony w pozycji absolutnej nie oddziałuje na granicę wysokości lub szerokości swojego rodzica (dlatego kolorowe tło elementów li nie będzie już widoczne, ponieważ obszar każdego elementu li zostanie wyrównany do obszaru wysokości oraz szerokości elementu a, jaki został umieszczony w danym elemencie li).

#menu > li > ul {
  width:100%;
  visibility:hidden;
  transform:scaleY(0);
  transform-origin:50% 0;
  transition:250ms;
  position:absolute;
  z-index:1;
  margin:0;
  padding:0;
  list-style-type:none;
  background-color:#FFF;
}

Rezultat:

Kod dokumentu HTML tej części kursu CSS został umieszczony poniżej.

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

    <style>
      /* ------------------------ POZIOME MENU CSS ------------------------ */
      /* wygląd elementu - ol */
      #menu {
        width:400px;
        margin:0 auto;
        padding:0;
        list-style-type:none;
        background-color:#FDF;
      }

      /* naprawa wysokości elementu - ol */
      #menu:after {
        content:'';
        display:block;
        clear:both;
      }

      /* wygląd elementów - li */
      #menu > li {
        float:left;
      }

      /* pierwszy element - li - elementu o identyfikatorze menu */
      #menu > li:first-child {
        background-color:red;
        width:30%;
      }

      /* drugi element - li - elementu o identyfikatorze menu */
      #menu > li:first-child + li {
        background-color:green;
        width:40%;
      }

      /* trzeci element - li - elementu o identyfikatorze menu */
      #menu > li:first-child + li + li {
        background-color:blue;
        width:30%;
      }

      /* wygląd elementów - a */
      #menu > li > a {
        display:block;
        padding:15px;
        text-decoration:none;
        text-align:center;
        color:#000;
        background-color:#DDD;
        box-shadow:0 0 0 1px #FFF inset;
        background-image:linear-gradient(#FFF 0%, #EEE 30%, #DDD 70%, #FFF 100%);
      }

      /* wygląd elementów - a - po najechaniu kursorem myszki na element - li */
      #menu > li:hover > a {
        color:#00F;
        background-color:#FFF;
        background-image:none;
      }

      /* -------------------- ROZWIJANA CZĘŚĆ MENU CSS -------------------- */
      /* wygląd elementów - li - rodzica każdej części rozwijanej menu CSS */
      #menu > li {
        position:relative;
      }

      /* wygląd elementów - ul */
      #menu > li > ul {
        width:100%;
        visibility:hidden;
        position:absolute;
        z-index:1;
        margin:0;
        padding:0;
        list-style-type:none;
        background-color:#FFF;
      }

      /* wygląd elementów - ul - po najechaniu kursorem myszki na element - li */
      #menu > li:hover > ul {
        visibility:visible;
      }

      /* wygląd elementów - li */
      #menu > li > ul > li {
        box-shadow:0 -4px 4px -4px #AAA;
      }

      /* wygląd pierwszego dziecka elementu typu - li */
      #menu > li > ul > li:first-child {
        box-shadow:none;
      }

      /* wygląd ostatniego dziecka elementu typu - li */
      #menu > li > ul > li:last-child {
        box-shadow:0 -4px 4px -4px #AAA, 0 4px 4px -4px #AAA;
      }

      /* wygląd elementów - a */
      #menu > li > ul > li > a {
        display:block;
        text-decoration:none;
        padding:15px;
        color:#000;
      }

      /* wygląd elementów - a - po najechaniu kursorem myszki na element - li */
      #menu > li > ul > li:hover > a {
        color:#00F; 
        background-color:#F0F0F0;
        background-image:linear-gradient(#FFF, #EEE, #FFF);
      }

      /* --------------- ANIMOWANIE ROZWIJANEJ CZĘŚCI MENU CSS --------------- */
      /* wygląd elementów - ul */
      #menu > li > ul {
        transform:scaleY(0);
        -webkit-transform:scaleY(0);
        transform-origin:50% 0;
        -webkit-transform-origin:50% 0;
        transition:250ms;
      }

      /* wygląd elementów - ul - po najechaniu kursorem myszki na element - li */
      #menu > li:hover > ul {
        transform:scaleY(1);
        -webkit-transform:scaleY(1);
      }
    </style>
  </head>

  <body>

    <ol id="menu">
      <li><a href="#">link - 1</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>
          <li><a href="#">link - 5</a></li>
          <li><a href="#">link - 6</a></li>
        </ul>
      </li>
      <li><a href="#">link - 2</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>
      <li><a href="#">link - 3</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>
          <li><a href="#">link - 5</a></li>
        </ul>
      </li>
    </ol>

  </body>
</html>