CSS 3D-Transformationen – transform perspective –

CSS transform perspective

Die CSS-Funktion perspective() transformiert ein Element aus der flachen 2D-Ansicht in einen dreidimensionale räumliche Ansicht. Wenn eine ganze Gruppe von Elementen perspektivisch transformiert werden soll, braucht die Gruppe die CSS Eigenschaft perspective.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Die CSS-Funktion perspective()

Perspektive braucht einen besonderen Wert: den Abstand des fiktiven Betrachters vom Objekt. Was näher am Betrachter liegt, erscheint größer, Objekte im Hintergrund kleiner.

CSS 3D Ebenen für CSS transform perspective

Die blaue Ebene ist die vertraute Fläche des Dokuments, auf der wir Elemente nach oben/unten, rechts/links bewegen oder rotieren.

rotate(90deg)
translate(25px, 25px)

CSS transform perspective() öffnet zusätzlich Y und Z – die Tiefe.

Für die perspektivische Sicht brauchen wir zusätzlich eine weitere Transformation: Für die meisten Effekte ist das eine Rotation.

perspective(400) rotateX(45deg)
perspective(400) rotateY(45deg)

Für ein Element mit perspective() kommt auch eine Transformation auf der Z-Achse in Frage: Die Bewegung auf der Z-Achse vergrößert bzw. verkleinert die Darstellung des Elements.

perspective(400) translateZ(-100px)
perspective(400) translateZ(50px)

Eine perspektivische Transformation braucht zwei Attribute:

  • den Wert für die räumliche Wirkung – perspective(),
  • einen Wert für die Rotation – rotateX() / rotateY() und/oder translateZ().

Der Wert von CSS perspective() bestimmt die Stärke des 3D-Effekts und wirkt wie ein Teleobjektiv: Je größer die Brennweite – der Wert von perspective() –, desto schwächer wird der perspektivische Effekt. Gehen wir mit einer kleinen Brennweite nah an das Motiv, wird der perspektivische Effekt immer stärker und die räumliche Wirkung nimmt zu. Wie bei der Brennweite eines Kameraobjektivs fällt die räumliche Wirkung um so stärker aus, je kleiner der Wert der CSS-Funktion perspective() ist.

perspective 30
rotation 0
.rect {
	transform: perspective(0px) rotateX(0deg)
}

transform-style: preserve-3d

Die Perspektive eines Elements wirkt nur auf seine direkten Kind-Elemente. Damit verschachtelte Kind-Elemente die Perspektive ihres Eltern-Elements erben und sich so im selben 3D-Raum befinden, übergibt das Eltern-Element seine Perspektive mit transform-style: preserve-3d an die untergeordneten Elements.

<transform-container>
	<transform-inner>
		<img src="car-cyan.svg" width="200">
		<inner-car>
			<img src="car-red.svg" width="200">
		</inner-car>
	</transform-inner>
</transform-container>

transform-style: preserve-3d ein- und ausschalten und die Elemente rotieren, um die Wirkung von preserve-3d zu sehen:

transform-inner {
	transform: rotateY(45deg);
	transform-origin:50% 50%;
}

inner-car {
	transform: rotateY(80deg);
	transform-origin:50% 50%;
}

Animationen mit CSS perspective

Animationen mit einem räumlichen Eindruck fallen buchstäblich aus dem Rahmen und kommen meist mit einem Schwung Javascript. Ein Karusell mit nur drei Elementen ist einfach genug, um den Effekt nur mit CSS einzusetzen.

<div class="carousel-parent">
	<div class="carousel-item"></div>
	<div class="carousel-item"></div>
	<div class="carousel-item"></div>
</div>

transform-style gibt an, wie Elemente unterhalb des Eltern-Elements (carousel-parent) gerendert werden und muss zusammen mit transform eingesetzt werden. Die Werte sind flat (Voreinstellung) oder preserve-3d.

Ohne die Einstellung preserve-3d drehen sich die drei Elemente zwar ebenso, aber sie bleiben flach und bauen keinen 3D-Raum auf.

.carousel-parent {
	position: absolute;
	width: 100%;
	height: 100%;
	transform-style: preserve-3d;
	transform: translateZ(var(--z-neg)) rotateY(0);
	animation: carousel 15s infinite forwards;
}
.carousel-item {
	position: absolute;
	top: 0;
	left: 0;
	width: var(--caro-width);
	height: var(--caro-height);
	border-radius: 6px;
}
.carousel-item:nth-child(1) {
	background: url(img/obst2.jpg);
	background-size: cover;
	transform: rotateY(0) translateZ(var(--z-achse));
}
.carousel-item:nth-child(2) {
	background: url(img/obst3.jpg);
	background-size: cover;
	transform: rotateY(120deg) translateZ(var(--z-achse));
}
.carousel-item:nth-child(3) {
	background: url(img/obst-01.jpg);
	background-size: cover;
	transform: rotateY(240deg) translateZ(var(--z-achse));
}

@keyframes carousel {  
	0%, 20% { transform: translateZ(var(--z-neg)) rotateY(0) }
 	25%, 45% { transform: translateZ(var(--z-neg)) rotateY(-120deg) }
	55%, 75% { transform: translateZ(var(--z-neg)) rotateY(-240deg) }
	85%, 100% { transform: translateZ(var(--z-neg)) rotateY(-360deg) }
}

Die CSS-Variablen übernehmen die responsive Anpassung der Bildgrößen.

:root {
	--z-achse: 220px;
	--z-neg: -220px;
	--caro-width: 300px;
	--caro-height: 300px;
}

Flip Cards

Im perspektivischen Carousel ist die Rückseite der Bilder spiegelverkehrt sichtbar, beim Flip-Card-Effekt hingegen sollen Vorder- und Rückseite einer Karte angezeigt werden.

<div class="city">
	<div class="flipcard">
		<div class="flipcard__face flipcard-front"></div>
		<div class="flipcard__face flipcard-back"></div>
	</div>
</div>

Die Perspektive eines Elements wirkt nur auf seine direkten Nachkommen, also hier auf das Element mit class="flipcard". Darum bekommt das Element transform-style: preserve-3d.

.flipcard {
	width: 100%;
	height: 100%;
	position: relative;
	transition: transform 1s;
	transform-style: preserve-3d;
	cursor:pointer;
}

Vorder- und Rückseite sind absolute positioniert und backface-visibility: hidden verbirgt die vom Betrachter abgewendete Seite der Karte.

.flipcard__face {
	position: absolute;
	height: 100%;
	width: 100%;
	backface-visibility: hidden;
}

.flipcard-front {
	background-image: url(img/city-day-560.webp);
}

.flipcard-back {
  background-image: url(img/city-night-560.webp);
  transform: rotateY( 180deg );
}

.flipcard.is-flipped {
  transform: rotateY(180deg);
}

perspective-origin

Wie in der Fotografie bestimmt der Standpunkt des Betrachters die Perspektive. Mit der Voreinstellung perspective-origin: center center zeigt sich der Würfel in frontaler Sicht. Wenn die Seiten nicht semitransparent wären, würden die Seiten, Deckel und Boden in der Zentralperspektive verschwinden.

perspective-origin wird nicht auf das Element selber, sondern auf ein Elternelement angewendet,

wirkt also nicht auf das Element selbst, sondern auf Transformation der untergeordneten Elemente, sodass sie alle eine konsistente Tiefenperspektive haben.

CSS
.box {
  transform-style: preserve-3d;
  perspective: 250px;
}

.boxTopLeft .box { perspective-origin: top left; }
HTML
<div class="box-wrapper boxTopLeft">
	<div class="box">
		<div class="plane front">1</div>
		<div class="plane back">6</div>
		<div class="plane right">4</div>
		<div class="plane left">3</div>
		<div class="plane top">5</div>
		<div class="plane bottom">2</div>
	</div>
</div>

Die CSS-Funktion perspective() beim Beispiel oben versetzt ein einzelnes Element in seinen eigenen dreidimensionalen Raum. Die CSS-Eigenschaft perspective eines Elements transformiert alle Elemente unterhalb in die 3D-Ansicht innerhalb eines Raums.

top left
1
6
4
3
5
2
top
1
6
4
3
5
2
top right
1
6
4
3
5
2
left
1
6
4
3
5
2
center
1
6
4
3
5
2
right
1
6
4
3
5
2
bottom left
1
6
4
3
5
2
bottom
1
6
4
3
5
2
bottom right
1
6
4
3
5
2