Kurs HTML

15.7. Transformacje 3D: perspective i transform-style

Strona główna > Kurs CSS > Rozdział 15: Transformacje CSS > Transformacje 3D: perspective i transform-style

Wprowadzenie do kontekstu 3D

Aby transformacje 3D (takie jak rotateX, rotateY, translateZ, scaleZ) były widoczne i tworzyły iluzję głębi, musimy stworzyć odpowiedni **kontekst renderowania 3D**. Bez niego, transformacje te będą wyglądały na "spłaszczone" w płaszczyźnie 2D.

Kluczowe właściwości do tworzenia tego kontekstu to perspective, perspective-origin (stosowane do rodzica) oraz transform-style (stosowane do rodzica, gdy chcemy transformować jego dzieci w przestrzeni 3D).

Właściwość perspective

Właściwość perspective jest stosowana do **elementu nadrzędnego** transformowanych elementów (lub do samego elementu w funkcji transform: perspective(...)). Określa ona **odległość między płaszczyzną Z=0 a obserwatorem**. Im mniejsza wartość, tym silniejszy efekt perspektywy (jakbyśmy patrzyli z bliska), a im większa, tym efekt jest subtelniejszy (jakbyśmy patrzyli z daleka).

Wartość podaje się w jednostkach długości (np. px). Typowe wartości to kilkaset do kilku tysięcy pikseli.

Składnia (na rodzicu):

.container {
  perspective: 800px;
}

.element-dziecka {
  transform: rotateY(45deg); /* Ten obrót będzie teraz widoczny w 3D */
}

Składnia (w funkcji transform):

.element {
  /* Perspektywa stosowana tylko do tego elementu */
  transform: perspective(800px) rotateY(45deg);
}

Użycie perspective na rodzicu jest częstsze, gdy chcemy, aby wszystkie jego dzieci współdzieliły tę samą perspektywę. Użycie w funkcji transform stosuje perspektywę indywidualnie do każdego elementu.

Właściwość perspective-origin

Ta właściwość, również stosowana do **elementu nadrzędnego**, określa **położenie punktu zbiegu perspektywy** (punkt, z którego "patrzy" obserwator) względem tego rodzica. Domyślnie jest to center center (50% 50%), co oznacza, że patrzymy na środek elementu.

Zmiana perspective-origin wpływa na to, jak obiekty 3D są zniekształcane przez perspektywę.

Składnia:

.container {
  perspective: 800px;
  perspective-origin: top right; /* Patrzymy z prawego górnego rogu */
}

.element-dziecka {
  transform: rotateY(45deg);
}

Wartości działają analogicznie jak dla transform-origin (słowa kluczowe, długości, procenty).

Właściwość transform-style

Właściwość transform-style jest stosowana do **elementu, który sam jest transformowany w 3D**, i określa, jak jego **dzieci** są renderowane w przestrzeni 3D.

  • transform-style: flat; (domyślne): Dzieci są renderowane w płaszczyźnie swojego rodzica. Nawet jeśli dzieci mają własne transformacje 3D, będą one "spłaszczane" do płaszczyzny rodzica.
  • transform-style: preserve-3d;: Dzieci są pozycjonowane w przestrzeni 3D względem rodzica. Pozwala to na tworzenie złożonych, zagnieżdżonych scen 3D, gdzie transformacje dzieci są stosowane w kontekście transformacji rodzica.

Przykład: Sześcian 3D

Aby zbudować sześcian, potrzebujemy kontenera (rodzica) z transform-style: preserve-3d; i sześciu ścian (dzieci), z których każda jest odpowiednio obrócona i przesunięta za pomocą rotate i translateZ.

<div class="scene">
  <div class="cube">
    <div class="face front">1</div>
    <div class="face back">2</div>
    <div class="face right">3</div>
    <div class="face left">4</div>
    <div class="face top">5</div>
    <div class="face bottom">6</div>
  </div>
</div>
.scene {
  width: 200px;
  height: 200px;
  perspective: 600px;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d; /* Kluczowe dla zagnieżdżonych transformacji 3D */
  transform: translateZ(-100px) rotateY(30deg); /* Przykładowa transformacja całego sześcianu */
}

.face {
  position: absolute;
  width: 200px;
  height: 200px;
  border: 1px solid black;
  background: rgba(200, 200, 200, 0.7);
  text-align: center;
  font-size: 30px;
  line-height: 200px;
}

/* Ustawienie poszczególnych ścian */
.front  { transform: rotateY(  0deg) translateZ(100px); }
.back   { transform: rotateY(180deg) translateZ(100px); }
.right  { transform: rotateY( 90deg) translateZ(100px); }
.left   { transform: rotateY(-90deg) translateZ(100px); }
.top    { transform: rotateX( 90deg) translateZ(100px); }
.bottom { transform: rotateX(-90deg) translateZ(100px); }

Bez transform-style: preserve-3d; na elemencie .cube, wszystkie ściany zostałyby spłaszczone do płaszczyzny sześcianu i nie utworzyłyby trójwymiarowej bryły.

FAQ - Najczęściej zadawane pytania

Gdzie dokładnie umieścić perspective?

perspective umieszcza się na elemencie **nadrzędnym** dla elementów, które mają być transformowane w 3D. Definiuje ona wspólną perspektywę dla wszystkich jego dzieci. Alternatywnie, można użyć funkcji perspective() bezpośrednio we właściwości transform elementu, co stosuje perspektywę tylko do tego konkretnego elementu.

Jaka jest dobra wartość dla perspective?

Nie ma jednej idealnej wartości. Zależy to od pożądanego efektu. Wartości między 500px a 1000px są często dobrym punktem wyjścia. Mniejsze wartości dają silniejszy, bardziej "rybie oko" efekt, a większe wartości dają subtelniejszą perspektywę.

Czy transform-style: preserve-3d jest dziedziczone?

Nie, właściwość transform-style nie jest dziedziczona. Jeśli chcesz tworzyć wielopoziomowe zagnieżdżone struktury 3D, musisz ustawić transform-style: preserve-3d; na każdym elemencie w hierarchii, który ma mieć dzieci renderowane w jego własnej przestrzeni 3D.

Czy transformacje 3D są kosztowne pod względem wydajności?

Transformacje 3D, podobnie jak 2D, są zazwyczaj dobrze optymalizowane przez przeglądarki i często wykorzystują akcelerację GPU. Jednak tworzenie bardzo złożonych scen 3D z wieloma elementami i animacjami może obciążyć przeglądarkę, zwłaszcza na słabszych urządzeniach. Warto testować wydajność.