Transform
skalieren, schräg
stellen und
verschieben
Durch CSS-Transform können Sie die Form eines HTML- oder SVG-Elements zwei- oder drei-dimensional ändern. So lässt es sich etwa spiegeln, drehen oder scheren, aber auch verschieben. Eine solche Transformation ist auf viele HTML Elemente anwendbar, mit Ausnahme von nicht ersetzten Inline-Elementen.
- Individuelle Eigenschaften
- transform-Eigenschaft
- Transformations-Funktionen
- Ausführungsreihenfolge
- Transforms kombinieren
- Drehen, Kreisen und Pendeln
- rotate(): Drehung
- transform-origin: Drehpunkt festlegen
- SVG-Transformationen
- transform-Attribut
- transform-Attribut
- 3D-Transforms
Individuelle Transformations-Eigenschaften
In SVG konnte man Elemente mit dem transform-Attribut verschieben, drehen und spiegeln. Seit 2008 gab es in der CSS-Welt eine entsprechende CSS-Eigenschaft, die sogar 3D-Transformationen ermöglicht.
Im CSS Transforms Module Level 2 wurden zusätzlich die Einzeleigenschaften rotate, scale und translate eingeführt, die mittlerweile von allen Browsern unterstützt werden.[1] Mit ihnen ist es möglich, einfache Transformationen unabhängig voneinander zu festzulegen, und zwar in einer Weise, die der typischen Verwendung auf der Benutzeroberfläche entspricht, anstatt sich die Reihenfolge in transform merken zu müssen.
translate
Die translate-Eigenschaft verschiebt die Form eines HTML- oder SVG-Elements.
Sie erwartet einen, zwei oder drei Werte.
- translate erfordert ein, zwei oder drei mit Leerzeichen getrennte Werte ohne umschließende Klammern.
- die gleichlautende translate()-Funktion erfordert dagegen zwei kommaseparierte Werte innerhalb der Klammer.
@keyframes translating {
0% { translate: 0 0;}
25% { translate: 0;}
50% { translate: 20em 200px;}
75% { translate: 0 200px;}
100%{ translate: 0 0;}
}
.animiert {
animation: translating 4s linear infinite;
background: #dfac20;
}
Im Beispiel wird das aside-Element mit der CSS-animation translating
zuerst nach rechts, dann nach unten, nach links und dann wieder hoch zum Ausgangspunkt verschoben. Dabei wird der folgende Textabsatz kurzfristig verdeckt.
Für Effekte wie :hover
verhält sich das Element zunächst so, als befände es sich noch an seiner Ausgangsposition. Das klingt merkwürdig, aber andernfalls würde ein :hover
-Effekt, der das Element an eine andere Stelle schiebt, eventuell sofort den Effekt beenden und das Element hin und her flackern lassen. Erst dann, wenn die Maus in den Bereich kommt, den das Element an seiner Zielposition belegt, wird der Auslösebereich für :hover
auf die Zielposition gelegt.
Um ein Element zu transformieren und aus dem Elementfluss zu entfernen, können Sie zusätzlich die Eigenschaft position auf absolute
oder fixed
setzen. Der Browser platziert das Element zunächst gemäß der position-Eigenschaft und transformiert es dann.
Eine Verschiebung alleine zeigt ihren Nutzen erst in Kombination mit anderen Transformationen:
scale
Die scale-Eigenschaft streckt, staucht oder verzerrt die Form eines HTML- oder SVG-Elements.
Sie erwartet einen, zwei oder drei Zahlenwerte als Streckungsfaktor(en).
Der Streckungsfaktor ist eine Zahl, das „Streckungszentrum“ (mathematisch korrekt die Fixpunktgerade) wird durch die Eigenschaft transform-origin
festgelegt. Wird dazu keine Angabe gemacht, so ist die Fixpunktgerade die durch den Mittelpunkt des Elements verlaufende Vertikale. Streckungsfaktoren größer als Eins vergrößern (strecken) das Element, Faktoren zwischen Null und Eins stauchen es und negative Faktoren spiegeln das Element an der Fixpunktgeraden.
Der Vollständigkeit halber sei erwähnt, dass k = 1
das Element unverändert lässt, wohingegen k = 0
die Breite des Elements auf Null setzt.
So können Sie eine Parallelstreckung entlang der Horizontalen erreichen. Mit einem negativen Streckungsfaktor können Sie einzelne Wörter oder Buchstaben spiegeln:
.gespiegelt {
color: #c82f04;
display: inline-block;
scale: -1 1;
}
Alle Elemente der Klasse .gespiegelt
werden entlang der x-Achse gespiegelt. Damit dies bei den inline-Elementen span funktioniert, müssen sie einen display:inline-block
bekommen.
scale: -1 1
benötigt einen zweiten Parameter, damit nur die X-Achse gespigelt wird; hier wäre transform: scaleX(-1)
übersichtlicher.
#scale1:hover {
scale: 2 0.5;
translate: -50px 25px;
}
#scale2:hover {
scale: 2 0.5;
}
Innerhalb des svg-Elements werden zwei Sterne mit einem path-Element gezeichnet.
Hovert die Maus über einen Stern, wird dieser in der X-Achse um das Zweifache gestreckt und in der y-Achse auf die Hälfte gestaucht. Damit das Objekt nicht aus dem Element wandert, erfolgt beim linken Stern zusätzlich eine Verschiebung mit translate.
- scale erfordert ein, zwei oder drei mit Leerzeichen getrennte Zahlenwerte ohne umschließende Klammern.
- die gleichlautende scale()-Funktion erfordert dagegen zwei kommaseparierte Werte innerhalb der Klammer.
rotate
Die rotate-Eigenschaft dreht die Form eines HTML oder SVG-Elements. Sie wurde im CSS Transforms Module Level 2 als zusätzliche Möglichkeit bereitgestellt, ein Element unabhängig von den übrigen Transformationen rotieren zu können.
@keyframes pulse {
from {
scale: 1;
}
to {
scale: 1.2;
}
}
svg {
fill: rebeccapurple;
rotate: .40turn;
animation: 1s infinite alternate pulse;
}
Der Pfeil erhält zwei Transformationen. Die Animation der scale-Eigenschaft läuft unabhängig von der Drehung durch rotate ab.
Siehe auch Drehen, Kreisen und Pendeln
transform-Eigenschaft
Die klassische Eigenschaft für Transformationen ist die transform-Eigenschaft. Sie wendet eine 2D- oder 3D-Transformation auf ein Element an, indem eine oder mehrere Transform-Funktionen angewandt werden.
Die Syntax entspricht der „normalen“ CSS-Schreibweise:
transform: … function3(…) function2(…) function1(…);
Diese Transform-Funktionen gibt es:
#scale1:hover {
transform: translate(-50px) scale(2, 0.5);
}
#scale2:hover {
transform: scale(2, 0.5) translate(-50px, 25px);
}
Das Beispiel scheint identisch zum oberen Beispiel. Allerdings wird hier die transform-Eigenschaft verwendet. Nach dem Namen der Eigenschaft folgen mehrere durch Leerzeichen separierte CSS-Funktionen:
- die translate()-Funktion führt die Verschiebung eines Elements aus. Sie benötigt folgende Parameter:
- eine (positive oder negative) Längenangabe für die horizontale Verschiebung,
- eine (optionale) Längenangabe für die vertikale Verschiebung
Wenn nur ein Wert angegeben wird, wird nur die x-Achse verschoben.
- die scale()-Funktion für eine Streckung. Sie benötigt folgende Parameter:
- ein (positiver oder negativer) Zahlenwert für die horizontale
- eine (optionaler) Zahlenwert für die vertikale Streckung
Wird nur eine Zahl angegeben, so gilt dieser Streckungsfaktor für beide Richtungen.
Im Unterschied zur CSS-Syntax für Eigenschaften werden die Parameter in den CSS-Funktionen durch Kommas separiert!
Die Funktionen werden von rechts nach links abgearbeitet:
- der linke Stern wird gestreckt und dann, da auch der Startpunkt des path-Elements skaliert wird, wieder an seinen Ausgangspunkt verschoben.
- der linke Stern wird zuerst verschoben und dann gestreckt. Nach der Transformation findet er sich an anderer Stelle wieder.
Ausführungsreihenfolge mehrerer Transformationen
Gerade wenn Skalierungen oder Rotationen im Spiel sind, ist die Reihenfolge, in der Transformationen angewendet werden, von Bedeutung. Das ist schon kompliziert genug, wenn nur die transform-Eigenschaft genutzt wird, und zusammen mit den übrigen Eigenschaften, die ein Element verschieben können, wird es nicht einfacher.
Eine Einführung dazu, wie der Browser mehrere Transformationen zu einer 3D-Matrix kombiniert, finden Sie bei der Beschreibung von matrix3D()). Die CSS Spezifikation[2] definiert eindeutig, in welcher Reihenfolge diese Kombination vorzunehmen ist, und dadurch entsteht die folgende Ausführungsreihenfolge:
- Verschiebe das Element um den negierten transform-origin Vektor. Das geschieht, weil die Berechnungen, die einen Punkt um einen bestimmten Winkel drehen können, immer auf den Nullpunkt des Koordinatensystems bezogen sind. Diese erste Verschiebung bringt den gewünschten Bezugspunkt der Transformation nach (0,0,0).
- Wende die Transform-Funktionen der transform-Eigenschaft von rechts nach links an. Die zuletzt notierte Transform-Funktion wird zuerst ausgeführt - das vergisst man gerne
- Wende die offset-Eigenschaft an
- Wende die scale-Eigenschaft an
- Wende die rotate-Eigenschaft an
- Wende die translate-Eigenschaft an
- Verschiebe das Element um den transform-origin-Vektor, d.h. Schritt 1 wird rückgängig gemacht.
Neigen und Verzerren mit skewX()
Mit skewX() können Sie ein Element neigen, bzw. verzerren. Durch dieses Schrägstellen können Sie rechteckige Elemente zu Parallelogrammen neigen. Im folgenden Beispiel sollen die Listenelemente der Navigation pfeilartig angeschrägt werden.
ul a {
background: lightgrey;
border: thin solid grey;
display: block;
margin: 0.5em 1em;
padding: 0.5em 1em;
text-decoration: none;
transform: skewX(-30deg);
}
ul a:hover {
background: #dfac20;
}
Die Elemente der Navigation werden zu Parallelogrammen verzerrt – leider aber auch der Text der beinhalteten Links!
Eine Möglichkeit wäre es, einem Kind-Element ul li a span
eine entsprechende positive Verzerrung zu geben. Allerdings würde der Text dann zweimal verzerrt werden und entsprechend unscharf dargestellt.
In der hier verwendeten Alternative werden die angeschrägten Parallelogramme nun durch Pseudoelemente ul a::before
gebildet. Diese werden mit z-index:-1;
in den Hintergrund geschoben.
Die Links der Navigation werden normal darüber dargestellt.
ul a {
display: block;
margin: 0.5em 1em;
position: relative;
text-decoration: none;
z-index: 0;
}
ul a::before {
background: lightgrey;
border: thin solid grey;
content: "\A0 ";
display: block;
height: 100%;
margin: -0.5em -1em;
padding: 0.5em 1em;
position: absolute;
transform: skewX(-30deg);
width: 100%;
z-index: -1;
}
Transformationen kombinieren
ul a::before { transform: skewX(-30%); } ul a:hover::before { /* überschreibt (wsl. unbeabsichtigt) die vorherige Tranfromation mit skewX() */ transform: scale(1.2); }
Eigentlich ist dieses CSS nicht falsch - es arbeitet nur anders als beabsichtigt. Anstatt die beiden CSS-Funktionen zu kombinieren, überschreibt die zweite Zuweisung den ersten Regelsatz.[3]
Die funktionierende Lösung wäre es, alle Funktionen in den Regelsatz einzuschließen, was aber dem WET-Grundsatz widerspricht.
ul a::before {
transform: skewX(-30deg);
}
ul a:hover::before {
transform: translate(-5px) scale(1.1) skewX(-30deg);
}
Alternativ könnte man die kombinierte Transformation nur einmal notieren und die Werte mit custom properties immer wieder neu setzen:
ul a::before {
transform: translate(var(--translate)) scale(var(--scale)) skewX(-30deg);
--scale: 1;
--translate: 0;
}
ul a:hover::before {
--scale: 1.2;
--translate: -10px;
}
kombinierte Transformationen animieren
Wenn Sie die Transform-Eigenschaft animieren möchten, dann müssen Sie wissen, wie der Browser dabei vorgeht. Es sind nämlich mehrere Fälle zu unterscheiden:
- Alle Transform-Funktionen von Start- und Zielzustand sind gleich
- In diesem Fall animiert der Browser jede Transform-Funktion einzeln. „Überrotationen“ wie (rotate(720deg) bleiben dabei erhalten.
- Ein Endzustand ist eine Erweiterung des anderen Endzustandes
- Dieser Fall liegt zum Beispiel vor, wenn an den Startzustand weitere Transform-Funktionen hinten angefügt werden. Der Browser sucht sich nun zu jeder angefügten Funktion den Wert, der zu einer identischen Transformation führt, also translate(0,0) oder scale(1), erweitert den kürzeren Zustand damit und animiert dann wieder jede Transform-Funktion einzeln
- Die 1:1 Zuordnung der Transform-Funktionen zwischen Start- und Endzustand kann nicht hergestellt werden
- Der Browser bildet von links nach rechts eine möglichst lange Kette zueinander passender Funktionen. Die übrigen Transform-Funktionen fasst er im Start- und Endzustanden jeweils zu einer Transformationsmatrix zusammen und interpoliert dann diese Matrix. Das geschieht nicht stumpf durch Interpolation der Matrix-Einzelwerte, statt dessen führt er eine Dekomposition der Matrizen in Einzeltransformationen durch, wodurch eine Liste von Transformationsfunktionen entsteht, deren Reihenfolge immer gleich ist. Und diese Einzeltransformationen werden dann interpoliert.
Sobald Sie den Browser zu einer Matrix-Animation zwingen, müssen Sie auf Überrotationen verzichten. Der Rotationswinkel wird in Form von Sinus- und Cosinuswerten in die Matrix eingearbeitet, wodurch Winkel auf das Intervall [0°, 360°[ normiert werden.
Ein weiteres Problem bei animierten Transformationen ist, dass Sie für Anfangs- und Endzustand immer die vollständige Liste der zu verwendenden Funktionen aufschreiben müssen. Das führt bei späteren Änderungen schnell zu Fehlern, oder zumindest zu viel Arbeit, wenn eine Animation geändert werden soll und mehrere Keyframes vorliegen.
Wenn Sie das nicht möchten, gibt es mehrere Lösungsansätze.
Zum einen können Sie prüfen, ob die neuen Einzeleigenschaften translate, scale und rotate für Ihren Zweck passend sind. Schauen Sie sich dazu die Ausführungsreihenfolge der Transformationen an. Diese Eigenschaften können Sie unabhängig von der transform-Eigenschaft animieren.
Alternative mit custom properties
Das umständliche Notieren aller Transformations-Funktionen lässt sich auch mithilfe von registrierten custom properties vereinfachen. Während unregistrierte custom properties vom Browser als Zeichenketten behandelt werden, die sich nur als "ist da" oder "ist nicht da" animieren lassen, kann die Registrierung dem Browser einen numerischen Datentyp für das Property liefern, für den eine Interpolation möglich ist.
Voraussetzung für diese Methode ist, dass die verwendeten Transform-Funktionen während der Animation gleich bleiben. Dann können Sie die Transformationsfunktion in dem HTML Element, das Sie animieren möchten, notieren und die Werte darin, die animiert werden sollen, durch custom properties angeben:
transform: rotate(.45turn) scale(var(--scale, 1));
Wenn Sie das custom property --scale
nun als Zahl deklarieren, können Sie es in der @keyframes-Regel animieren und der Browser passt die Transformation entsprechend an. Von der zusätzlichen Rotation brauchen Ihre Keyframes dann nichts mehr zu wissen. Allerdings ist die Registrierung von custom properties derzeit (2022) nur in Browsern der Chrome-Familie einsetzbar. Firefox und Safari unterstützen dagegen die Einzeleigenschaften, bei denen Chrome wiederum erst im August 2022 nachgezogen ist. Diese Methode ist deshalb zur Zeit nur für Anwendungsfälle relevant, wo Sie mit Einzeleigenschaften nicht zurechtkommen und wo Sie außerhalb der Chrome-Welt auch auf die Animation verzichten können.
Das folgende Beispiel verwendet in älteren Chrome-Browsern custom properties und in Browsern, die die rotate-Eigenschaft unterstützen, Einzeleigenschaften.
@property --scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@keyframes pulse {
from { --scale: 1.0; }
to { --scale: 1.2; }
}
svg {
fill: rebeccapurple;
width: 12em;
transform: rotate(.45turn) scale(var(--scale, 1));
animation: 1s infinite alternate custom-pulse;
}
@supports (rotate: .45turn) {
svg {
transform: none;
rotate: .45turn;
}
@keyframes pulse {
from { scale: 1.0; }
to { scale: 1.2; }
}
}
@property legt fest, dass die selbstdefinierte Eigenschaft --scale
nur einheitenlose Zahlen enthalten darf, vererbt werden kann und einen Standardwert von 1 hat.
Die Feature-Abfrage auf rotate: .45turn
bewirkt, dass aktuelle Browser durchweg die Animation mit Einzeleigenschaften verwenden. Etwas ältere Chromebrowser fallen auf die custom property Animation zurück. Und Browser, die beides nicht kennen, lassen die Pfeilgröße zwischen klein und groß springen.
Siehe auch
- Polaroid-Bildergalerie
In dieser Bildergalerie werden Bilder als kleinere Vorschauansichten angezeigt. Ein Berühren mit der Maus skaliert sie auf die Originalgröße. Zusätzlich erscheint die bisher durch verborgene figcaption als Bildunterschrift. - SVG/Tutorials/Rube-Goldberg-Maschinen
unnötig komplizierte Maschinen, bei denen eine eigentlich triviale Aktion durch eine Kette nacheinander ablaufender Aktionen ausgelöst wird. Die SVG-Elemente werden mit CSS-Transforms animiert. - SELFHTML-Forum: Erläuterung der Orientierung der Scherung von Gunnar Bittersmann
Weblinks
- W3C: CSS Transforms Module Level 1 vom 20.Aug 2015
- github: Intro to CSS 3D transforms (sehr gutes Tutorial mit vielen Beispielen von David DeSandro)
- ↑ CSSWG: CSS Transforms Module Level 2
- ↑ CSS Transforms 2
- ↑ css-tricks: Individual CSS Transform Functions Chris Coyier on Feb 23, 2017