Efekt animacji wysuwania rozwijanego menu w CSS 3
W jednym z moich poprzednich artykułów opisałem krok po kroku jak przy pomocy HTML 5 oraz CSS 3 zrobić trzy poziomowe, rozwijane menu na stronie internetowej. Już napisany kod działa bardzo dobrze ale nie wykorzystuje wszystkich dostępnych możliwości jakie daje CSS 3. Warto trochę to uatrakcyjnić dodając efekt animowanego wysuwania dodatkowych opcji po najechaniu myszką na jakiś element z menu.
Kod z poprzedniego wpisu, na którym będziemy pracować:
HTML
<ul> <li><a href="#">Strona główna</a></li> <li><a href="#">Newsy</a> <ul> <li><a href="#">Internet</a></li> <li><a href="#">Sprzęt</a> <ul> <li><a href="#">Komputery</a></li> <li><a href="#">Tablety</a></li> <li><a href="#">Telefony</a></li> </ul> </li> <li><a href="#">Oprogramowanie</a></li> <li><a href="#">Wydarzenia</a></li> </ul> </li> <li><a href="#">Programowanie</a> <ul> <li><a href="#">C++</a></li> <li><a href="#">C#</a></li> <li><a href="#">Java</a></li> </ul> </li> <li><a href="#">Poradniki</a> <ul> <li><a href="#">CMS</a> <ul> <li><a href="#">Drupal</a></li> <li><a href="#">Joomla</a></li> <li><a href="#">WordPress</a></li> </ul> </li> <li><a href="#">HTML 5</a></li> <li><a href="#">CSS 3</a></li> </ul> </li> <li><a href="#">Kontakt</a></li> </ul>
CSS
ul { list-style: none; float: left; } ul > li { margin: 0; padding: 0; float: left; position: relative; height: 30px; } ul > li > a { padding: 10px; color: #444; text-decoration: none; } ul > li > a:hover, ul > li:hover > a { color: #de5f44; text-decoration: underline; } ul > li ul { padding: 0; position: absolute; display: none; left: 0px; top: 30px; width: 200px; text-align: left; background-color: #fcfcfc; border: 1px solid #ccc; } ul li:hover > ul { display: block; } ul > li ul ul { left: 200px; top: -1px; } ul > li ul li { margin: 0; padding: 0; position: relative; float: none; height: auto; } ul > li ul li a { padding: 10px 20px; color: #505050; text-decoration: none; display: block; } ul > li ul li a:hover, ul > li ul li:hover > a { text-decoration: none; color: #fff; background-color: #f26c4f; }
Oczywiście nie będziemy modyfikować wszystkiego, skupimy się tylko na małym fragmencie:
ul > li ul { padding: 0; position: absolute; display: none; left: 0px; top: 30px; width: 200px; text-align: left; background-color: #fcfcfc; border: 1px solid #ccc; } ul li:hover > ul { display: block; }
Jak nie trudno się domyślić, mamy tutaj style odpowiedzialne za ukrywanie bądź pokazywanie dodatkowych opcji w menu w zależności od tego na którą pozycję najedziemy myszką.
Na początku zamienimy style display: none;
oraz display: block;
na visibility: hidden;
i visibility: visible;
. Musimy tak zrobić ponieważ styl display: none;
uniemożliwia działanie innych stylów, a co za tym idzie animacja którą chcemy uzyskać nie będzie po prostu funkcjonowała tak jak tego oczekujemy. Co prawda na upartego nie musimy dopisywać w zamian display
stylu visibility
, ale należy pamiętać o starszych przeglądarkach, które mogą nie obsłużyć reguł CSS 3, w takim wypadku nasze menu będzie po prostu działać jak dotychczas.
Za efekt naszej animacji będzie odpowiedzialny styl transform: scaleY(arg);
. Funkcja scaleY()
jako argument (arg
) przyjmuje liczbę od 0
do 1
gdzie 0
oznacza całkowite zmniejszenie elementu, a 1
pełną jego wysokość wraz z przypisanym marginesem, obramowaniem itd.. Warto tutaj zwrócić uwagę na to, że zmniejszanie i powiększanie elementu przy pomocy tego stylu domyślnie działa względem punktu ustawionego na środku elementu html. My w naszym przykładzie będziemy musieli to zmienić za pomocą transform-origin
przesuwając ten punkt na środek górnej krawędzi (50% 0
): transform-origin: 50% 0;
.
Na samym końcu pozostaje nam tylko wydłużyć wykonywanie powyższych stylów za pomocą transition
: transition: 200ms
; (jak widać ustawiliśmy czas na 200 milisekund co spowoduje efekt animacji).
Nasz przerobiony fragment kodu:
ul > li ul { padding: 0; position: absolute; visibility: hidden; left: 0px; top: 30px; width: 200px; text-align: left; background-color: #fcfcfc; border: 1px solid #ccc; transform: scaleY(0); /* zwijamy cały element */ -webkit-transform: scaleY(0); transform-origin: 50% 0; /* ustawiamy punkt zwijania względem środka górnej krawędzi */ -webkit-transform-origin: 50% 0; transition: 200ms; /* wydłużamy wykonywanie stylów */ } ul li:hover > ul { visibility: visible; transform: scaleY(1); /* rozwijamy element do całej jego wysokości */ -webkit-transform: scaleY(1); }
Cały kod CSS (kod HTML pozostaje bez zmian):
ul { list-style: none; float: left; } ul > li { margin: 0; padding: 0; float: left; position: relative; height: 30px; } ul > li > a { padding: 10px; color: #444; text-decoration: none; } ul > li > a:hover, ul > li:hover > a { color: #de5f44; text-decoration: underline; } ul > li ul { padding: 0; position: absolute; visibility: hidden; left: 0px; top: 30px; width: 200px; text-align: left; background-color: #fcfcfc; border: 1px solid #ccc; transform: scaleY(0); /* zwijamy cały element */ -webkit-transform: scaleY(0); transform-origin: 50% 0; /* ustawiamy punkt zwijania względem środka górnej krawędzi */ -webkit-transform-origin: 50% 0; transition: 200ms; /* wydłużamy wykonywanie stylów */ } ul li:hover > ul { visibility: visible; transform: scaleY(1); /* rozwijamy element do całej jego wysokości */ -webkit-transform: scaleY(1); } ul > li ul ul { left: 200px; top: -1px; } ul > li ul li { margin: 0; padding: 0; position: relative; float: none; height: auto; } ul > li ul li a { padding: 10px 20px; color: #505050; text-decoration: none; display: block; } ul > li ul li a:hover, ul > li ul li:hover > a { text-decoration: none; color: #fff; background-color: #f26c4f; }
Demo
>> Zobacz demo – rozwijane menu w HTML 5 i CSS 3 z efektem animacji <<
Bardzo fajnie wszystko ładnie opisane. Brawo!
Fajnie, że się przydało :)
Panie Łukaszu a jak to menu w css wyjustować na środek a nie do lewej ? Słabeusz jestem i próbowanie po omacku zupełnie mi nie wychodzi :(
Hej bodo,
Tekst w menu jest wyjustowany do lewej (text-align: left). Możesz bardziej doprecyzować pytanie?
jakoś poradziłem sobie, chodziło mi centrowanie całego menu na środek strony o tak:
ul {
list-style: none;
width: 100%;
float: center;
margin: 0px auto;
display: flex;
align-items: center;
justify-content: center;
}