[CSS] Efektowne okrągłe menu rozwijane zbudowane za pomocą CSS
W oczekiwaniu na rozstrzygnięcia dzisiejszego wieczoru (polska drużyna, Legia Warszawa, gra mecz rewanżowy w Lidze Mistrzów) postanowiłem Ci przedstawić jeszcze jeden sposób na utworzenie rozwijanego menu na stronie za pomocą CSS. Co ciekawe, będzie ono symulowało efekt kliknięcia bez JS.
Okrągłe menu - kod HTML
1 2 3 4 5 6 7 8 | <a class="button" href="#">★</a> <ul class="menu"> <li class="item"><a href="#">✦</a></li> <li class="item"><a href="#">✿</a></li> <li class="item"><a href="#">✵</a></li> <li class="item"><a href="#">✪</a></li> <li class="item"><a href="#">☀</a></li> </ul> |
Utworzono dwa osobne elementy: przycisk i listę elementów. Są one od siebie niezależne i są one nałożone na siebie. Jako tekstu w menu użyto encji HTMLowych, które są zapisem technicznym symboli, takich jak różnego rodzaju gwiazdy lub kwiatki.
Dobrodziejstwa CSS3 - animacje i transformacje
Jedną z największych zalet najnowszej specyfikacji CSS są animacje i transformacje. Oczywiście, istnieje również mnóstwo innych zalet, między innymi nowy box-model czy też media queries.
W przypadku tego menu będzimy wykorzystywać animacje i transformacje, a także pobawimy się cieniami i wielokrotnymi tłami.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | .button, /* #1 */ .menu { position: absolute; top: 50%; left: 50%; font: 1.5em/1.13 Verdana, sans-serif; transition: .5s; } .button, .menu a { display: block; opacity: .56; background: #c9c9c9; color: #7a8092; text-align: center; text-decoration: none; text-shadow: 0 -1px #666; } .button:hover, .button:focus, .menu a:hover, .menu a:focus { opacity: 1; } .button:focus, .menu a:focus { outline: none; } .button { z-index: 2; margin: -.625em; width: 1.25em; height: 1.25em; border-radius: 50%; box-shadow: 0 0 3px 1px #fff; } .menu { /* #2 */ z-index: 1; margin: -5em; width: 10em; height: 10em; transform: scale(.001); list-style: none; opacity: 0; } .menu:before, .menu:after { /* #3 */ position: absolute; top: 34.3%; width: .5em; height: 14%; opacity: .56; background: #c9c9c9; content: ''; } .menu:before { left: 5.4%; border-radius: .25em 0 0 .25em; box-shadow: -1px 0 1px #666, inset 1px 0 1px #fff, inset -1px 0 1px #555, inset 0 1px 1px #fff, inset 0 -1px 1px #fff; transform: rotate(-75deg); } .menu:after { right: 5.4%; border-radius: 0 .25em .25em 0; box-shadow: 1px 0 1px #666, inset -1px 0 1px #fff, inset 1px 0 1px #555, inset 0 1px 1px #fff, inset 0 -1px 1px #fff; transform: rotate(75deg); } .button:focus + .menu { /* #4 */ transform: scale(1); opacity: 1; } .item { /* #5 */ overflow: hidden; position: absolute; width: 50%; height: 50%; transform-origin: 100% 100%; } .item:first-child { transform: rotate(-45deg) skewY(60deg); } /* #6 */ .item:nth-child(2) { transform: rotate(-15deg) skewY(60deg); } .item:nth-child(3) { transform: rotate(15deg) skewY(60deg); } .item:nth-child(4) { transform: rotate(45deg) skewY(60deg); } .item:last-child { transform: rotate(75deg) skewY(60deg); } .item:after { /* #7 */ position: absolute; top: 32%; left: 32%; width: 136%; height: 136%; border-radius: 50%; transform: skewY(-60deg); content: ''; } .item a { /* #8 */ width: 200%; height: 200%; border-radius: 50%; box-shadow: 0 0 3px #666, inset 0 0 4px #fff; transform: skewY(-60deg) rotate(-15deg); background: linear-gradient(75deg, transparent 50%, #555 50%, transparent 54%) no-repeat 36.5% 0, linear-gradient(-75deg, transparent 50%, #555 50%, transparent 54%) no-repeat 63.5% 0, radial-gradient(rgba(127,127,127,0) 49%, rgba(255,255,255,.7) 51%, #c9c9c9 52%); background-size: 15% 15%, 15% 15%, cover; line-height: 1.4; } .item:nth-child(3) a:after { /* #9 */ position: absolute; top: 13%; left: 50%; margin: -.25em; width: .5em; height: .5em; box-shadow: 2px 2px 2px #fff; transform: rotate(45deg); background: linear-gradient(-45deg, #c9c9c9 50%, transparent 50%); content: ''; } |
W przerwie meczu (jest remis 0-0 z Molde), kontynuuję dalsze opisywanie sposobu uzyskania efektu rozwijanego menu po okręgu.
W związku z tym, że ciekawych rozwiązań zastosowanych przy budowie tego menu jest dość sporo, to postanowiłem, że opiszę je kolejno w punktach.
Zastosowane rozwiązania:
Definiujemy te same style początkowe dla przycisku menu i samego menu, a także czas trwania efektu przejścia między wartościami własności;
W tym miejscu definiujemy sposób zachowania się menu. Własność transform o wartości scale(.001) pozwala na utworzenie efektu rozwijania się menu bezpośrednio spod przycisku aktywującego;
Pseudoelementy :before i :after służą do określania stylu zakończeń menu;
Taka kombinacja selektorów pozwala na symulowanie kliknięcia w element i rozwinięcie menu;
Określamy wymiary pojedynczego elementu w menu oraz jego stopień transformacji na osi OXY;
W tym miejscu, definiujemy położenie każdego elementu z osobna, czyli określamy jego pozycję na okręgu oraz jego spłaszczenie, powstanie romboid. W tym przypadku, zastosowano wzór matematyczny:
kąt obrotu = (A/2)° + (k - (n+1)/2)*A°, gdzie:- A to kąt pierwszego elementu naszej listy (stanowi naszą bazę),
- k jest numerem porządkowym elementu, np: dla pierwszego elementu to 1, a dla trzeciego to 3;
- n to liczba elementów w menu.
Powyższy wzór ma zastosowanie dla nieparzystej liczby elementów. Dla parzystej liczby wzór się nieco zmienia:
kąt obrotu = (A/2)° + (k - n/2)*A°Po obliczeniu kąta obrotu elementów, obliczamy ich przekrzywienie wg wzoru (dla wszystkich ta sama wartość):
kąt przekrzywienia = 90° - kąt obrotuW tym miejscu określamy przestrzeń między elementem listy a przyciskiem głównym menu, aby efekt najazdu (hover) nie pojawiał się;
Definiujemy wygląd środka elementu listy w którym znajduje się link. Dzięki wykonaniu transformacji link będzie widoczny poprawnie. Zerujemy przekrzywienie oraz poprawiamy jego położenie.
Ponadto, tworzymy efektownie wyglądające tło elementu, dzięki temu uzyskujemy ulepszony efekt przestrzeni między elementami.Poprawiamy wygląd linka wewnątrz środkowego elementu listy.
Podsumowanie
Powyższy przykład został przygotowany dla przeglądarki Mozilla Firefox, ale bez problemu można tak zmodyfikować kod, aby działał on również w przeglądarkach z silnikiem Webkit. Zapewne pod IE9 i nowszych też zadziała po podaniu odpowiednich prefiksów.
Dlaczego to menu jest ciekawe i użyteczne? Dlatego, że mamy tu doczynienia z nietypową animacją listy elementów, w których kształty elementów są zależne od kąta nachylenia. Ponadto, dzięki skupieniu elementów w jednym miejscu pod jednym prczyciskiem, możemy utworzyć ciekawe interefejsy użytkownika, które będą cieszyły wzrok animacjami i nie będą rozpraszały uwagi od głównej zawartości strony.
BTW. Wpis ten dokończyłem już po meczu Legii. Na szczęcie mamy przynajmniej jedną polską drużynę w pucharach do grudnia. Podoba Ci się taka forma wpisu, która zawiera wtrącenia niekoniecznie powiązane w projektowaniem stron?
Demo z tego artykułu jest dostępne tutaj (obecnie działa tylko w Firefoksie): menu punktowe w CSS