CSS3 - Animowany efekt wprowadzanego tekstu

W tej części kursu CSS utworzymy animowany efekt wprowadzenego tekstu.

Końcowy rezultat został zaprezentowany poniżej.

To jest przykładowy tekst

Nasz docelowy efekt przypomina moment, gdy wprowadzamy tekst, np. w jakimś edytorze tekstowym. Do utworzenia wspomnianego efektu przyda nam się podobna wiedza, która była nam potrzebna w poprzedniej części kursu CSS.

Zaczniemy od utworzenia odpowiedniego układu elementów HTML, w części body dokumentu HTML.

<body>

  <div id="blok">To jest przykładowy tekst<span></span></div>

</body>

Nasz układ elementów HTML to po prostu pusty element span umieszczony w elemencie div. Do elementu div został dodany atrybut id, dzięki czemu wykorzystamy jego wartość, czyli wartość blok, w regułach CSS, które zostały umieszczone poniżej:

#blok {
  float:left;
  font-size:1.8em;
  font-family:"Courier New", monospace;
  background-color:white;
}

#blok > span {
  background-color:white;
}

Rezultat:

To jest przykładowy tekst

Jak na razie nasz układ elementów HTML nie zawiera w sobie niczego specjalnego. Zawartością elementu #blok jest tekst oraz pusty element span. Wykorzystamy ten pusty element span do przesłonięcia całego tekstu elementu #blok, jednak cały ten proces będzie wykonywała animacja CSS, którą utworzymy, lecz najpierw musimy dodać dodatkowe właściwości CSS, do naszych wcześniej utworzonych reguł CSS.

#blok {
  position:relative;
  float:left;
  font-size:1.8em;
  font-family:"Courier New", monospace;
  background-color:white;
}

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
}

Z poprzednich części kursu CSS powinniśmy wiedzieć jak oddziałują na siebie elementy pozycjonowane relatywnie oraz absolutnie. Element span, który jest pozycjonowany absolutnie (position:absolute;), został przesunięty do górnej krawędzi (top:0;) oraz prawej krawędzi (right:0;) pierwszego przodka pozycjonowanego relatywnie (position:relative;), czyli elementu #blok. Wysokość elementu span będzie równa wysokości elementu #blok, dzięki zapisowi height:100%;

Rezultat:

To jest przykładowy tekst

Rezultat jest taki sam jak wcześniej i właśnie o to nam chodziło, ponieważ w ten sposób zabezpieczymy się przed sytuacją, gdy dana przeglądarka internetowa nie będzie interpretować animacji CSS3, które będą nam potrzebne do uzyskania końcowego efektu.

Spójrzmy co się stanie, gdy zwiększymy szerokość elementu span (dla ułatwienia został on wypełniony czerwonym tłem).

To jest przykładowy tekst

Obszar elementu span przesłania zawartość elementu #blok.

Czas stworzyć animację, która na starcie będzie posiadała wartość szerokości równą 100%, a na końcu będzie posiadała wartość szerokości równą 0.

@keyframes pisz
{
  0% { width:100%; }
  100% { width:0; }
}

W ten sposób utworzoną animację pisz dodajemy do elementu span, dzięki następującemu zapisowi:

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
  animation:pisz 10s linear infinite;
}

Rezultat:

To jest przykładowy tekst

Nasza animacja pisz została dodana do elementu span. Wspomniana animacja trwa dziesięć sekund (10s), ma stałe tempo (linear) oraz powtarza się od początku do końca, w nieskończoność (infinite).

Pierwszym ważnym czynnikiem do uzyskania naszego ostatecznego efektu jest to, aby kolor tła elementu #blok oraz elementu span był taki sam (na ten czas, czerwone tło elementu span pełni tylko pomocniczą rolę, o czym była mowa już wcześniej).

Gdy określaliśmy tempo animacji dla naszego elementu span, to wybraliśmy wartość linear, która sprawia, że tempo animacji jest stałe, lecz nie daje to naszego docelowego efektu. Skorzystamy więc z funkcji steps.

Jako pierwszy parametr funkcji steps należy podać liczbę klatek animacji, dzięki czemu nasza animacja będzie składała się z określonej liczby klatek, które będą ukazywały się naszym oczom, jedna po drugiej, w stałych odstępach czasu. Liczbą klatek będzie liczba znaków, które zostały umieszczone w elemencie #blok, a tą liczbą jest liczba 25 (liczymy nie tylko litery, ale też ewentualne spacje).

Jako drugi parametr mamy do wyboru wartość start lub end. Wartość end jest wartością domyślną, która sprawia, że w danej animacji jest pomijana ostatnia klatka, jednak my podamy wartość start, dzięki czemu nasza animacja zacznie się od drugiej klatki.

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
  animation:pisz 10s steps(25,start) infinite;
}

Rezultat:

To jest przykładowy tekst

Nie bez powodu utworzyliśmy czcionkę typu monospace, dla naszego układu elementów HTML. Wspomniany typ czcionki sprawia, że każdy znak tekstu ma tą samą szerokość. Skoro każdy znak naszego tekstu, który składa się z 25-ciu takich znaków, ma stałą wartość szerokości, a nasza animacja ma stałe tempo oraz składa się z 25 klatek, to widzimy efekt, który został umieszczony powyżej.

Czas zająć się drugą animacją, która utworzy nam znak zachęty (pionowy migający czarny pasek). Tym paskiem będzie lewe obramowanie elementu span, które w zwykłych okolicznościach (bez animacji CSS) będzie przezroczyste.

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
  border-left:1px solid transparent;
  animation:pisz 10s steps(25,start) infinite;
}

Tworzymy następującą animację CSS o przykładowej nazwie znak.

@keyframes znak
{
  0% { border-left-color:transparent; }
  50% { border-left-color:black; }
  100% { border-left-color:transparent; }
}

Nasza animacja znak będzie zmieniać kolor lewego obramowania, z przezroczystego koloru na czarny, następnie z czarnego na przezroczysty.

Naszą animację znak dodajemy do elementu span, za pomocą następującego zapisu:

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
  border-left:1px solid transparent;
  animation:pisz 10s steps(25,start) infinite, znak 1s step-end infinite;
}

Rezultat:

To jest przykładowy tekst

Od tej pory element span zawiera w sobie dwie animację CSS. Animację pisz już omówiliśmy, natomiast animacja znak trwa jedną sekundę (1s) oraz powtarza się w nieskończoność, od początku do końca (infinite).

Wspomniana animacja znak ma tempo step-end, co oznacza, że dana animacja będzie składała się z określonej liczby klatek animacji, a tą liczbą klatek będzie liczba selektorów czasu animacji, jakie budują daną animację (w naszej animacji znak są to trzy selektory, czyli 0%, 50%, 100%), dodatkowo ostatnia klatka animacji jest pomijana (czyli w tym wypadku wartości właściwości CSS, które zostały podane w selektorze 100%).

Kod całego dokumentu HTML został umieszczony poniżej:

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

    <style>
      #blok {
        position:relative;
        float:left;
        font-size:1.8em;
        font-family:"Courier New", monospace;
        background-color:white;
      }

      #blok > span {
        position:absolute;
        top:0;
        right:0;
        height:100%;
        background-color:white;
        border-left:1px solid transparent;
        animation:pisz 10s steps(25,start) infinite, znak 1s step-end infinite;
        -webkit-animation:pisz 10s steps(25,start) infinite, znak 1s step-end infinite; /* dla Google Chrome, Safari, Opera 15+ */
      }

      #blok > p:hover {
        animation-play-state:paused;
      }
	  
      /* ------------ANIMACJE------------ */
      @keyframes pisz
      {
        0% { width:100%; }
        100% { width:0; }
      }

      @keyframes znak
      {
        0% { border-left-color:transparent; }
        50% { border-left-color:black; }
        100% { border-left-color:transparent; }
      }

      /* dla Google Chrome, Safari, Opera 15+ */
      @-webkit-keyframes pisz
      {
        0% { width:100%; }
        100% { width:0; }
      }

      @-webkit-keyframes znak
      {
        0% { border-left-color:transparent; }
        50% { border-left-color:black; }
        100% { border-left-color:transparent; }
      }
    </style>
  </head>

  <body>

    <div id="blok">To jest przykładowy tekst<span></span></div>

  </body>
</html>

Jeżeli chcemy, aby nasza animacja wykonała się tylko raz, to usuwamy z właściwości animation wartości infinite, które odpowiadają za nieskończoną ilość powtórzeń animacji. Dodatkowo dla animacji znak określamy liczbę powtórzeń animacji dzieląc czas animacji pisz przez czas animacji znak, czyli 10s / 1s = 10, dzięki czemu nasze obramowanie elementu span będzie migać przez cały czas, jaki będzie potrzebowała animacja pisz, aby wykonać się jeden raz.

Dodatkowo usuwamy parametr start z funkcji steps(), co sprawi że zostanie użyty domyślny parametr dla tej funkcji, czyli wartość end, dzięki czemu animacja pisz pominie ostatnią klatkę animacji, a nie pierwszą (wcześniej potrzebowaliśmy, aby klatka pierwsza była pomijana, ponieważ nasza animacja była animacją powtarzającą się, gdyby ostatnia klatka była pomijana, to nie zobaczylibyśmy ostatniego znaku tekstu elementu #blok).

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:white;
  border-left:1px solid transparent;
  animation:pisz 10s steps(25), znak 1s step-end 10;
}

Rezultat zobaczysz po odświeżeniu strony (cały efekt wykonuje się tylko raz, w tym wypadku).

To jest przykładowy tekst

Inny efekt uzyskamy, gdy określimy przezroczysty kolor tła dla elementu span, dodatkowo możemy pogrubić czcionkę tekstu (font-weight:bold;).

#blok {
  position:relative;
  float:left;
  font-size:1.8em;
  font-family:"Courier New", monospace;
  font-weight:bold;
  background-color:white;
}

#blok > span {
  position:absolute;
  top:0;
  right:0;
  height:100%;
  background-color:rgba(255,255,255,0.9);
  border-left:1px solid transparent;
  animation:pisz 10s steps(25,start) infinite, znak 1s step-end infinite;
}

Rezultat:

To jest przykładowy tekst

Jednym z ograniczeń naszego efektu jest to, że tekst elementu #blok musi zawsze być umieszczony w jednym wierszu, czyli musi mieścić się w szerokości elementu #blok.

Ponadto sam element #blok musi mieć taką samą wartość szerokości, jaką ma tekst umieszczony w nim (w tym wypadku uzyskujemy tą zależność dzięki właściwości float:left;).

Natomiast jeżeli chcemy dodać właściwość padding do elementu #blok, to element span powinien posiadać właściwość margin z tymi samymi wartościami co właściwość padding, którą chcemy dodać do elementu #blok.

W następnej części kursu wykorzystamy funkcję steps() oraz inne właściwości CSS, do utworzenia animowanego obrazka, klatka po klatce.