Kawałek Kodu

Dziś znów wracamy do tematu animacji CSS. Pomimo, że ostatnio robiliśmy baby steps, dziś będzie wielki krok w przód. Spróbujemy wystartować animację po najechaniu myszą na element, ale jednocześnie spowodować, aby odtwarzała się nadal po zjechaniu z niego. Bez JavaScript of course!

Na początku było słowo.

Potrzebujemy nasz element. Dodatkowo kilka innych na stronie, aby pokazać co się z nimi dzieje kiedy animacja odtwarza się. Bo tak różowo nie będzie, ale też nie tak smoliście czarno.

<!-- to zapełniacz strony -->
<p>Lorem Ipsum jest tekstem stosowanym jako przykładowy wypełniacz 
w przemyśle poligraficznym. Został po raz pierwszy użyty w XV w. przez 
nieznanego drukarza do wypełnienia tekstem próbnej książki.
Pięć wieków później zaczął być używany przemyśle elektronicznym, 
pozostając praktycznie niezmienionym. Spopularyzował się w latach 60. XX w. 
wraz z publikacją arkuszy Letrasetu, zawierających fragmenty Lorem Ipsum, 
a ostatnio z zawierającym różne wersje Lorem Ipsum oprogramowaniem 
przeznaczonym do realizacji druków na komputerach osobistych, 
jak Aldus PageMaker
</p>

<!-- to nasz element -->
<div></div>

<!-- a to znów zapełniacz strony -->
<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>
<p>Lorem Ipsum jest tekstem stosowanym jako przykładowy wypełniacz 
w przemyśle poligraficznym. Został po raz pierwszy użyty w XV w. przez 
nieznanego drukarza do wypełnienia tekstem próbnej książki.
Pięć wieków później zaczął być używany przemyśle elektronicznym, 
pozostając praktycznie niezmienionym. Spopularyzował się w latach 60. XX w. 
wraz z publikacją arkuszy Letrasetu, zawierających fragmenty Lorem Ipsum, 
a ostatnio z zawierającym różne wersje Lorem Ipsum oprogramowaniem 
przeznaczonym do realizacji druków na komputerach osobistych, 
jak Aldus PageMaker
</p>

Kiedy najeżdżamy myszą na element chcemy aby animacja startowała i to potrafimy zrobić. Jednak zazwyczaj kiedy mysza ucieka znad elementu, animacja przestaje działać. Mogłaby działać gdyby element pokrywał ekran w miejscu gdzie znajduje się kursor myszy. Jednak tego nie chcemy, bo element ma zachowywać swoje wymiary i nie wpływać na layout strony. 

A wcześniej był :before.

Właśnie! Nie musimy manipulować rozmiarami naszego elementu, ale możemy wykorzystać pseudoelement :before, który pokryje stronę i będzie nadal "odbierał" kursor myszy. I to jest ta łyżka czarnego dziegciu dolana do kolorowego zachwytu. Nie łam się, nie będzie tak źle. Element :before wstawimy na stronę tylko podczas odtwarzania animacji, wtedy inne elementy na stronie niestety nie będą aktywne, natomiast przed i po, wrócą do normy.

/* nasz element */
div {
  width: 200px;
  height: 200px;
  display: inline-block;
  background: #f00;
  position: relative;
  z-index: 10000;
/* animacja zmiany koloru tła */
  animation: anim 2s forwards;
/* na razie spauzowana */
  animation-play-state: paused;
}

/* nasz element pokrywający cały ekran
   przed :hover siedzi sobie grzecznie w środku <DIV>
*/
div:before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: block;
/* chowamy element pod rodzica */
  z-index: -1;
/* animacja powrotu do absolute */
  animation: animBefore 0s 2s forwards;
/* na razie spauzowana */
  animation-play-state: paused;
}

/* na :hover startujemy animację zmiany koloru tła */
div:hover {
  animation-play-state: running;
}

/* na :hover zmieniamy położenie i wymiary
   będzie na pełny ekran z pozycją fixed
*/
div:hover:before {
  position: fixed;
  width: 100vw;
  height: 100vh;
/* startujemy animację animBefore */
  animation-play-state: running;
}

@keyframes anim {
  0% {
    background: #000;
  }
  100% {
    background: #f00;
  }
}

@keyframes animBefore {
  0%, 100% {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
}

p,
ul,
div {
  float: left;
}

Działa to następująco. Na :hover startujemy animację dla DIV. Element :before ustawiamy na pełny ekran i jemu też startujemy animację. Ale ta jest opóźniona o 2 sekundy, czyli tyle ile trwa animacja na głównym elemencie. Animacja na :before nie ma właściwie klatek, po prostu po 2 sekundach element znów wciśnie się do środka rodzica i przestanie okupować cały ekran.

Animacja jednak nie startuje ponownie po najechaniu i tu wykorzysytamy tajemnicze zaklęcie z wpisu Wszystko od początku! Czyli o resetowaniu animacji CSS.

div:not(:hover),
div:not(:hover):before {
  animation: empty;
}

A tu już animacja w akcji.

Mi do tej pory nie udało się znaleźć w czeluściach internetu innego rozwiązania na problem z tego wpisu. Jeśli masz inny pomysł, pisz!
Ja na razie wykonuję zdarzenie out i zjeżdżam stąd. Do przeczytania!