CSS3 - Animowana karta w przestrzeni 3D

W tej i w następnych częściach kursu CSS wykorzystamy informacje, z którymi mogliśmy zapoznać się w dziale pierwszy podczas poznawania zasad jakie rządzą przekształceniami elementu HTML w przestrzeni 2D oraz 3D - Przekształcenia Transform CSS3.

Pierwszym układem elementów, jaki utworzymy, będą elementy HTML, które wyglądem będą przypominały obracającą się kartę w przestrzeni 3D. Nasza wirtualna karta będzie posiadała swój przód jak i tył, tak jak zwykła karta w świecie realnym.

Efekt końcowy został zaprezentowany poniżej (najedź kursorem myszki na elementy HTML, aby zobaczyć efekt, nad którym będziemy pracować w tej części kursu CSS).

LEW

Od tej pory będę operował nazwami, z którymi mogliśmy zapoznać się w dziale pierwszym podczas poznawania osi X, osi Y, przestrzeni 3D (która często będzie nazywana przeze mnie "przestrzenią perspektywy").

Niestety, ale układy elementów HTML, którymi będziemy się zajmować przez najbliższe części tego działu, nie będą interpretowane przez przeglądarkę Internet Explorer (do czasu gdy zacznie ona rozumieć właściwość transform-style:preserve-3d;).

Pierwszą rzeczą jaką musimy sobie uświadomić jest fakt, że aby wykonać tego typu układ elementów HTML, jaki został zaprezentowany powyżej, wszystkie elementy HTML powinny znaleźć się w tej samej przestrzeni perspektywy.

Na samym początku dodajemy dwa elementy div do części body. Wspomniane elementy div umieszczamy jeden w drugim.

<body>

  <div id="pudelko">
    <div id="karta">KARTA</div>
  </div>

</body>

Do elementu #pudelko dodajemy przestrzeń perspektywy za pomocą właściwości perspective, dzięki czemu jego element dziecko, czyli element #karta, znajdzie się we wspomnianej przestrzeni perspektywy.

#pudelko {
  width:180px;
  height:240px;
  margin:0 auto;
  border:3px dashed #000;
  background-color:#FDD700;
  perspective:300px;
}

#karta {
  width:100%;
  height:100%;
  background-color:#EEE;
  text-align:center;
}

Następnie tworzymy regułę CSS, która sprawi, że po najechaniu kursorem myszki na element #pudelko jego element dziecko div zostanie obrócony wokół własnej osi Y o 180 stopni. Aby wspomniany efekt trwał dłużej, dodajemy efekt przejścia, czyli właściwość transition:1s; do obracanego elementu HTML, czyli do elementu #karta.

#karta {
  width:100%;
  height:100%;
  text-align:center;
  background-color:#EEE;
  transition:1s;
}

#pudelko:hover > #karta {
  transform:rotateY(180deg);
}

Rezultat zobaczysz po najechaniu kursorem myszki na obszar elementu #pudelko.

KARTA

W tym momencie należy sobie uświadomić jedną istotną rzecz, o której należy zawsze pamiętać, ponieważ gdy wykonujemy jakieś przekształcenie w przestrzeni na elemencie HTML to jego cała zawartość również ulega przekształceniu. Wspomnianą zawartością mogą być, np. inne elementy HTML.

Do elementu #karta dodajemy dwa kolejne elementy div, które utworzą przednią oraz tylną stronę naszego układu elementów HTML. Wspomniane elementy powinny być tych samych rozmiarów co ich rodzic i powinny znajdować się w tym samym miejscu, w granicy szerokości oraz wysokości ich elementu rodzica.

<body>

  <div id="pudelko">
    <div id="karta">
      <div id="przod">PRZÓD</div>
      <div id="tyl">LEW</div>
    </div>
  </div>

</body>

Aby elementy div znalazły się w tym samym miejscu dodajemy do nich właściwość position:absolute; a do ich rodzica, czyli elementu #karta, dodajemy właściwość position:relative;

Dla ułatwienia, na razie, utworzymy różny rozmiar szerokości oraz wysokości dla elementów #przod oraz #tyl, aby zobaczyć ich miejsce w przestrzeni perspektywy, do której wkrótce zostaną dodane.

#karta {
  position:relative;
  width:100%;
  height:100%;
  text-align:center;
  background-color:#EEE;
  transition:1s;
}

#przod {
  position:absolute;
  width:100%;
  height:60%;
  color:#F00;
  font-size:1.6em;
  background:url('http://webkod.pl/images/lioncard.png') no-repeat;
  background-size:100%;
}

#tyl {
  position:absolute;
  width:50%;
  height:30%;
  color:#FFF;
  font-size:1.6em;
  background-color:#000;
}

Rezultat:

PRZÓD
LEW

W realnym świecie, gdy patrzymy na kartę, która leży na naszym biurku, to nie możemy widzieć jej przedniej oraz tylnej strony jednocześnie, ponieważ jedna z tych stron będzie zawsze obrócona od naszego wzroku i przesłonięta przez drugą stronę karty.

Naszym celem będzie uzyskać ten sam efekt w świecie wirtualnym.


Obracamy element #tyl o 180 stopni wokół jego osi Y, dzięki czemu zobaczymy jego tylną stronę (odwrócony napis LEW).

#tyl {
  position:absolute;
  width:50%;
  height:30%;
  color:#FFF;
  font-size:1.6em;
  background-color:#000;
  transform:rotateY(180deg);
}

Rezultat:

PRZÓD
LEW

Czas przyjrzeć się naszemu efektowi, jaki do tej pory udało się nam uzyskać.

Gdy najedziemy kursorem myszki na element #pudelko to jego element dziecko #karta jest obracany o 180 stopni wokół własnej osi Y. Zawartość jaką posiada element #karta jest obraca razem z nim. Wspomnianą zawartością elementu #karta są elementy #przod oraz #tyl. Gdy element #karta oraz jego elementy dzieci, czyli elementy #przod oraz #tyl, zostaną obrócone o 180 stopni, to widzimy tylną stroną wszystkich wymienionych elementów HTML, czyli elementu #karta, #przod oraz #tyl, jednak nie tyczy się to elementu #tyl, ponieważ do tego elementu dodaliśmy obrót o 180 stopni wokół osi Y, dzięki właściwości transform:rotateY(180deg); dlatego też w momencie gdy element #tyl jest obracany o 180 stopni razem z jego elementem rodzicem, czyli elementem #karta, to w tym momencie, po wykonaniu obrotu na elemencie #karta, będziemy widzieć przednią stronę elementu #tyl, tylną stronę elementu #przod oraz tylną stronę elementu #karta.

Analizując cały dotychczasowy efekt, jaki udało się nam uzyskać, możemy dość do wniosku, że wystarczy ukryć tylną stronę elementu #przod oraz tylną stronę elementu #tyl, aby uzyskać efekt obracanej karty w przestrzeni 3D. Do ukrycia tylnej strony elementu HTML służy właściwość backface-visibility wraz z wartością hidden.

Zobaczmy jak będzie wyglądał nasz efekt, gdy dodamy właściwość backface-visibility:hidden; do elementów #przod oraz #tyl.

#przod {
  position:absolute;
  width:100%;
  height:60%;
  color:#F00;
  font-size:1.6em;
  background:url('http://webkod.pl/images/lioncard.png') no-repeat;
  background-size:100%;
  backface-visibility:hidden;
}

#tyl {
  position:absolute;
  width:50%;
  height:30%;
  color:#FFF;
  font-size:1.6em;
  background-color:#000;
  transform:rotateY(180deg);
  backface-visibility:hidden;
}

Rezultat:

PRZÓD
LEW

Efekt jaki tym razem udało się nam utworzyć jest tylko w niewielkim stopniu tym co chcemy uzyskać. Właściwość backface-visibility:hidden; ukryła tylną stronę elementu #tyl, jednak w ogóle już jej nie widzimy nawet po obróceniu elementu #karta o 180 stopni wokół osi Y, co więcej tylna strona elementu #przod nadal jest widoczna, mimo tego że do wspomnianego elementu #przod dodaliśmy właściwość backface-visibility:hidden;

Dlaczego tak się dzieje? Dlaczego widoczność tylnej strony elementów #przod oraz #tyl nie zmienia się po obróceniu elementu #karta wokół własnej osi Y o 180 stopni?

Ponieważ elementy #przod oraz #tyl nie znajdują się w tej samej przestrzeni perspektywy co ich rodzic, czyli element #karta, dlatego wspomniane elementy HTML są rozumiane przez przeglądarkę internetową jako zwykła zawartość elementu #karta, obraca wraz ze wspomnianym elementem.

Spójrzmy co się stanie z naszym układem elementów HTML, gdy do elementu #karta dodamy właściwość transform-style wraz z wartością preserve-3d.

#karta {
  position:relative;
  width:100%;
  height:100%;
  text-align:center;
  background-color:#EEE;
  transition:1s;
  transform-style:preserve-3d;
}

Rezultat:

PRZÓD
LEW

Nasz efekt od tej pory jest tym do czego dążyliśmy.

W momencie gdy dodaliśmy właściwość transform-style:preserve-3d; do elementu #karta to jego elementy dzieci, czyli element #przod oraz #tyl, znalazły się w tej samej przestrzeni perspektywy co element #karta, dlatego też w momencie gdy obracamy elementem #karta to jego elementy dzieci są uwzględniane w perspektywie przestrzeni, w której znalazł się element #karta, a tą perspektywą przestrzeni jest perspektywa utworzona za pomocą właściwości perspective:300px; w elemencie #pudelko.

Nie pozostaje nam nic innego, jak dodać pozostałe, znane już nam właściwości CSS, do elementów #przod oraz #tyl.

#przod {
  position:absolute;
  width:100%;
  height:100%;
  background:url('http://webkod.pl/images/lioncard.png') no-repeat;
  background-size:100%;
  box-shadow:0 0 4px 8px #FFF inset;
  backface-visibility:hidden;
}

#tyl {
  position:absolute;
  width:100%;
  height:100%;
  line-height:240px;
  color:#FFF;
  font-size:1.6em;
  background-color:#000;
  box-shadow:0 0 4px 8px #FFF inset;
  transform:rotateY(180deg);
  backface-visibility:hidden;
}

Finalny rezultat:

LEW

Kod dokumentu HTML został umieszczony poniżej:

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

    <style>
      #pudelko {
        width:180px;
        height:240px;
        margin:0 auto;
        perspective:300px;
        -webkit-perspective:300px;
      }

      #karta {
        position:relative;
        width:100%;
        height:100%;
        text-align:center;
        transition:1s;
        -webkit-transition:1s;
        transform-style:preserve-3d;
        -webkit-transform-style:preserve-3d;
      }

      #pudelko:hover > #karta {
        transform:rotateY(180deg);
        -webkit-transform:rotateY(180deg);
      }

      #przod {
        position:absolute;
        width:100%;
        height:100%;
        background:url('http://webkod.pl/images/lioncard.png') no-repeat;
        background-size:100%;
        box-shadow:0 0 4px 8px #FFF inset;
        backface-visibility:hidden;
        -webkit-backface-visibility:hidden;
      }

      #tyl {
        position:absolute;
        width:100%;
        height:100%;
        line-height:240px;
        color:#FFF;
        font-size:1.6em;
        background-color:#000;
        box-shadow:0 0 4px 8px #FFF inset;
        transform:rotateY(180deg);
        -webkit-transform:rotateY(180deg);
        backface-visibility:hidden;
        -webkit-backface-visibility:hidden;
      }
    </style>
  </head>

  <body>
  
    <div id="pudelko">
      <div id="karta">
        <div id="przod"></div>
        <div id="tyl">LEW</div>
      </div>
    </div>

  </body>
</html>

Jeżeli nadal nie rozumiesz niektórych zagadnień związanych z przekształceniami w przestrzeni perspektywy to nic się nie martw, ponieważ kolejne części tego działu wyjaśnią o wiele więcej.

W następnej części kursu CSS utworzymy Animowany Sześcian 3D.