Einfache Animationen mit CSS transition

Einfache Animationen mit CSS

Transition ist die Vorstufe zu Animationen – Keyframe-Animationen sind eine Folge von Transitions. Die einfachen »Cross-Fade«-Animationen kommen nie aus der Mode: Wir kennen Sie aus der Fotografie, aus Film und Video.

23-02-02 SITEMAP

Übergänge – CSS Transition starten

Transitions erwachen genauso wie komplexe Animationen durch Events – Ereignisse. Das erste und einfachste Ereignis ist das Laden der Seite. Ohne besondere Einstellungen starten CSS Transitions und Animationen beim Laden der Seite.

Für die Interaktion mit dem Benutzer braucht CSS Transition genauso wie CSS-Keyframe-Animationen zwei Faktoren: ein Element und ein Event, das den Übergang auslöst. Das klassische auslösende Ereignis ist das Hovern mit der Maus oder die Berührung des Fingers auf dem Touchscreen (für das Touch-Event hat CSS nur wenige stabile und breit unterstützte Lösungen).

C S S
<div class="wrap">
   <span class="p1">C</span>
   <span class="p2">S</span>
   <span class="p3">S</span>
</div> 

Das Element, auf dem das hover-Event auslöst, ist <div class="wrap">, aber die Transition findet auf den Pseudo-Elementen .p1:before, .p2:before und .p3:before statt.

.wrap:hover .p1:before, 
.wrap:hover .p2:before, 
.wrap:hover .p3:before {
	width: 100%;
}

.p1, .p2, .p3 {
   color: #fff;
   letter-spacing: 0.1em;
   position: relative;
}

.p1:before, .p2:before, .p3:before {
   position: absolute;
   width: 0%;
   overflow: hidden;
   filter: drop-shadow(5px 5px 5px hsla(0,0%,0%, 0.3));
}
.p1:before {
   content: "C";
   color: salmon;
   -webkit-text-stroke-width: 2px;
   text-stroke-width: 2px;
   -webkit-text-stroke-color: salmon;
   text-stroke-color: salmon;
   transition: 1s;
}
.p2:before {} und .p3:before {} äquivalent zu p1

:hover ist der Haken der Animationen und Transitionen, denn Touchscreens kennen kein hovern mit der Maus. Das Bewegen des Fingers auf dem Screen scrollt die Seite.

text-stroke-color, text-stroke-width

text-stroke-color ist ein typischer Abkömmling des Print-Designs: eine Umrandung der einzelnen Zeichen eines Texts. Dazu muss das CSS die Strichstärke angegeben, z.B. 2px, 0.4em.

Header
.stroked {
	-webkit-text-stroke-color:green;
	text-stroke-color:green;
	-webkit-text-stroke-width:2px;
	text-stroke-width:2px;
}

Dann gibt es auch noch text-fill-color. Auch text-fill-color braucht noch den Präfix -webkit für Chrome, Edge, Opera, Firefox und Safari. Die Textfarbe color ist der Fallback für Browser, die text-fill-color nicht unterstützen.

Unterschied zwischen text-fill-color und color? Allem Anschein nach keiner …

img flip mit Bildwechsel: Vorderseite, Rückseite

Das Bild zeigt beim Hovern die Rückseite – hier muss Javascript den Touch in Gang setzen.

front
back
<div class="flipbox">
   <div class="flipper">
      <div class="front">
         <img src="/css/img/front.jpg" width="600" height="468" alt="front">
      </div>
      <div class="back">
         <img src="/css/img/back.jpg" width="600" height="448" alt="back">
      </div>
   </div>
</div>
Javascript für Touchscreens
<script>
const flipbox = document.querySelector(".flipbox");
flipbox.ontouchstart=this.classList.toggle('hover');
</script>

backface-visibility gibt an, ob die Rückseite eines Elements angezeigt werden soll oder nicht. Die Rückseite ist ein Spiegelbild der Vorderseite und wird beim Rotieren eingesetzt, wenn der Benutzer die Rückseite nicht sehen soll.

perspective wirkt wie die Brennweite einer Kamera: Je kleiner der Wert, desto plastischer oder räumlicher wirkt der Effekt. Bei kleinen Werten scheint das Bild vorn groß, hinten klein. Mit großen Werten wird die Wirkung der Rotation immer flacher.

img { width: 100%; height:auto}

.flipbox {
  perspective: 2000px; 
  max-width: 600px; 
  margin-left:auto; margin-right:auto;
  margin-top: 2em; 
}
.flipbox:hover .flipper, .flipbox.hover .flipper { 
  transform: rotateY(180deg); 
}
.flipbox, .front, .back {
  width: 270px;height: 202px; 
}

/** Für größere Viewports **/
@media (min-width: 640px) {
  .flipbox, .front, .back {
    width: 600px;height: 448px; 
  }
}

.flipper {
  position: relative;
  transition: 1s;
  transform-style: preserve-3d;
}

.front, .back {
  position: absolute;top: 0;left: 0;
  backface-visibility: hidden;
}

.front {transform: rotateY(0deg);}
.back {transform: rotateY(180deg);}

Text mit CSS transition weich über ein Bild legen

CSS transition kann Text beim Hovern weich über einem Bild einblenden. Der Text ist anfangs durch opacity: 0 ausgeblendet und soll mit transition:opacity 1s beim Hovern über das Bild eingeblendet werden.

Der auslösende Faktor ist :hover. Damit das Hovern über das Bild seine Wirkung auf den Text erstreckt, brauchen wir einen Kontext-Selektor: E + F. F ist das HTML-Element, das direkt auf das img-Tag folgt (das div-Element mit dem Text).

<div id="blend">
<img src="image-1.jpg"  />
<div id="lep">Der Veloziraptor</div>
</div>
CSS Transition Slide2
Der Veloziraptor

CSS für das weiche Überblenden

#blend{
   position:relative;
}

#blend ist relativ positioniert, damit es immer so groß wie das Bild. Das Bild ist nicht positioniert, denn sonst würde es seine Größe nicht autziehen.

#blend img {
   width: 100%; 
   height: auto;
   padding: 10px; 
   box-sizing: border-box;
}

#lep – das Element, in dem der Text liegt, ist absolut am unteren Rand von #blend positioniert: position: absolute; bottom: 0;

#lep {
   position:absolute; 
   bottom: 0px;
   background: hsla(0,0%,0%,0.5);
   opacity:0; 
   transition: opacity 1s; 
   width: 100%; 
   text-align:center;
}

#blend img:hover + #lep { 
   opacity: 1
}

Der Trick ist der Kontext-Selektor #blend img:hover + #lep – das Element, das beim Hovern mit der Maus auf das Bild folgt.

Der kleine Effekt hat einen Haken: Auf Touch-Devices gibt es kein hovern mit der Maus und der Effekt muss noch mit Javascript nachgeführt werden.

<script>
var blendimg = document.querySelector("#blend img");
blendimg.ontouchstart = function (eve) {
	eve.preventDefault();
	document.querySelector ("#led").classList.toggle("touchenter");
}
</script>	

Bild über Text einblenden

Das Hovern mit der Maus war schon in CSS 2.1 der Auslöser für die ersten Effekte. Wird das Element, auf dem das Hovern ausgelöst wird, durch eine Einblendung verdeckt, endet das Hovern abrupt, so dass der Effekt gar nicht erst zur Geltung kommt.

Der Auslöser ist darum nicht aus Hovern über dem Text, sondern das anfangs durchsichtige Bild muss das :hover-Ereignis tragen, damit es über dem Text sichtbar wird.

Lohengrin
lohengrin
<div id="lohenbox">
   <div id="lohentext">Lohengrin</div>
   <img id="lohengrin" src="lohengrin.png" width="400" height="400" alt="lohengrin">
</div>
#lohenbox { 
   position:relative; 
   width: 300px; height: 300px;
}

Der Text bekommt einen Hintergrund, damit die Maus einen großen Landeplatz findet. Hier zentriert top: -9999px; bottom: -9999px; margin: auto; den Text in die vertikale Mitte des umfassenden Blocks (wie bei Bilder horizontal und vertikal zentrieren).

#lohentext { 
   width: 100%; 
   height: 80px;
   position: absolute;
   top: -9999px;
   bottom: -9999px;
   margin: auto;
   background: white; 
}

Das Bild liegt im HTML nach dem Text, und weil es absolut positioniert ist, im Viewport durchsichtig (opacity: 0) des Browsers über dem Text.

#lohengrin { 
   width: 100%; height: auto; 
   position: absolute; 
   opacity: 0; 
   transition: opacity 1s; 
}

#lohengrin:hover {
   opacity: 1; 
   transition: opacity 1s;
}

Touchscreens brauchen wieder den Schuss Javascript, denn ein Touch auf dem Touchscreen erzeugt ein anderes Verhalten als das Hovern mit der Maus:

  • Ein Touch auf einen Link wird wie ein Mausklick auf dem Monitor behandelt,
  • eine längere Berührung bedeutet auf dem Touchscreen: Markiere diesen Text zum Kopieren.
  • Die Bewegung des Fingers auf den Touchscreen ist kein Hovern, sondern scrollt die Seite.

Eine 1:1-Übersetzung vom Hovern in Touch-Events gibt es nicht.

<script>
var lohengrin = document.querySelector("#lohengrin");
lohengrin.ontouchstart = function (eve) {
	eve.preventDefault();
	this.classList.add("fragnicht");
}
</script>

Das Script braucht also noch eine weitere CSS-Klasse:

.fragnicht { opacity: 1; }

Das Bild verschwindet nicht, wenn der Finger hochgenommen wird: Ein Touch ist immer nur eine kurze Berührung, ähnlich wie der Klick mit der Maus. In dieser kurzen Zeitspanne würde der Benutzer das eingeblendete Bild gar nicht zu Gesicht bekommen. Das Bild bleibt stehen bis der Benutzer den Touchscreen außerhalb des Bildes berührt.

Touch-Device oder Pointer Device?

Diese Frage können weder CSS noch Javascript immer eindeutig beantworten.

function is_touch_device(){
  return window.matchMedia('(hover: none)').matches;
}

In den modernen Browsern kann CSS allerdings die Weichen für ein Pointer Device stellen: Hier funktioniert hover.

@media (hover: hover) {
	.btn {
		color: blue;
	}
}