Back-to-Top-Aufzug: Teil 2

Wie man eine Aufzugsanimation mit CSS erstellt: Die Animation.
Aufzug in Gitterkasten in einem heruntergekommenen Gebäude. Licht fällt durch die großen Fenster.

Im ersten Teil dieses Projektes haben wir das Grundgerüst für unseren Aufzug erstellt. In diesem Teil wollen wir ihn nun bewegen: Erst lassen wir ihn etwas schaukeln, und dann, wenn man auf ihn klickt, gegen die Decke krachen und abstürzen. Bevor wir loslegen, sprechen wir nochmal kurz über UX und Accessibility.

CSS-Animationen nutzerfreundlich einsetzen

Grundsätzlich sollte man stets bedacht mit plötzlichen und unerwarteten visuellen Reizen auf dem Bildschirm vorgehen. Personen, die an einer vestibulären Erkrankung leiden, reagieren darauf mit Kopfschmerzen, Übelkeit oder sogar Panik. Ähnliches gilt für manche Autisten oder Personen, die an Migräne leiden.

Betroffene können in ihrem Betriebssystem (oder direkt im Firefox-Browser) angeben, dass nicht notwendige Bewegungen wie etwa Animationen reduziert werden sollen. Genaueres könnt ihr hier nachlesen: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion . Dafür müssen wir allerdings die entsprechenden CSS-Regeln in folgender Media Query hinterlegen:

@media (prefers-reduced-motion: reduce) {
  /* Hier CSS mit verringerter oder keiner Bewegung */
}

Es ist ohne Frage super, dass diese Möglichkeit besteht. Allerdings müssen wir im Kopf behalten, dass nicht alle Betroffenen von der Erkrankung oder der Möglichkeit dieser Einstellungen wissen. Zudem ist es natürlich so, dass uns starke oder plötzliche Bewegungen generell ablenken. Im schlimmsten Fall hören Nutzer*innen mitten im Text auf zu lesen, drücken auf den Aufzug und vergessen, wo sie gerade gelesen haben. Oder verlieren das Interesse. Nicht ideal.

Die Beispiele im Folgenden sollten deshalb nicht als Handlungsempfehlung angesehen werden, sondern eher als Inspiration. Lasst den Aufzug vielleicht erst am Ende der Seite schaukeln. Oder verringert die Bewegung. Schaut zudem, wer eure Zielgruppe ist und ob es überhaupt ratsam wäre, den Aufzug überhaupt schaukeln zu lassen.

1. Den Aufzug zum Schwingen bringen

Fangen wir damit an, dass wir unseren Aufzug leicht hin und her schaukeln zu lassen. Dafür erstellen wir eine neue Klasse namens swing_container, die Informationen über die Animation und ihren Ablauf enthält:

.swing_container {
  animation-name: swing;
  /* Dauer in Sekunden: */
  animation-duration: 2s;
  /* Übergänge zwischen Keyframes konfigurieren: */
  animation-timing-function: ease-in-out;
  /* Sekunden zwischen dem Abschluss des Ladevorgangs und dem Start der Animation: */
  animation-delay: 0s;
  /* Anzahl der Wiederholungen: */
  animation-iteration-count: infinite;
  /* Richtung der Animation: */
  animation-direction: alternate;
  /* Zustand der Animation vor oder nach deren Ablauf: */
  animation-fill-mode: none;
}

/* oder zu einer Zeile zusammengefasst: */
.swing_container {
  animation: swing 2s ease-in-out 0s infinite alternate none;
}

Kurz gesagt: Die Animation namens swing soll zwei Sekunden dauern, unendlich oft wiederholt werden und nach Ablauf wieder rückwärts ablaufen.

Nun müssen wir die einzelnen Schritte der Animation hinzufügen. Das passiert mit @keyframes und den jeweiligen Prozentangaben. Damit können wir timen, wann im Ablauf was passieren soll. Für unsere Animation namens swing brauchen wir nur zwei Keyframes:

@keyframes swing {
    0%{ transform: translateX(-0.4rem) rotate(0.3deg); }
  100%{ transform: translateX(0.4rem) rotate(-0.3deg); }
}

Der Ablauf startet mit einer Verschiebung des Elements nach links, in diesem Fall um 0.4rem. Dabei drehen wir mit rotate(0.3deg) den gesamten Aufzug um einen Tick nach rechts. Bis zum Ende, also bei 100% soll der Aufzug um insgesamt 0.8rem nach rechts gewandert sein und auf die andere Seite schwingen. Danach läuft die Animation erst rückwärts ab und startet dann erneut.

Übrigens habe ich hier der Übersichtlichkeit wegen die Browser-Prefixes weggelassen, im Beispiel unten und auf Codepen sind sie aber vorhanden. Sonst wird der Aufzug in den meisten Browsern nichts tun.

Die Klasse swing_container müssen wir jetzt nur noch auf unseren Aufzug anwenden:

var e_box = document.getElementById("elevatorContainer");

window.onscroll = function() { 
  var vh= (window.innerHeight)*0.8;
  if (document.body.scrollTop > vh || document.documentElement.scrollTop > vh) {
    e_box.className = "show swing_container";
  } else {
    e_box.className = "hide";
  }
};

Die Funktion habe ich mit Blick auf den folgenden Abschnitt umgeschrieben, damit der Aufzug nur dann abstürzt, wenn er oben ankommt, und nicht, wenn er höher als 80vh ist.

So sieht unser Aufzug nun aus:

Der Aufzug schaukelt jetzt leicht hin und her.

Und hier der Link zum Aufzug bei CodePen: https://codepen.io/althausme/pen/ExXEEKv

2. Den Aufzug gegen die Decke krachen und fallen lassen

Zwar schwingt der Aufzug jetzt schön hin und her, aber wenn der Button aktiviert wird, scrollt der Browser hoch und der Aufzug ist plötzlich nicht mehr da. Jetzt wollen wir etwas Drama ins Spiel bringen: Wenn der Button aktiviert wird und hochgescrollt wurde, soll der Aufzug hochfliegen, gegen die Decke krachen und abstürzen.

Hierfür benötigen wir zwei Klassen, eine für das Seil und eine für den Aufzug selber. Denn das Seil soll schneller und in eine andere Richtung verschwinden als der Aufzug.

.rope_smash {
  animation: elevator_rope 1.3s linear 0s 1 normal none;
  transform-origin: top;
}

.elevator_smash {
  animation: elevator 1.3s linear 0s 1 normal none;
  transform-origin: top;
}

@keyframes elevator_rope {
    0%{ transform: translateY(0px);}
   20%{ transform: translateY(calc(-78vh + 2.2rem)); }
  100%{ transform: translateY(-200vh); }
}

@keyframes elevator {
     0%{ transform: scale(1, 1); }
    20%{ transform: translateY(calc(-78vh + 2.2rem)); }
    21%{ transform: translateY(calc(-78vh + 2.2rem)) scale(1.25, 0.75); }
   100%{ transform: translateY(200vh) scale(1.25, 0.75) rotate(28deg); }
}

Was passiert hier im Detail?

  • Bei 0 %: Die Animation startet.
  • Bei 20 %: Das Seil und der Aufzug fliegen zusammen hoch.
  • Bei 21 %: Das Seil verändert sich nicht. Die Breite und Höhe des Aufzugs verändern sich durch scale(1.25, 0.75), als würde er wie ein Karton zusammengedrückt.
  • Bei 100 %: Das Seil fliegt nach oben weg, der Aufzug fällt aus dem Bild. Er behält seinen zerdrückten Zustand und dreht sich beim Fallen etwas. Je höher der Wert für translateY ist, umso schneller fällt der Aufzug.

Mehr müssen wir an dieser Stelle gar nicht machen. Nun fügen wir im HTML-Teil unserem elevatorButton noch onclick="runAnimation()" hinzu, damit folgende Funktion abläuft, wenn der Button aktiviert wird:

var e_box = document.getElementById("elevatorContainer");
var e_rope = document.getElementById("elevatorRope");
var e = document.getElementById("elevatorButton");

function runAnimation() {

// Nach oben scrollen, wenn auf den Aufzug geklickt wird:
  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;

// Anschließend die Animationsklassen hinzufügen:
  e_rope.classList.add("rope_smash");
  e.classList.add("elevator_smash");

// Entferne die Klassen und blende die Aufzugsbox aus, wenn die Animation beendet wurde:
  e.addEventListener("animationend", function() {
    e_box.className = "hide";
    e.classList.remove("elevator_smash");
    e_rope.classList.remove("rope_smash");
  });
  e.addEventListener("webkitAnimationEnd", function() {
    e_box.className = "hide";
    e.classList.remove("elevator_smash");
    e_rope.classList.remove("rope_smash");
  });
}

Der Ablauf ist simpel. Zuerst wird hochgescrollt, dann startet die Animation, indem wir die entsprechenden Klassen hinzufügen. Sobald sie enden, entfernen wir die Klassen mit den Animationen wieder und blenden den gesamten Aufzug wieder aus.

Diese Funktion funktioniert übrigens auch ohne Ankerlink, ihr könnt <a href="#top"> also entfernen, wenn ihr möchtet.

Das Ergebnis könnt ihr hier bewundern:

Wenn wir nun auf den Aufzug klicken, knallt er oben an und fällt dann herunter.

Und wie gewohnt auf CodePen: https://codepen.io/althausme/pen/PojQqqd .

Ich wiederhole mich zwar, aber denkt bitte daran, das Ganze noch durch den Autoprefixer zu schicken, um eine breite Browserkompatibilität zu gewährleisten.

Fazit

Natürlich könnte man hier noch viel weiter gehen. Man könnte das Erscheinen des Aufzugs auch animieren, z. B. indem man ihn fallen und stark schwingen lässt oder ihn ruckartig herunterfahren lässt. Oder fügt noch eine Dimension hinzu und macht eine 3-D-Animation daraus. Oder treibt es auf die Spitze und fügt Tim Homans Elevator.js hinzu. Wer mag, kann auch die SVG-Grafik animieren und so z. B. die Türen öffnen und schließen lassen.

Wir haben gesehen, dass Animationen mit wenig Aufwand auch nutzerfreundlich und barrierefrei gestaltet werden können. Ich würde jedoch empfehlen, dem Aufzug auch einen Text zu geben, damit alle Nutzer*innen verstehen, wofür er da ist. Vielleicht möchtet ihr auch ein <noscript> für den Fall integrieren, das JavaScript im Browser blockiert wurde.

Wenn ihr weitere Ideen habt oder einen eigenen Aufzug gebaut habt, schreibt mir gerne eine Nachricht, z. B. auf Twitter .

Weiterlesen: