Ganzseitige Animationen mit CSS

Mit Internet Explorer 9 wurde Unterstützung für CSS 2D-Transformationen eingeführt. Mit der Internet Explorer 10 Developer Preview wurde Unterstützung für CSS-3D-Transformationen und CSS-Animationen hinzugefügt. Diese IE10-Funktionen nutzen die volle Leistungsfähigkeit Ihrer GPU und werden asynchron zu regulärem JavaScript ausgeführt. Sie stellen damit eine leistungsstärkere und flexiblere Alternative zu traditionellen skriptbasierten Animationen für Webinhalte dar.

CSS 3D-Transformationen sowie CSS-Animationen und -Übergänge wurden bereits in früheren Blogbeiträgen behandelt. In diesem Beitrag stellen wir ein „unkonventionelleres“ Nutzungsszenario dieser Technologien vor und erläutern das Konzept der „ganzseitigen Animationen“, die im Navigationsprozess verwendet werden können, um Flüssigkeit und Kontinuität beim Browsen zu erzielen. Wir möchten damit ein nahtloses Browsen ermöglichen, bei dem Inhalte reibungslos im Bild eingeblendet werden, wenn der Benutzer eine Seite besucht, und mit fließenden Übergängen ausgeblendet werden, wenn er auf einen Link klickt oder eine relevante Aktion ausführt.

Diese Effekte können durch Transformieren des HTML-<body>-Elements mithilfe von CSS-Animationen erreicht werden. Bei diesem Nutzungsszenario werden aber einige Überlegungen angestellt, die der näheren Erläuterung bedürfen, z. B. die Auswirkung von Layout und Größenanpassung auf das Transformieren von <body> sowie die Frage der entsprechenden zeitlichen Abstimmung von Seitennavigationen, damit sie richtig mit unseren Animationen ineinander greifen.

Das Codebeispiel in diesem Beitrag verwendet CSS-Markup ohne Präfix, so wie von der IE10 Release Preview unterstützt, andere Browser benötigen möglicherweise Herstellerpräfixe für die verwendeten Eigenschaften für CSS-Animationen und CSS-Transformationen.

Transformieren des gesamten Inhalts einer Seite

CSS-Transformationen werden in den stilistischen Eigenschaften eines HTML-DOM-Elements definiert. Der Markup zum Drehen eines Elements um 45 Grad entlang seiner Z-Achse würde zum Beispiel so aussehen:

#element {

transform: rotateZ(45deg);

}

Das Anfügen einer Transformation an das <body>-Element Ihres HTML-Dokuments funktioniert in gleicher Weise. Sie könnten in etwa wie folgt vorgehen, um den gleichen Effekt zum <body> Ihres Dokuments deklarativ hinzuzufügen:

body {

transform: rotateZ(45deg);

}

Schauen wir uns die Vorher-Nachher-Aufnahme einer Seite an, wenn eine Transformation auf das Textelement angewendet wird:

Screenshot, der das Anwenden einer rotateZ(45deg)-Transformation auf das Textelement eines Dokuments zeigt
Anwenden einer rotateZ(45deg)-Transformation auf das Textelement eines Dokuments.

Bei dreidimensionalen Transformationen definiert die Spezifikation für CSS-Transformationen die perspective-Eigenschaft, die im übergeordneten Element des zu transformierenden Elements angegeben werden kann. Beim Transformieren des <body>-Elements Ihres Inhalts muss es auf das <html>-Element angewendet werden, das sich über ihm innerhalb der DOM-Hierarchie befindet. Das ist ziemlich einfach:

html {

perspective: 500px;

}

Eine Kombination mit einer rotateY(45deg)-Transformation des <body>-Elements führt zum folgenden Ergebnis:

Screenshot, der das Anwenden einer rotateZ(45deg)-Transformation auf <body> zeigt mit perspective: 500px-Einstellung bei <html>
Anwenden einer rotateZ(45deg)-Transformation auf <body> mit perspective: 500px-Einstellung bei <html>.

Wir können die transform-origin-Eigenschaft des Textelements so manipulieren, dass interessante Ergebnisse entstehen. Sehen wir uns einige Beispiele an:

body {

transform-origin: 50% 100%;

transform: rotateX(45deg);

}

Durch das obige Markup wird eine Drehung entlang der X-Achse für das Textelement festgelegt, während gleichzeitig der Ausgangspunkt der Drehung mithilfe von transform-origin zur Unterseite des Elements verschoben wird. Dadurch wird der Inhalt des Dokuments in den Bildschirm hinein gedreht, so wie hier zu sehen:

Screenshot, der das Anwenden von transform: rotateX(45deg) und transform-origin: 50% 100% auf <body> zeigt

Es ist ebenso möglich, die perspective-origin-Eigenschaft des Stammelements des Dokuments zu manipulieren und damit einen Projektionseffekt außerhalb der Achse zu erzielen. Ändern des Stils von <html> zu:

html {

perspective: 500px;

perspective-origin: 90% 50%;

}

Unsere Seite sieht jetzt folgendermaßen aus:

Screenshot, der das Anwenden von perspective: 500px und perspective-origin: 90% 50% auf das <html>-Element zeigt

Mithilfe von CSS-Transformationen lässt sich die visuelle Erscheinung des gesamten Inhalts unserer Seite ganz leicht manipulieren. Da die üblichen Layout- und Größenanpassungsregeln immer noch gelten, können einige Transformationen des Textelements (besonders wenn sie Prozentzahlen verwenden oder auf die transform-origin-Eigenschaft angewiesen sind) in Abhängigkeit vom Inhalt unserer Seite zu unterschiedlichen visuellen Effekten führen. Denken Sie an das vorherige rotateX(45deg)-Beispiel mit der transform-origin-Einstellung von 50% 100%.

Unten können Sie die Ergebnisse sehen, bevor und nachdem die Transformation angewendet wird.

Screenshot, der die Unterschiede bei den Bildlaufleisten vor und nach dem Anwenden einer Transformation mit Perspektivprojektion hervorhebt

Achten Sie darauf, wie sich der Inhalt nicht wirklich am unteren Fensterrand dreht, sondern eher an einem Punkt außerhalb des Viewports. Für CSS-Transformationen ist dies das erwartete Verhalten: der <body> verfügt über ein normales Layout und wird dann entlang seines unteren Rands gedreht, der sich außerhalb des Bildschirms befindet. Sie sehen auch, dass sich der tatsächliche Platzbedarf des Inhalts ausgeweitet hat (achten Sie auf die Bildlaufleisten im „Nachher“-Bild), um den transformierten Inhalt unterzubringen (da wir Perspektivprojektion verwenden, ist dieser Effekt noch stärker ausgeprägt).

Was machen wir also mit beliebig großen Inhalten, wenn Transformationen auf das Textelement angewendet werden? Alle Inhalte maßzuschneidern, damit die Größe des Texts sich nicht über ein gewisses Maß ausdehnt, erscheint unrealistisch. Stattdessen können wir mithilfe eines einfachen HTML/CSS-Musters die Größe des Textelements an diejenige des Browserfensters binden und Inhalt innerhalb eines Wrapper <div> anfügen. Das folgende Markup erreicht genau das

html, body {

width: 100%;

height: 100%;

min-width: 100%;

max-width: 100%;

padding: 0;

margin: 0;

overflow: hidden;

}

 

#Wrapper {

position: absolute;

width: 100%;

height: 100%;

overflow: scroll;

}

Die Abbildung unten zeigt, was passiert, wenn ein vertikaler Bildlauf auf einer Seite durchgeführt wird und wir eine rotateY(45deg)-Transformation direkt (links) und mithilfe des Wrappermusters (rechts) auf das <body>-Element unseres Dokuments anwenden:

Screenshot, der zeigt, was passiert, wenn ein vertikaler Bildlauf auf einer Seite durchgeführt wird und eine rotateY(45deg)-Transformation auf das <body>-Element unter Perspektivprojektion angewendet wird, mit und ohne ein CSS/HTML-Wrappermuster

Die direkte Anwendung der Transformation führt aufgrund der außeraxialen Projektion (da wir nicht länger auf „Zentrum“ des Textelements schauen) zu einem schiefen visuellen Ergebnis. Durch Verwendung des Wrappermusters ist gewährleistet, dass die perspective-origin-Eigenschaft (standardmäßig 50% 50%) des <html>-Elements immer richtig im Verhältnis zum <body>-Element zentriert wird und eine angenehmer visueller Eindruck entsteht.

Durch Verwenden des obigen Musters und Festlegen von CSS-Transformationen mit Prozentwerten, wenn möglich, lässt sich unabhängig von der Größe seines Inhalts ein einheitlicher Effekt auf das <body>-Element erreichen.

Von Transformationen zu Animationen

Nachdem Sie nun die komplexen Zusammenhänge des Anwendens von CSS-Transformationen auf das <body>-Element kennen, sind CSS-Animationen der nächste Schritt. Den oben beschriebenen Prinzipien folgend, können wir Animationen erstellen, die unsere Webinhalte auf interessante Weise in das Bild rücken.

Denken Sie an diese grundlegende @keyframes-Regel:

@keyframes rotateInLeft {

from {

transform-origin: 0% 0%;

transform: rotateY(180deg);

}

to {

transform-origin: 0% 0%;

transform: rotateY(0deg);

}

}

Auf ein Element angewendet, verursacht diese Animation eine Drehung des Elements auf seiner linken Seite. Auf ein <body>-Element angewendet, das unser Wrappermuster verwendet, ergibt sich ein interessanteres visuelles Ergebnis. Das Dokument dreht sich dann tatsächlich von außerhalb des visuellen Bereichs des Browserfensters hinein in die Vollansicht:

Drei Screenshots in Folge, die zeigen, wie sich das Anwenden der „rotateInLeft“-Animation auswirkt

In ähnlicher Weise können wir Animationen erstellen, die unseren Webinhalt fließend aus dem Sichtbereich entfernen. Damit unsere Seite in die Ferne verschwindet, während sie sich dabei dreht, könnten wir Folgendes verwenden:

@keyframes whirlOut {

to {

transform: scale(0)rotateZ(1260deg);

}

}

Das visuelle Ergebnis wäre:

Drei Screenshots in Folge, die zeigen wie, sich das Anwenden der „whirlOut“-Animation auswirkt

Da wir die umfassenden Möglichkeiten von CSS-Animationen auf die Gesamtheit unseres Webinhalts anwenden können, bietet sich eine große Flexibilität beim Erstellen dieser Effekte für ganze Seiten (und das beschränkt sich nicht allein auf die Verwendung von CSS-Transformationen). Nachdem wir diese Effekte zum Anwenden auf unseren Inhalt programmiert haben, stellt sich die Frage: Wie können wir diese Effekte während des Prozesses der Seitennavigation auslösen?

Anfügen von Animationen an <body>

Ziel ist es, auslösende Animationen so an strategischen Punkten des Browsens einzusetzen, dass der Eindruck entsteht, beim Laden einer Seite wird Inhalt eingeblendet und, wenn der Benutzer auf einen Link klickt, wieder ausgeblendet.

Der erste naheliegende Punkt, um eine Animation zum Textelement hinzuzufügen, wäre das onload-JavaScript-Ereignis. Allerdings müssen wir feststellen, dass es jedoch bereits zu spät, eine Animation hinzuzufügen, wenn onload ausgelöst wird. Dieses Ereignis löst tatsächlich erst aus, nachdem der gesamte Inhalt der Seite bereits geladen wurde (einschließlich aller Bilder oder anderer Ressourcen, die hohe Bandbreiten benötigen). Das Anfügen einer Animation an onload für eine Seite mit starker Bandbreitenbeanspruchung würde zunächst zu einer „normalen“ Anzeige des Inhalts führen und anschließend durch das Auslösen der Animation zu einer erneuten Einblendung des Inhalts. Das ist nicht gerade der Effekt, den wir erzielen wollen.

Eine Alternative wäre das DOMContentLoaded-Ereignis, das auslöst, sobald der Browser die Analyse der DOM-Struktur des Inhalts beendet hat (jedoch potenziell bevor das Laden der Ressourcen beendet wurde). Die IE Test Drive-DOMContentLoaded-Demo zeigt den Unterschied zwischen diesen beiden Ereignissen. Allerdings könnte ein moderner Browser bei komplexen Webinhalten ein „progressives“ Rendering anwenden und die Seite anzeigen, bevor die DOM-Struktur vollständig geladen wurde. In diesen Situationen wäre das visuelle Ergebnis ähnlich wie beim onload-Szenario.

Der optimale Punkt zum Einfügen einer Animation, die unseren Seiteninhalt einblendet, ist inline zu Beginn des <body>-Elements. So ist sichergestellt, dass die Animation genau dann beginnt, wenn der Inhalt gerendert wird (und dass die Anfangsposition des Inhalts dem from-Keyframe der ausgewählten Animation entspricht). Ein angenehmer Nebeneffekt dabei ist, dass die Animation sogar progressives Rendering, Layoutanpassungen oder das Laden von Ressourcen maskieren kann, die bei komplexen Inhalten auftreten können.

Das Einrichten von Animationen, die den Inhalt aus dem Bild ausblenden, ist ebenso interessant. Man würde vermuten, wir können einfach einen onclick-Handler an alle interessanten Objekte unseres Inhalts anfügen (zum Beispiel alle <a>-Tags) und dabei die relevanten Animationseigenschaften (animation-name, animation-duration usw.) in der Callback-Funktion festlegen. Wir erhalten jedoch nicht den erwarteten flüssigen Übergang, es sei denn, wir verzögern die Navigation tatsächlich in ihrem Ablauf .

Das ist eine günstige Gelegenheit, die Animationsereignisse zu verwenden, die in der Spezifikation für CSS-Animationen beschrieben werden. Insbesondere kann das animationend-Ereignis dazu verwendet werden, das Beenden der Animation festzustellen und dann einen Navigationsvorgang auszulösen (zum Beispiel durch Festlegen von window.location.href). So löst unser onclick die „Aus-dem-Bild-ausblenden“-Animation aus und registriert einen Handler für animationend in <body>, der sicherstellt, dass das Navigationsereignis stattfindet.

Live-Demo verfügbar

Wir haben eine Demonstration und ein englischsprachiges Tutorial über das Beleben von Seiten mithilfe von CSS-Transformationen und -Animationen erstellt, das die Materie vertieft und weitere Beispiele enthält, die über das hinausgehen, was hier dargestellt werden konnte. Das Tutorial verwendet ganzseitige Animationen bei der Seitennavigation, die in Internet Explorer 10 unter Windows 8 ebenso funktionieren wie in aktuellen Versionen von Chrome und Firefox.

Um die Animationen der Seitenübergänge anzusehen, blättern Sie einfach seitenweise durch das Tutorial, indem Sie den „Continue to ...“-Link in der rechten unteren Ecke der einzelnen Seiten verwenden.

Am Ende des Tutorials geben wir weitere Ratschläge und Codebeispiele, die Ihnen zeigen, wie Sie diese Animationen bei Ihren eigenen Webinhalten anwenden können.

Fazit

CSS-Transformationen und CSS-Animationen sind zwei leistungsstarke Funktionsgruppen, die reichhaltigere und immersivere Weberfahrungen ermöglichen. In diesem Blogbeitrag wurden wichtige Aspekte beim Verwenden von CSS-Transformationen und CSS-Animationen zur lebhafteren Gestaltung des gesamten Inhalts Ihrer Webseiten erläutert. Mit geringem Aufwand können Sie Webseiten erstellen (sogar statische), die ein flüssiges und beinahe App-ähnliches Navigationsverhalten ermöglichen.

—Charilaos „Harris“ Papadopoulos, Program Manager Intern, Internet Explorer Graphics