Kawałek Kodu

Mówią, że ilu ludzi tyle opinii. Nie wiem czy to się przekłada na przedstawianie rozwiązań. Chyba nie, bo dziś w liczbie osób 1, przedstawię Ci aż 4 sposoby na efekt hover. Dwa z nich znasz z pewnością, jeden być może, a ostatni być może być może.

Wyrollowani.

Java Script był chyba pierwszym sposobem na osiągnięcie efektu hover. Właściwie wtedy nazywało się go rollover. Wtedy kiedy królowały przeglądarki IE5 oraz IE6 pseudoklasa działała wyłącznie z elementami A. Tak więc JS był jedynym fix'em na rozpropagowanie efektu na dowolny element HTML. Co ciekawe, oprócz umieszczania obsługi zdarzeń bezpośrednio w atrybutach elementu (onmouseover, onmouseout), IE umożliwał sprytniejszy sposób implementacji takiej pseudoklasy.

Jeśli chcieliśmy, aby wszystkie elementy w  BODY podatne były na :hover, to do BODY podpinana była następująca reguła w CSS:

body {
  behavior: url(hoverfix.htc);
}

Plik .htc był niczym innym jak plikiem JS, choć wraz ze znacznikami <SCRIPT>. Działało to mniej więcej tak:

  • znalezienie wszystkich dzieci danego selektora,
  • usunięcie pseudoklasy :hover z arkusza styli (tego załadowanego do przeglądarki),
  • kopia styli z :hover do reguły opartej na klasie onhover,
  • podpięcie zdarzeń JS do elementu wraz z obsługą dodawania i usuwania klasy onhover.

Być może pamiętasz CSS3 PIE, dzięki któremy można było osiągnąć zaokrąglone narożniki w elementach. Jeśli tak, to właśnie ta nakładka również korzystała z pliku .htc.

Pułapka na mysz.

Kiedy przeglądarki zaczęły namiętnie obsługiwać pseudoklasę na dowolnym elemencie, to wtedy i projektanci stron zaczęli się drapać w głowę myśląc, że może jednak jest to lepsze rozwiązanie niż podmiana atrybutu src obrazka z pomocą JS. Późniejsze pojawienie się selektorów sąsiada oraz bezpośredniego sąsiada całkowicie zrewolucjonizowało obszar związany z Nakrywcami. Na stronach można było zobaczyć zmieniające się elementy pomimo, że interakcja użytkownika obejmowała inny element - niczym za działaniem różdżki Merlina.

Tak więc mieliśmy (i mamy!):

*:hover{
}

*:hover *{
}

*:hover > *{
}

*:hover + *{
}

*:hover ~ *{
}

Etykietka na haczyku.

To jest ten trzeci sposób, o którym być może czytałeś w jednym z poprzednich wpisów, jeśli nie to zapraszam Cię na: Etykietka na haczyku, czyli label hack - efekt hover pomiędzy dwoma niespokrewnionymi elementami. To jest niczym rewolucja w rewolucji, bo w stosunku do poprzedniego rozwiązania, możemy powiązać efektem dwa elementy leżące w dowolnych miejscach drzewa DOM. Niestety tylko element LABEL wraz z powiązaną kontrolka formularza, czyli np.:

<div>
  <input type="checkbox" id="c"/>
  <p>Tekst</p>
</div>
<label for="c">Najedź tutaj</label>

+

input:hover + p{
  color: #f00;
}

W powyższym przykładzie po najechaniu na element LABEL wywołany zostanie hover na elemencie INPUT, co możemy wykorzystać do ostylowania tekstu w bezpośrednim sąsiedzie (P). Zauważ, że element P jest zagłębiony w elemencie DIV, a dodatkowo ten blok jest przed elementem LABEL.

Wektorowy hover.

Jeśli chodzi o elementy SVG, to nic nie stoi na przeszkodzie, aby używać pseudoklasy :hover dla elementów potomnych, ale jest również inne rozwiązanie, nie wykraczające poza strukturę SVG.

<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320">
  <circle cx="159" cy="159" r="40" stroke="#000" stroke-width="1" fill="#f00" >
    <animate attributeName="fill" begin="mouseover" dur="0.001s" to="#f0f" fill="freeze" />
    <animate attributeName="fill" begin="mouseout" dur="0.001s" to="#f00" fill="freeze" />
  </circle>
</svg>

SVG - wiadomo, CIRCLE - wiadomo. O animacji w SVG też trochę było, ale wyjaśnijmy. Elementy ANIMATE mamy umieszczone w środku węzła CIRCLE, co oznacza, że są one przypisane właśnie do tego elementu. Jeśli byłyby poza CIRCLE, to należałoby je wiązac poprzez atrybut xlink:href.      

No dobra, to co "robią" poszczególne atrybuty ANIMATE:

  • attributeName - wskazuje jaki atrybut będzie poddawany animacji,
  • begin - determinuje jakie zdarzenie wywoła animację, nie musi to być interakcja z użytkownikiem, może to być relatywny punkt w czasie,
  • dur - tu czas trwania animacji. 0s niestety nie spowoduje jej wywołania, więc nadałem jakiś znikomy czas,
  • to - wartość dla właściwości wskazanej w attributeName, którą animacja ma osiągnąć w 100%,
  • fill - jak ma się zakończyć animacja - podobnie jak animation-fille-mode w CSS (freeze - forwards, remove - none).

Możesz się zastanawiać dlaczego nie użyłem jednego elementu ANIMATE (wyzwalanego na mouseover) wraz z atrubtem fill="remove". Niestety wyzwalanie animacji faktycznie następuje po najechaniu myszą na element, ale kiedy się skończy, a mysz nadal byłaby nad kółkiem, to i tak kolor tła wróciłby do domyślego. Zmiana wartości atrybutu fill na freeze, wcale nie pomaga, bo bym razem kolor pozostałby fioletowy nawet po usunięciu wskaźnika znad kółka. Trzeba więc zastosować dwie odrębne animacje. Taką, która zmieni kolor kółka i po zakończeniu pozostawi, oraz taką, która przywróci domyślny kolor po zjechaniu wskaźnika. Tu też musi fill musi mieć wartość freeze, bo inaczej po zakończeniu tej animacji kolor powróciłby do poprzedniego, czyli fioletowego!

Tak to działa:

Każdego kto poczuł, że przynależy do tajemnego kręgu Nakrywców, zapraszam do kolejnego wpisu. Oczywiście pozostałych również. Do przeczytania!

 

Przydatne linki:
Jak naprawić :hover w IE (czyli jak to się robiło w 2008).