CSS3 - Perspektywa elementu HTML

W poprzedniej części kursu CSS poznaliśmy informacje o tym w jaki sposób przeglądarka internetowa stara się odwzorować wygląd elementu HTML w przestrzeni 3D, gdy skorzystamy z funkcji właściwości transform, które są przeznaczone do przekształcenia elementu HTML w przestrzeni 3D.

W tej części kursu CSS poznamy sposoby dodania perspektywy do elementu HTML, która jest wymagana w przypadku gdy chcemy przekształcić dany element HTML tak, aby jego wygląd przypominał element HTML znajdujący się w przestrzeni 3D.

Na sam początek utworzymy prosty układ elementów HTML w relacji jeden element rodzic oraz kilka elementów dzieci.

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

    <style>
      #rodzic {
        position:relative;
        outline:3px solid red;
        width:500px;
        height:400px;
        line-height:100px;
        margin:0 auto;
        text-align:center;
        font-size:30px;
        background-color:#FEE;
      }

      #rodzic > div {
        position:absolute;
        outline:3px solid black;
        width:120px;
        height:120px;
        line-height:60px;
        font-size:20px;
        background-color:#FDD700;
      }

      #dziecko1 {
        top:30px;
        left:30px;
      }

      #dziecko2 {
        top:30px;
        right:30px;
      }

      #dziecko3 {
        bottom:30px;
        left:30px;
      }

      #dziecko4 {
        bottom:30px;
        right:30px;
      }
    </style>
  </head>

  <body>

    <div id="rodzic">rodzic
      <div id="dziecko1">dziecko - 1</div>
      <div id="dziecko2">dziecko - 2</div>
      <div id="dziecko3">dziecko - 3</div>
      <div id="dziecko4">dziecko - 4</div>
    </div>

  </body>
</html>

Rezultat:

dziecko - 1
dziecko - 2
dziecko - 3
dziecko - 4

Nasz układ elementów HTML nie zawiera w sobie niczego szczególnego, po prostu jest to jeden element div (#rodzic), w którym zostały umieszczone cztery inne elementy div (które w tym wypadku są elementami dziećmi elementu #rodzic). Elementy dzieci zostały odpowiednio rozmieszczone w zawartości elementu #rodzic, ponieważ skorzystaliśmy z właściwości position, którą wraz z wartością relative dodaliśmy do elementu #rodzic, natomiast do dzieci wspomnianego elementu #rodzic dodaliśmy właściwość position wraz z wartością absolute, dzięki czemu za pomocą właściwości top, right, bottom, left możemy kontrolować pozycję elementów dzieci w zawartości elementu #rodzic (dzięki relacji pozycja absolutna do pozycji relatywnej, czyli właściwość position:absolute; do właściwości position:relative; o czym była mowa w jednej z poprzednich części tego działu kursu CSS - Pozycja statyczna, relatywna, absolutna oraz ustalona).

Naszym celem na samym początku tej części kursu CSS będzie sprawienie, aby każdy element dziecko elementu #rodzic w naszym przykładowym układzie elementów HTML posiadał swoją własną perspektywę oraz aby każdy wspomniany element dziecko elementu #rodzic został obrócony w pionie o 30 stopni.

Z poprzedniej części kursu CSS wiemy, że każdy element HTML posiada niewidzialny dla nas punkt środka perspektywy, który domyślnie znajduje się w miejscu przecięcia się poziomej osi X oraz pionowej osi Y danego elementu HTML, czyli w centralnej części elementu HTML. Na schemacie, który znajduje się poniżej, został zaznaczony punkt środka perspektywy dla każdego elementu HTML w naszym przykładowym układzie elementów HTML.

transform CSS3 - punkty środka kilku perspektyw

Również z poprzedniej części kursu CSS wiemy, iż aby utworzyć perspektywę dla interesującego nas elementu HTML należy skorzystać z właściwości transform oraz funkcji perspective(). Przykładowo, gdy dodamy właściwość transform wraz z funkcją perspective(300px) do interesującego nas elementu HTML, element ten znajdzie się w zasięgu swojej perspektywy, czyli punkt środka perspektywy interesującego nas elementu HTML zostanie przesunięty względem osi Z (po stronie Z+) od pozycji początkowej o 300 pikseli.

Zobaczmy co się stanie z elementami dziećmi elementu #rodzic w naszym przykładowym układzie elementów HTML, gdy do wspomnianych elementów dzieci elementu #rodzic dodamy właściwość transform wraz z funkcją perspective(300px).

#rodzic > div {
  position:absolute;
  outline:3px solid black;
  width:120px;
  height:120px;
  line-height:60px;
  font-size:20px;
  background-color:#FDD700;
  transform:perspective(300px);
}

Rezultat:

dziecko - 1
dziecko - 2
dziecko - 3
dziecko - 4

Wizualnie nie otrzymaliśmy żadnej zmiany wyglądu elementów HTML w naszym przykładowym układzie elementów HTML, jednak na schemacie, który został zaprezentowany poniżej możemy dostrzec, co tak naprawdę zmieniło się w naszym układzie elementów HTML.

transform CSS3 - transform:perspective(300px);

Punkt środka perspektywy każdego elementu dziecka elementu #rodzic w naszym przykładowym układzie elementów HTML został odsunięty od swojej pozycji początkowej względem osi Z o 300 pikseli za pomocą funkcji perspective(300px) właściwości transform, dzięki czemu każdy wspomniany element dziecko znajduje się w zasięgu swojej własnej perspektywy. W tym momencie, gdy zechcemy przekształcić, któryś z naszych przykładowych elementów dzieci za pomocą funkcji właściwości transform, które służą do przekształcenia elementu HTML w przestrzeni 3D, przeglądarka internetowa poradzi sobie z takim przekształceniem, ponieważ dany element HTML będzie znajdował się w swojej własnej perspektywie, której wartością nie jest wartość domyślna 0.

Zobaczmy jak zmieni się wygląd naszego przykładowego układu elementów HTML, gdy do każdego elementu dziecka elementu #rodzic dodamy zapis transform:perspective(300px) rotateY(30deg);.

#rodzic > div {
  position:absolute;
  outline:3px solid black;
  width:120px;
  height:120px;
  line-height:60px;
  font-size:20px;
  background-color:#FDD700;
  transform:perspective(300px) rotateY(30deg);
}

Rezultat:

dziecko - 1
dziecko - 2
dziecko - 3
dziecko - 4

Naszym celem podczas tej części kursu CSS było sprawienie, aby każdy element dziecko elementu #rodzic w naszym przykładowym układzie elementów HTML znalazł się w zasięgu swojej własnej perspektywy oraz aby został obrócony o 30 stopni w pionie, co jak widzimy udało się nam osiągnąć za pomocą właściwości transform oraz funkcji perspective(300px) i rotateY(30deg).

Naszym drugim celem podczas tej części kursu CSS będzie sprawienie, aby każdy element dziecko elementu #rodzic w naszym przykładowym układzie elementów HTML znalazł się w zasięgu jednej i tej samej perspektywy, która będzie należała do wspomnianego elementu #rodzic oraz aby wspomniane elementy dzieci zostały obrócone w pionie o 30 stopni.

Aby osiągnąć nasz cel możemy skorzystać z właściwości perspective, która gdy zostanie dodana do elementu HTML tworzy perspektywę dla danego elementu HTML, w zasięgu której znajdą się wszystkie elementy dzieci wspomnianego elementu HTML, lecz nie on sam. Mówiąc prościej - element rodzic nie znajdzie się w zasięgu swojej perspektywy, lecz wszystkie jego elementy dzieci tak.

#rodzic {
  position:relative;
  outline:3px solid red;
  width:500px;
  height:400px;
  line-height:100px;
  margin:0 auto;
  text-align:center;
  font-size:30px;
  background-color:#FEE;
  perspective:300px;
}

Poniżej znajduje się schemat naszego układu elementów HTML po dodaniu do elementu #rodzic właściwości perspective:300px;.

transform CSS3 - perspective:300;

Na naszym schemacie możemy dostrzec, że właściwość perspective, działa podobnie jak funkcja perspective() właściwości transform. Owe podobieństwo tyczy się tego, że właściwość perspective podobnie jak funkcja perspective() właściwości transform odsuwa punkt środka perspektywy danego elementu HTML od jego pozycji początkowej wzdłuż osi Z o podaną wartość. Jedną z różnic pomiędzy właściwością perspective, a funkcją perspective() właściwości transform jest fakt, że właściwość perspective tworzy jedną perspektywę dla wszystkich dzieci interesującego nas elementu HTML, natomiast funkcja perspective() właściwości transform tworzy perspektywę tylko dla tego elementu HTML, do którego zostanie dodana wspomniana funkcja perspective() wraz z właściwością transform.

Zobaczmy jak będzie wyglądał nasz przykładowy układ elementów HTML, gdy do elementu #rodzic dodamy właściwość perspective:300px; natomiast do elementów dzieci elementu #rodzic dodamy właściwość transform wraz z funkcją rotateY(30deg).

#rodzic {
  position:relative;
  outline:3px solid red;
  width:500px;
  height:400px;
  line-height:100px;
  margin:0 auto;
  text-align:center;
  font-size:30px;
  background-color:#FEE;
  perspective:300px;
}

#rodzic > div {
  position:absolute;
  outline:3px solid black;
  width:120px;
  height:120px;
  line-height:60px;
  font-size:20px;
  background-color:#FDD700;
  transform:rotateY(30deg);
}

Rezultat:

dziecko - 1
dziecko - 2
dziecko - 3
dziecko - 4

Naszym drugim celem podczas tej części kursu CSS było sprawienie, aby wszystkie elementy dzieci elementu #rodzic znalazły się w zasięgu jednej i tej samej perspektywy oraz aby zostały obrócone w pionie o 30 stopni. Wspomniany cel udało się nam osiągnąć za pomocą właściwości perspective:300px; oraz funkcji rotateY(30deg) właściwości transform, jednak naszym oczom ukazał nieco inny widok, jaki moglibyśmy się spodziewać, co prawda każdy element dziecko elementu #rodzic został przekształcony za pomocą tej samej funkcji rotateY() z tą samą wartością 30deg, jednak każdy z zaprezentowanych elementów HTML różni się wyglądem od pozostałych.

Dlaczego się tak dzieje?

Żeby odpowiedzieć sobie na to pytanie musimy przyjrzeć się jeszcze raz dwóm zaprezentowanym wcześniej schematom.

#rodzic > div {transform:perspective(300px);}

transform CSS3 - transform:perspective(300px);

Na pierwszym zaprezentowanym schemacie widzimy cztery elementy dzieci elementu #rodzic, które wyglądem nie różnią się od siebie. Wygląd wspomnianych elementów HTML będzie również taki sam, gdy spróbujemy przekształcić je za pomocą tej samej funkcji właściwości transform wraz z tą samą wartością, np. rotateY(30deg), ponieważ każdy element dziecko elementu #rodzic znajduje się w zasięgu swojej własnej perspektywy.

To tak gdybyśmy ustawili przed naszymi oczami cztery takie same przedmioty w różnych miejscach, obrócili je o tą samą wartość w tym samym kierunku, a następnie na każdy przedmiot spojrzelibyśmy z osobna przesuwając naszą głowę wraz z oczyma na tą sama odległość od każdego z poszczególnych przedmiotów względem ich środka, a następnie spróbowalibyśmy sobie wyobrazić jeden obraz wyglądu wszystkich czterech przedmiotów, które zobaczyliśmy.

#rodzic {perspective:300px;}

transform CSS3 - perspective:300;

Na drugim zaprezentowanym schemacie widzimy cztery elementy dzieci elementu #rodzic, które wyglądem nie różnią się od siebie, jednak wygląd wspomnianych elementów HTML nie będzie taki sam, gdy spróbujemy przekształcić je za pomocą tej samej funkcji właściwości transform wraz z tą samą wartością, np. rotateY(30deg), ponieważ każdy element dziecko elementu #rodzic znajduje się w zasięgu jednej i tej samej perspektywy.

To tak gdybyśmy ustawili przed naszymi oczami cztery takie same przedmioty w różnych miejscach, obrócili je o tą samą wartość w tym samym kierunku, a następnie na wszystkie cztery przedmioty spojrzelibyśmy z jednej i tej samej perspektywy, czyli z jednego miejsca, w którym znalazłaby się nasza głowa wraz z oczami, co w rezultacie dałoby nam jeden obraz wszystkich czterech wspomnianych przedmiotów.

Czas na kolejny cel podczas tej części kursu CSS. Tym razem naszym celem będzie sprawienie, aby element #rodzic oraz wszystkie jego elementy dzieci znalazły się w zasięgu jednej i tej samej perspektywy, dzięki czemu będziemy mogli wykonać przekształcenie w przestrzeni 3D na elemencie #rodzic oraz na jego elementach dzieciach względem jednej i tej samej perspektywy (przy korzystaniu z właściwości perspective jest to możliwe tylko dla elementów dzieci danego elementu HTML).

Aby osiągnąć nasz cel musimy ponownie skorzystać z funkcji perspective() właściwości transform, którą tym razem dodajemy do elementu #rodzic.

#rodzic {
  position:relative;
  outline:3px solid red;
  width:500px;
  height:400px;
  line-height:100px;
  margin:0 auto;
  text-align:center;
  font-size:30px;
  background-color:#FEE;
  transform:perspective(300px);
}

Poniżej znajduje się schemat naszego układu elementów HTML po dodaniu do elementu #rodzic właściwości transform:perspective(300px);.

transform CSS3 - perspective(300px);

Jak już zdążyliśmy się przyzwyczaić funkcja perspective() właściwości transform dodaje perspektywę do elementu HTML, do którego zostanie dodana wspomniana właściwość transform wraz z funkcją perspective().

Na naszym schemacie widzimy, że punkt środka perspektywy elementu #rodzic zmienił swoją pozycję początkową po tym jak do elementu #rodzic została dodana właściwość transform wraz z funkcją perspective(300px). Na naszym schemacie widzimy również, iż w zasięgu wspomnianego punktu środka perspektywy znalazł się tylko element #rodzic, co dla potrzeb naszego przykładu zostało oznaczone czerwonymi liniami. Naszym celem jest, aby nie tylko element #rodzic znalazł się w zasięgu jednej, swojej własnej perspektywy, lecz aby również elementy dzieci wspomnianego elementu #rodzic również znalazły się w zasięgu perspektywy swojego elementu rodzica. Wspomniany efekt możemy uzyskać za pomocą właściwości transform-style oraz wartości preserve-3d.

#rodzic {
  position:relative;
  outline:3px solid red;
  width:500px;
  height:400px;
  line-height:100px;
  margin:0 auto;
  text-align:center;
  font-size:30px;
  background-color:#FEE;
  transform:perspective(300px);
  transform-style:preserve-3d;
}

Poniżej znajduje się schemat naszego układu elementów HTML po dodaniu do elementu #rodzic właściwości transform:perspective(300px); oraz właściwości transform-style:preserve-3d;.

transform CSS3 - preserve-3d;

Spoglądając na nasz schemat przykładowego układu elementów HTML możemy dostrzec, że funkcja perspective() właściwości transform tworzy perspektywę dla elementu HTML, natomiast właściwość transform-style wraz z wartością preserve-3d dodana do elementu HTML, który znajduje się w zasięgu jakiejkolwiek perspektywy sprawia, że dana perspektywa rozszerza swój zasięg również na elementy dzieci elementu HTML, do którego została dodana właściwość transform-style wraz z wartością preserve-3d. Dlatego w tym momencie nasz cel został osiągnięty, ponieważ zarówno element #rodzic, jak również jego elementy dzieci znajdują się w zasięgu jednej i tej samej perspektywy.

Aby dobrze zrozumieć działanie właściwości transform-style oraz wartości preserve-3d należy zapamiętać, że dodaje się ją do elementu HTML w celu wymuszenia, aby elementy dzieci danego elementu HTML znalazły się w tym samym zasięgu perspektywy, w której znajduje się ich element rodzic, do którego dodaliśmy właściwość transform-style wraz z wartością preserve-3d. Mowa tu o perspektywie, w zasięgu której znalazł się dany element rodzic, dzięki funkcji perspective() właściwości transform lub dzięki właściwości perspective lub dzięki właściwości transform-style oraz wartości preserve-3d.

Z tej części kursu CSS należy przede wszystkim zapamiętać, że gdy korzystamy tylko z właściwości perspective to przeglądarka internetowa jest zdolna do prawidłowego przekształcenia w przestrzeni 3D tylko elementów dzieci elementu HTML, do którego została dodana wspomniana właściwość perspective, a nie ich elementu rodzica. Natomiast gdy korzystamy z połączenia funkcji perspective() oraz właściwości transform oraz właściwości transform-style oraz wartości preserve-3d, przeglądarka internetowa jest zdolna do prawidłowego przekształcenia w przestrzeni 3D zarówno elementów dzieci, jak również ich elementu rodzica, do którego została dodana wspomniana funkcja perspective() właściwości transform oraz została dodana właściwość transform-style wraz z wartością preserve-3d.

W następnej części kursu CSS postaramy się zrozumieć, dlaczego informacje, które zostały zaprezentowane w tej części kursu CSS są takie ważne w kontekście przekształceń elementów HTML w przestrzeni 3D.