CINXE.COM

Slider als Keyframe-Animation mit CSS3 - So kommt ohne Javascript Bewegung in die Sache | MODX Revolution

<!DOCTYPE html> <html lang="de" class="no-js"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <base href="https://ebene11.com/" /> <title>Slider als Keyframe-Animation mit CSS3 - So kommt ohne Javascript Bewegung in die Sache | MODX Revolution</title> <meta name="description" content="Ein kleiner Einstieg in die Möglichkeiten der Keyframe-Animationen von CSS3 anhand eines Sliders für beliebigen Inhalt." /> <meta name="viewport" content="width=device-width; initial-scale=1.0" /> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#68b022"> <meta name="msapplication-TileColor" content="#ffffff"> <meta name="theme-color" content="#ffffff"> <link rel="stylesheet" href="assets/minifyx/css/styles_p6a955ac5c1.css" type="text/css"/> <link rel="shortcut icon" type="image/x-icon" href="/assets/files/images/favicon.ico" /> <style type="text/css"> /* Definition der Animationen */ /* 1. Bewegung des Sliders */ @keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @-webkit-keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @keyframes slidesStart101 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @-webkit-keyframes slidesStart101 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @keyframes slidesStart02 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @-webkit-keyframes slidesStart02 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @keyframes slidesStart102 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @-webkit-keyframes slidesStart102 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @keyframes slidesStart03 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @-webkit-keyframes slidesStart03 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @keyframes slidesStart103 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @-webkit-keyframes slidesStart103 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @keyframes slidesStart04 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @-webkit-keyframes slidesStart04 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @keyframes slidesStart104 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @-webkit-keyframes slidesStart104 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } /* 2. Wechsel des ersten Slides ans Ende und zurück */ @keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @-webkit-keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @keyframes slide01ToEndStart101 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @-webkit-keyframes slide01ToEndStart101 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @keyframes slide01ToEndStart02 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @-webkit-keyframes slide01ToEndStart02 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @keyframes slide01ToEndStart102 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @-webkit-keyframes slide01ToEndStart102 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @keyframes slide01ToEndStart03 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @-webkit-keyframes slide01ToEndStart03 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @keyframes slide01ToEndStart103 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @-webkit-keyframes slide01ToEndStart103 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @keyframes slide01ToEndStart04 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @-webkit-keyframes slide01ToEndStart04 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @keyframes slide01ToEndStart104 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @-webkit-keyframes slide01ToEndStart104 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } /* 3. Animationen für den Farbwechsel in den Controls */ @keyframes slideControl01 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @-webkit-keyframes slideControl01 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @keyframes slideControl101 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @-webkit-keyframes slideControl101 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @keyframes slideControl02 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @-webkit-keyframes slideControl02 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @keyframes slideControl102 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @-webkit-keyframes slideControl102 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @keyframes slideControl03 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @-webkit-keyframes slideControl03 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @keyframes slideControl103 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @-webkit-keyframes slideControl103 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @keyframes slideControl04 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @-webkit-keyframes slideControl04 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @keyframes slideControl104 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @-webkit-keyframes slideControl104 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } /* Basisfunktionalität des Sliders */ .slider { overflow: hidden; } .slider input { position: absolute; left: -10000px; top: 0; } .slideList { width: 400%; /* Anzahl der Slides mal 100 */ position: relative; /* über die relative Positionierung wird der Slider durchs Sichtfenster geschoben */ -webkit-transition: left 2s; -moz-transition: left 2s; -o-transition: left 2s; transition: left 2s; /* für den fließenden Schub */ margin: 0; padding: 0; } .slideList:after { content: "."; display: block; height: .1px; clear: both; visibility: hidden; font-size: 0; overflow: hidden; } .slide { list-style: none; width: 25%; /* Breite gleich 100 / Anzahl Slides */ float: left; position: relative; left: 0; -webkit-transition: left 0s .5s; -moz-transition: left 0s .5s; -o-transition: left 0s .5s; transition: left 0s .5s; /*bei Klick auf ein Control werden alle Slides wieder auf Original-Position geschoben, hier für den ersten relevant. Damit die Aktion erst nach der slides-Verschiebung beginnt, kommt ein delay hinzu*/ } #slide04:checked ~ .slideList .slide, #slide104:checked ~ .slideList .slide { -webkit-transition-delay: 2s; -moz-transition-delay: 2s; -o-transition-delay: 2s; transition-delay: 2s; /* damit er nicht zu früh zurückrutscht */ } .slideList img { width: 100%; height: auto; vertical-align: bottom; } /* Zuweisung der Keyframe-Animationen */ .slideList, .slide, .slideControl label { -webkit-animation: 20s 2s infinite; animation: 20s 2s infinite; /* allgemeingültige Werte für die Keyframe-Animation */ } /* Positionierung und Aufruf der passenden Animation in Abhängigkeit des Status der Radiobuttons */ #slide01:checked ~ .slideList { -webkit-animation-name: slidesStart01; animation-name: slidesStart01; left: 0; } #slide02:checked ~ .slideList { -webkit-animation-name: slidesStart02; animation-name: slidesStart02; left: -100%; } #slide03:checked ~ .slideList { -webkit-animation-name: slidesStart03; animation-name: slidesStart03; left: -200%; } #slide04:checked ~ .slideList { -webkit-animation-name: slidesStart04; animation-name: slidesStart04; left: -300%; } /* Damit der Wechsel von 01 zu 101, 02 zu 102 usw. klappt, muss jeweils eine andere Animation aufgerufen werden*/ #slide101:checked ~ .slideList { -webkit-animation-name: slidesStart101; animation-name: slidesStart101; left: 0; } #slide102:checked ~ .slideList { -webkit-animation-name: slidesStart102; animation-name: slidesStart102; left: -100%; } #slide103:checked ~ .slideList { -webkit-animation-name: slidesStart103; animation-name: slidesStart103; left: -200%; } #slide104:checked ~ .slideList { -webkit-animation-name: slidesStart104; animation-name: slidesStart104; left: -300%; } /* Der erste Slide wird jeweils zur rechten Zeit an den Anfang oder das Ende gestellt */ #slide01:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart01; animation-name: slide01ToEndStart01; } #slide02:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart02; animation-name: slide01ToEndStart02; } #slide03:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart03; animation-name: slide01ToEndStart03; } #slide04:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart04; animation-name: slide01ToEndStart04; } /* Separate Animations-Namen für die zweite Steuerung */ #slide101:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart101; animation-name: slide01ToEndStart101; } #slide102:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart102; animation-name: slide01ToEndStart102; } #slide103:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart103; animation-name: slide01ToEndStart103; } #slide104:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart104; animation-name: slide01ToEndStart104; } /* nur zur Deko */ .sliderWrapper { position: relative; padding: 6px; border: 1px solid #ddd; margin-bottom: 40px; } .slide p { position: absolute; bottom: 1em; left: 0; background: rgba(0, 0, 0, .6); color: #ddd; padding: .4em 1em; } /* Steuerung durch den Benutzer */ .slideControl { width: 80px; position: absolute; bottom: -40px; left: 50%; margin-left: -40px; padding: 0; } .control01:checked ~ .slideControl01, .control02:checked ~ .slideControl02 { left: -5000px; /* Blendet die nicht benötigten Labels aus */ } .slideControl li { float: left; margin: 0 4px; width: 10px; height: 10px; border-radius: 50%; position: relative; text-indent: -10000px; border: 1px solid #ccc; box-shadow: 0 0 2px 2px #ccc; list-style: none; } .slideControl label { display: block; cursor: pointer; background: none; width: 100%; height: 100%; border-radius: 50%; box-sizing: border-box; border: 2px solid #fff; } .slideControl label:hover { background: #68b022!important; } #slide01:checked ~ .slideControl label[for="slide101"], #slide02:checked ~ .slideControl label[for="slide102"], #slide03:checked ~ .slideControl label[for="slide103"], #slide04:checked ~ .slideControl label[for="slide104"] { -webkit-animation-name: slideControl01; animation-name: slideControl01; background: #68b022; } #slide101:checked ~ .slideControl label[for="slide01"], #slide102:checked ~ .slideControl label[for="slide02"], #slide103:checked ~ .slideControl label[for="slide03"], #slide104:checked ~ .slideControl label[for="slide04"] { -webkit-animation-name: slideControl101; animation-name: slideControl101; background: #68b022; } #slide01:checked ~ .slideControl label[for="slide102"], #slide02:checked ~ .slideControl label[for="slide103"], #slide03:checked ~ .slideControl label[for="slide104"], #slide04:checked ~ .slideControl label[for="slide101"] { -webkit-animation-name: slideControl02; animation-name: slideControl02; } #slide101:checked ~ .slideControl label[for="slide02"], #slide102:checked ~ .slideControl label[for="slide03"], #slide103:checked ~ .slideControl label[for="slide04"], #slide104:checked ~ .slideControl label[for="slide01"] { -webkit-animation-name: slideControl102; animation-name: slideControl102; } #slide01:checked ~ .slideControl label[for="slide103"], #slide02:checked ~ .slideControl label[for="slide104"], #slide03:checked ~ .slideControl label[for="slide101"], #slide04:checked ~ .slideControl label[for="slide102"] { -webkit-animation-name: slideControl03; animation-name: slideControl03; } #slide101:checked ~ .slideControl label[for="slide03"], #slide102:checked ~ .slideControl label[for="slide04"], #slide103:checked ~ .slideControl label[for="slide01"], #slide104:checked ~ .slideControl label[for="slide02"] { -webkit-animation-name: slideControl103; animation-name: slideControl103; } #slide01:checked ~ .slideControl label[for="slide104"], #slide02:checked ~ .slideControl label[for="slide101"], #slide03:checked ~ .slideControl label[for="slide102"], #slide04:checked ~ .slideControl label[for="slide103"] { -webkit-animation-name: slideControl04; animation-name: slideControl04; } #slide101:checked ~ .slideControl label[for="slide04"], #slide102:checked ~ .slideControl label[for="slide01"], #slide103:checked ~ .slideControl label[for="slide02"], #slide104:checked ~ .slideControl label[for="slide03"] { -webkit-animation-name: slideControl104; animation-name: slideControl104; } </style> <script src="/assets/components/syntaxhighlighter/scripts/shCore.js"></script> <script src="/assets/components/syntaxhighlighter/scripts/shBrushCss.js"></script> <script src="/assets/components/syntaxhighlighter/scripts/shBrushXml.js"></script> <link rel="stylesheet" href="/assets/components/syntaxhighlighter/css/core.css" type="text/css" /> <link rel="stylesheet" href="/assets/components/syntaxhighlighter/css/theme/Default.css" type="text/css" /> </head> <body id="slider-als-keyframe-animation-mit-css3" class="blogArticle"> <header class="pageHeader"> <h1> <a href="/"><svg width="200" height="25" viewBox="0 0 200 25" class="logo"> <defs> <style type="text/css"> <![CDATA[ path, circle { fill: #121212; } .inner { fill: #fff; } #charEsuper, #charLsuper, #charFsuper path, #charFsuper circle{ fill: #68b022; } ]]> </style> <symbol> <path id="charE" d=" M 27.5,0 h -19 c -2.7,0 -4.8,-.8 -6.3,-2.3 c -1.4,-1.6 -2.1,-3.7 -2.1,-6.5 c 0,-2.8 .7,-4.9 2.2,-6.5 c 1.4,-1.6 3.5,-2.3 6.3,-2.3 h 19 v 4 h -18.4 c -1,.1 -1.8,.4 -2.4,.9 c -.3,.3 -0.7,.8 -1.1,1.9 h 21.9 v 4 h -21.9 c .4,1.1 .8,1.6 1.1,1.9 c .6,.5 1.4,.8 2.4,.9 h 18.4 z " /> </symbol> <symbol> <g id="charB"> <path d=" M 0,0 v -24.6 h 5.3 v 7 h 16.9 c 3.6,0 6,1.3 7.4,4 c .7,1.3 1,2.9 1,4.8 c 0,3.8 -1.3,6.4 -3.9,7.8 c -1.3,.7 -2.9,1 -4.6,1 z " /> <path class="inner" d=" M 5.3,-4.4 v -8.8 h 16.1 c 1.2,0 2.2,.4 2.9,1.3 c .5,.8 .8,1.8 .8,3.1 c 0,1.3 -.2,2.3 -.8,3.1 c -.7,.9 -1.6,1.3 -2.8,1.3 z " /> </g> </symbol> <symbol> <path id="charN" d=" M 0,0 v -17.6 h 21.7 c 2.1,0 3.7,.6 4.8,1.7 c 1,1.1 1.5,2.3 1.5,3.7 v 12.2 h -5.3 v -11.4 c 0,-1.2 -.6,-1.8 -1.8,-1.8 h -15.6 v 13.2 z " /> </symbol> <symbol> <path id="charEsuper" d=" M 11.7,0 h -8.1 c -1.2,0 -2.1,-.3 -2.7,-1 c -.6,-.7 -.9,-1.6 -.9,-2.8 c 0,-1.2 .3,-2.1 .9,-2.8 c .6,-.7 1.5,-1 2.7,-1 h 8.1 v 1.8 h -7.8 c -.4,0 -.8,.1 -1,.4 c -.1,.1 -.3,.4 -.5,.8 h 9.3 v 1.6 h -9.3 c .2,.4 .4,.7 .5,.8 c .2,.3 .6,.4 1,.4 h 7.8 z " /> </symbol> <symbol> <path id="charLsuper" d=" M 11.1,0 h -7.6 c -1.7,0 -2.8,-.7 -3.3,-2.1 c -.1,-.6 -.2,-1.2 -.2,-1.8 v -3.7 h 2.4 v 3.5 c 0,.6 .2,1 .5,1.4 c .3,.3 .7,.4 1.2,.4 h 7 z " /> </symbol> <symbol> <g id="charFsuper"> <path d=" M 0,0 v -3.7 c 0,-.6 .1,-1.2 .2,-1.8 c .5,-1.4 1.6,-2.1 3.3,-2.1 h 7.6 v 2.3 h -7 c -.5,0 -.9,.1 -1.2,.4 c -.3,.4 -.5,.8 -.5,1.4 v 3.5 z " /> <circle cx="4.9" cy="-2" r="1.2" /> </g> </symbol> </defs> <use xlink:href="#charE" x="0" y="25" /> <use xlink:href="#charB" x="32" y="25" /> <use xlink:href="#charE" x="66" y="25" /> <use xlink:href="#charN" x="99" y="25" /> <use xlink:href="#charE" x="132" y="25" /> <use xlink:href="#charEsuper" x="163" y="8" /> <use xlink:href="#charLsuper" x="176" y="8" /> <use xlink:href="#charFsuper" x="189" y="8" /> </svg></a> <span>Webentwicklung . AutoCAD . Schulung</span> </h1> <nav class="navigationMain"> <h2>Navigation</h2> <label for="toggleNavigationMain" class="toggleNavigationMain"> <svg width="70" height="50" viewBox="0 0 70 50" class="burger"> <path d=" M5 10 l60 0 M5 25 l60 0 M5 40 l60 0 " /> </svg> </label> <input id="toggleNavigationMain" name="toggleNavigationMain" type="checkbox" /> <ul class="navigationList"><li class="first level1 cat2"><a href="leistungen" >Leistungen</a></li><li class=" level1 cat3"><a href="portfolio/" >Portfolio</a></li><li class="active level1 cat4"><a href="blog/" >Blog</a></li><li class="last level1 cat5"><a href="kontakt" >Kontakt</a></li></ul> </nav> </header> <article id="content"> <header> <h2 class="articleHeader">Slider als Keyframe-Animation mit CSS3 <span>So kommt ohne Javascript Bewegung in die Sache</span></h2> <p>Mit den @keyframes-Regeln von CSS3 stehen Werkzeuge zur Verfügung, die Darstellung von Inhalten einer Website zeitgesteuert zu verändern. Um die Möglichkeiten sowie die Vor- und Nachteile im Vergleich zum Einsatz von Javascript etwas näher zu untersuchen, wird hier der Ansatz aus <a href="imageslider-ohne-javascript">Imageslider ohne Javascript</a> weiterverfolgt und der Slider um einen zeitgesteuerten Ablauf ergänzt.</p> </header> <aside class="blogData"> <dl> <dt>Datum</dt> <dd>11.08.2014</dd> <dt>Kategorie</dt> <dd><a href="css/">CSS</a></dd> <dt>Schlagworte</dt> <dd class="tag">CSS3</dd><dd class="tag">Checkbox-Hack</dd><dd class="tag">Keyframe-Animation</dd><dd class="tag">Slider</dd><dd class="tag">Transition</dd> </dl> </aside> <section class="blogArticleContent"> <figure> <img src="assets/files/images/hero/css3AnimationSliderEC.jpg" alt="Konzeptskizze für einen CSS-Slider" width="1200" height="400" class="responsive" /> <figcaption> </figcaption> </figure> <h3>Grundlagen - was sind Keyframe-Animationen</h3> <p>Keyframe-Animationen bieten die Möglichkeit, die Darstellung von HTML-Elementen über eine Zeitspanne hinweg zu verändern. Es lassen sich beliebig viele Zwischenstufen der Darstellung (Keyframes) definieren, der Browser berechnet die Übergänge dazwischen - es entsteht Bewegung.</p> <p>Wir brauchen also zweierlei Dinge:</p> <ol> <li>Die Definition der Darstellung eines Elements zu verschiedenen Zeitpunkten</li> <li>Die Zuweisung der Definition (inkl. Angaben zum Ablauf) zu einem Element</li> </ol> <h4>Keyframe-Animationen definieren</h4> <p>Im einfachsten Fall wird ein Start- und ein Endzustand definiert, es können aber auch beliebig viele Zwischenstufen (Keyframes) eingefügt werden. Für jeden Keyframe kann man beliebigen CSS-Eigenschaften (diese sollten natürlich animierbar sein) Werte zuweisen. Allgemein ausgedrückt sieht eine Animation wie folgt aus:</p> <pre class="brush: css; toolbar: false;"> @keyframes nameDerAnimation { x% { Eigenschaft01: Wert; Eigenschaft02: Wert; } y% { Eigenschaft01: Wert; Eigenschaft02: Wert; } z% { Eigenschaft01: Wert; Eigenschaft02: Wert; } } </pre> <p>Derzeit werden Vendor-Präfixe für webkit-basierte Browser noch benötigt, sind hier zur besseren Lesbarkeit jedoch nicht aufgeführt.</p> <h4>Zuweisung einer Animation</h4> <p>Eine Animation lässt sich über folgende CSS-Eigenschaften steuern</p> <ul class="contentList" lang="en"> <li><code>animation-name</code></li> <li><code>animation-duration</code></li> <li><code>animation-timing-function</code></li> <li><code>animation-iteration-count</code></li> <li><code>animation-direction</code></li> <li><code>animation-play-state</code></li> <li><code>animation-delay</code></li> <li><code>animation-fill-mode</code></li> </ul> <p>Essentiell sind der Name und die Dauer der Animation. In Kurzschreibweise lassen sich diese Eigenschaften unter <code lang="en">animation</code> zusammenfassen. Die Zuweisung einer Animation zu einem Element E sieht also mindestens wie folgt aus:</p> <pre class="brush: css; toolbar: false;"> E { animation: name duration; } </pre> <p>Einen Überblick über die verschiedenen Eigenschaften und mögliche Werte findet sich unter <a href="http://www.w3.org/TR/css3-animations/" target="blank">http://www.w3.org/TR/css3-animations/</a>. Auch hier werden die Vendor-Präfixe für die Unterstützung der Webkit-Browser noch benötigt.</p> <h3>Slider - Grundfunktion</h3> <p>Nehmen wir uns den angestrebten Slider vor. Dieser besteht in Sachen HTML, wie in <a href="mainova-ag">Mainova AG</a> beschrieben, aus einer unsortierten Liste für die Slides und Radiobuttons sowie zugehörige Labels zur Steuerung. Der prinzipielle Aufbau des Codes, angereichert mit ein paar zusätzlichen Klassen, die im weiteren Verlauf das Leben leichter machen:</p> <pre class="brush: html; toolbar: false;"> <div class="slider"> <input type="radio" name="slider" class="control" id="slide01" /> <input type="radio" name="slider" class="control" id="slide02" /> … <ul class="slideList"> <li class="slide slide01"></li> <li class="slide slide02"></li> … </ul> <ul class="slideControl"> <li><label for="slide01">1</label></li> <li><label for="slide02">2</label></li> … </ul> </div> </pre> <p>Die einzelnen Slides sind gefloatet, die Position der Liste soll sich je Schritt (Keyframe) um die Breite eines Listenpunktes im Sichtfenster weiterschieben. In der Annahme, dass der Slider aus vier Slides besteht, hat jeder Slide genau 25% der gesamten Zeit der Animation zur Verfügung. Diese Zeit teilt sich dann nochmal in die Standzeit (hier 15%) und die Animationszeit (hier 10%) eines Slides. Die Notation der Animation sieht demnach wie folgt aus:</p> <pre class="brush: css; toolbar: false;"> @keyframes slider { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } .slideList { animation-name: slider; animation-duration: 20s; animation-delay: 2s; animation-iteration-count: infinite; } </pre> <p>Die Angaben kann man natürlich in Kurzschreibweise notieren (s.u.), sind hier jedoch zur besseren Lesbarkeit ausgeschrieben. Notwendige Eigenschaften sind in diesem Fall der Name der Animation, die Dauer und die Wiederholung. Die Verzögerung wird nötig, da bei manueller Steuerung der Slider langsam verschoben wird, die Animation also erst starten darf, wenn die Verschiebung abgeschlossen ist.</p> <p>Bauen wir die Animation in dieser Form, wird, wie nicht anders zu erwarten, im letzten Schritt der Slider komplett ins Nirwana (-400%) geschoben, es bleibt also nur noch Luft im Sichtfenster übrig. Wir brauchen demzufolge noch eine Möglichkeit, statt dieser Luft den ersten Slide noch einmal zu sehen, bevor die Animation wieder von vorne startet.</p> <h4>Die Luft ist raus</h4> <p>Die Idee ist eigentlich ganz simpel. Wir definieren für den ersten Slide eine weitere Keyframe-Animation, die diesen unmittelbar bevor der letzte Verschub des Sliders stattfindet (bei 90%), nahtlos an seinem Ende anfügt. Danach starten beide Animationen wieder von vorne und es entsteht der Eindruck eines Endlosbandes. Die Stylesheet-Anweisungen dazu:</p> <pre class="brush: css; toolbar: false;"> @keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } .slide { position: relative; } .slide01 { animation: slide01ToEndStart01 20s 2s infinite; } </pre> <p>Damit haben wir einen voll funktionstüchtigen Slider, allerdings noch ohne Steuerelemente. Diese kommen im nächsten Schritt.</p> <h3>Steuerungsmöglichkeit für den Benutzer</h3> <p>Die Steuerelemente funktionieren vom Prinzip identisch zu dem in <a href="mainova-ag">Mainova AG</a> beschriebenen Szenario über die Pseudoklasse <code>:checked</code> (<i class="properName">Checkbox-Hack</i>). Diese Variante läuft auch hier prima, allerdings stolpern wir über das Problem, dass die einmal zugewiesene Animation ohne Unterlass weiterläuft. D.h. bei Klick auf einen Radiobutton rutscht der Slider zwar kurz zur passenden Position, aber dann greift direkt wieder die bei Seitenaufruf gestartete Animation und es wird zum nächsten Keyframe in ihrem Ablauf gesprungen. Zu verhindern wäre dies, wenn nach jeder Wahl eines Radiobuttons (also dem Sprung zu einem bestimmten Slide) die Animation bei eben diesem Slide wieder von vorne losläuft. Da es keine Möglichkeit gibt, einen anderen Startpunkt als 0 für eine Animation zu definieren, bleibt nur übrig, jeweils eine separate Keyframe-Animation zu erstellen und diese in Abhängigkeit des Status der Radiobuttons zuzuweisen. Das könnte dann wie folgt aussehen:</p> <pre class="brush: css; toolbar: false;"> @keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @keyframes slidesStart02 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @keyframes slidesStart03 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @keyframes slidesStart04 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } .slideList{ animation: 20s 2s infinite; transition: left 2s; } #slide01:checked ~ .slideList { animation-name: slidesStart01; left: 0; } #slide02:checked ~ .slideList { animation-name: slidesStart02; left: -100%; } #slide03:checked ~ .slideList { animation-name: slidesStart03; left: -200%; } #slide04:checked ~ .slideList { animation-name: slidesStart04; left: -300%; } </pre> <p>Soweit, so gut - aber drei Problemstellen gibt es noch. Erstens muss der erste Slide passend zur jeweils aktiven Animation des Sliders verschoben werden, zweitens lässt sich nicht noch einmal zum aktuell ausgewählten Slide springen und drittens sollten sich die Kontrollelemente natürlich auch dem Status der Animation anpassen.</p> <h4>Position des ersten Slides</h4> <p>Da die Animation jeweils bei einem anderen Slide startet, müssen wir für den ersten Slide weitere Keyframe-Animationen anlegen, damit er zum jeweils passenden Zeitpunkt verschoben wird.</p> <pre class="brush: css; toolbar: false;"> @keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @keyframes slide01ToEndStart02 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @keyframes slide01ToEndStart03 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @keyframes slide01ToEndStart04 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } #slide01:checked ~ .slideList .slide01 { animation-name: slide01ToEndStart01; } #slide02:checked ~ .slideList .slide01 { animation-name: slide01ToEndStart02; } #slide03:checked ~ .slideList .slide01 { animation-name: slide01ToEndStart03; } #slide04:checked ~ .slideList .slide01 { animation-name: slide01ToEndStart04; } </pre> <p>Doch damit nicht genug. Es kann passieren, das wir in dem Moment manuell zu einem anderen Slide springen, in dem der erste Slide schon durch die Animation verschoben wurde. Die Position muss also bei Klick auf einen Steuerelement wieder auf Null gesetzt werden. Da der gesamte Slider jedoch langsam verschoben wird (Transition), darf der erste Slide nicht sofort zurückgesetzt werden, sondern mit einer entsprechenden Verzögerung. Diese wird per <code>transition-delay</code> gesteuert:</p> <pre class="brush: css; toolbar: false;"> .slide { transition: left 0s .5s; } #slide04:checked ~ .slideList .slide { transition-delay: 2s; } </pre> <h4>Volle Kontrolle</h4> <p>Der aktuell markierte Slide kann bis jetzt nicht wieder angewählt werden. Ist auch logisch, da die Animation nicht den Zustand der Radiobuttons steuert, der einmal gewählte also so lange ausgewählt bleibt, bis man einen anderen anklickt. Ein erneuter Klick auf einen ausgewählten Radiobutton löst keine neue Animation aus. Wenn man mit dieser Einschränkung nicht leben möchte, kann man mit einer doppelten Steuerung arbeiten. Die Idee ist, die Anzahl der Radiobuttons zu verdoppeln und die beiden Hälften mit zwei getrennten Zusammenstellungen von Labels zu steuern. Durch die Trennung, lassen sich die beiden Labelgruppen jeweils wechselseitig sichtbar schalten - ist ein zur ersten Steuerung zugehöriger Radiobutton ausgewählt, wird die zweite Gruppe von Labeln angezeigt und umgekehrt. Wir brauchen also etwas zusätzlichen HTML-Code:</p> <pre class="brush: html; toolbar: false;"> <div class="slider"> <input type="radio" name="slider" id="slide01" /> <input type="radio" name="slider" id="slide02" /> … <input type="radio" name="slider" id="slide101" /> <input type="radio" name="slider" id="slide102" /> … <ul class="slideList"> <li class="slide slide01"></li> <li class="slide slide02"></li> … </ul> <ul class="slideControl slideControl01"> <li><label for="slide01">01</label></li> <li><label for="slide02">02</label></li> … </ul> <ul class="slideControl slideControl02"> <li><label for="slide101">101</label></li> <li><label for="slide102">102</label></li> … </ul> </div> </pre> <p>Dieses zusätzliche Markup zieht einen Rattenschwanz an weiteren Stylesheets nach sich. Da bei jedem Klick auf ein Label, die zugehörige Animation von vorne starten muss, können wir den Buttons der zweiten Gruppe nicht die gleichen Animationen zuordnen. Folgendes reicht leider nicht:</p> <pre class="brush: css; toolbar: false;"> #slide01:checked ~ .slideList, #slide101:checked ~ .slideList { animation-name: slidesStart01; left: 0; } </pre> <p>Es müssen die gleichen Animationen unter einem neuen Namen angelegt und separat aufgerufen werden - z.B. so:</p> <pre class="brush: css; toolbar: false;"> @keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } #slide01:checked ~ .slideList { animation-name: slidesStart01; left: 0; } @keyframes slidesStart101 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } #slide101:checked ~ .slideList { animation-name: slidesStart101; left: 0; } </pre> <p>Analog hierzu wird der gleiche Schritt auch für die Animationen, die den ersten Slide ans Ende schieben, notwendig.</p> <h4>Hervorhebung der Labels</h4> <p>Zur Kennzeichnung des zum jeweils ausgewählten Radiobuttons zugehörigen Labels werden ebenfalls Keyframe-Animationen definiert. Hier muss wie bereits gewohnt für jeden Startpunkt wieder eine separate Definition erstellt werden, was dann für die erste Labelgruppe wie folgt aussehen kann:</p> <pre class="brush: css; toolbar: false;"> @keyframes slideControl01 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @keyframes slideControl02 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @keyframes slideControl03 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @keyframes slideControl04 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } .slideControl label { animation: 20s 2s infinite; } #slide01:checked ~ .slideControl label[for="slide01"], #slide02:checked ~ .slideControl label[for="slide02"], #slide03:checked ~ .slideControl label[for="slide03"], #slide04:checked ~ .slideControl label[for="slide04"] { animation-name: slideControl01; background: #68b022; } #slide01:checked ~ .slideControl label[for="slide02"], #slide02:checked ~ .slideControl label[for="slide03"], #slide03:checked ~ .slideControl label[for="slide04"], #slide04:checked ~ .slideControl label[for="slide01"] { animation-name: slideControl02; } #slide01:checked ~ .slideControl label[for="slide03"], #slide02:checked ~ .slideControl label[for="slide04"], #slide03:checked ~ .slideControl label[for="slide01"], #slide04:checked ~ .slideControl label[for="slide02"] { animation-name: slideControl03; } #slide01:checked ~ .slideControl label[for="slide04"], #slide02:checked ~ .slideControl label[for="slide01"], #slide03:checked ~ .slideControl label[for="slide02"], #slide04:checked ~ .slideControl label[for="slide03"] { animation-name: slideControl04; } </pre> <p>Die zweite Gruppe wird analog gesteuert und die Sichtbarkeit der Gruppen über die Positionierung mit folgendem Code geregelt:</p> <pre class="brush: css; toolbar: false;"> .control01:checked ~ .slideControl01, .control02:checked ~ .slideControl02 { left: -5000px; } </pre> <p>Damit ist man durch und hat einen komplett funktionstüchtigen Slider inkl. Steuerelemente für beliebige Inhalte, der ohne eine Zeile Javascript auskommt.</p> <h3>Fazit</h3> <p>Man kann mittlerweile eine rein CSS-basierte Lösung für Slider und ähnliche Bausteine schreiben, die sogar von den meisten Browsern verstanden wird, d.h. mit Vendor-Präfix kommt so ziemlich jeder moderne Browser damit klar. Eine ausführliche Übersicht, welche Browser Keyframe-Animationen unterstützen gibt es auf <a href="http://caniuse.com/#feat=css-animation" target="blank">caniuse.com</a>.</p> <p>Unbestritten ist sicherlich der Mehraufwand, im Vergleich zur Verwendung einer fertigen (Javascript-)Lösung. Wobei man die dem CSS-Code zugrundeliegende Logik natürlich auch mit einer beliebigen Programmiersprache abbilden und ihn so automatisch erzeugen lassen kann.</p> <p>Andere Verhalten, als der Verschub von rechts nach links (Überblendungen, Drehungen, Skalierungen etc.) lassen sich über die Manipulation der entsprechenden CSS-Eigenschaften natürlich problemlos bauen.</p> </section> <section class="sample tabs"> <h2 id="demo">So sieht es aus</h2> <input id="tabNaviHtml" type="radio" name="tabNavi" class="invisible" /> <label for="tabNaviHtml">HTML</label> <input id="tabNaviCss" type="radio" name="tabNavi" class="invisible" /> <label for="tabNaviCss">CSS</label> <input id="tabNaviResult" type="radio" name="tabNavi" checked="checked" class="invisible" /> <label for="tabNaviResult">Resultat</label> <section class="tabHtml"> <pre class="brush: html; toolbar: false;"> <div class="sliderWrapper"> <div class="slider"> <input type="radio" name="slider" class="control01" id="slide01" checked="checked" /> <input type="radio" name="slider" class="control01" id="slide02" /> <input type="radio" name="slider" class="control01" id="slide03" /> <input type="radio" name="slider" class="control01" id="slide04" /> <input type="radio" name="slider" class="control02" id="slide101" /> <input type="radio" name="slider" class="control02" id="slide102" /> <input type="radio" name="slider" class="control02" id="slide103" /> <input type="radio" name="slider" class="control02" id="slide104" /> <ul class="slideList"> <li class="slide slide01"> <img src="assets/files/images/portfolio/dgKegelschnitte.jpg" alt="" width="600" height="400" /> <p>Kegelschnitte</p> </li> <li class="slide slide02"> <img src="assets/files/images/portfolio/dgMassaufgaben.jpg" alt="Maßaufgaben" width="600" height="400" /> <p>Maßaufgaben</p> </li> <li class="slide slide03"> <img src="assets/files/images/portfolio/dgWuerfelkomposition.jpg" alt="Würfelkomposition" width="600" height="400" /> <p>Würfelkomposition</p> </li> <li class="slide slide04"> <img src="assets/files/images/portfolio/dgZylinderHyperboloid.jpg" alt="Schnitt Zylinder - Hyperboloid" width="600" height="400" /> <p>Schnittkurve von Zylinder und Hyperboloid</p> </li> </ul> <ul class="slideControl slideControl01"> <li><label for="slide01">Nummer 1</label></li> <li><label for="slide02">Nummer 2</label></li> <li><label for="slide03">Nummer 3</label></li> <li><label for="slide04">Nummer 4</label></li> </ul> <ul class="slideControl slideControl02"> <li><label for="slide101">Nummer 101</label></li> <li><label for="slide102">Nummer 102</label></li> <li><label for="slide103">Nummer 103</label></li> <li><label for="slide104">Nummer 104</label></li> </ul> </div> </div> </pre> </section> <section class="tabCss"> <pre class="brush: css; toolbar: false;"> /* Definition der Animationen */ /* 1. Bewegung des Sliders */ @keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @-webkit-keyframes slidesStart01 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @keyframes slidesStart101 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @-webkit-keyframes slidesStart101 { 0%, 15% {left: 0;} 25%, 40% {left: -100%;} 50%, 65% {left: -200%;} 75%, 90% {left: -300%;} 100% {left: -400%;} } @keyframes slidesStart02 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @-webkit-keyframes slidesStart02 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @keyframes slidesStart102 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @-webkit-keyframes slidesStart102 { 90.01% {left: 0;} 0%, 15%, 100% {left: -100%;} 25%, 40% {left: -200%;} 50%, 65% {left: -300%;} 75%, 90% {left: -400%;} } @keyframes slidesStart03 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @-webkit-keyframes slidesStart03 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @keyframes slidesStart103 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @-webkit-keyframes slidesStart103 { 65.01% {left: 0;} 0%, 15%, 100% {left: -200%;} 25%, 40% {left: -300%;} 50%, 65% {left: -400%;} 75%, 90% {left: -100%;} } @keyframes slidesStart04 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @-webkit-keyframes slidesStart04 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @keyframes slidesStart104 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } @-webkit-keyframes slidesStart104 { 40.01% {left: 0;} 0%, 15%, 100% {left: -300%;} 25%, 40% {left: -400%;} 50%, 65% {left: -100%;} 75%, 90% {left: -200%;} } /* 2. Wechsel des ersten Slides ans Ende und zurück */ @keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @-webkit-keyframes slide01ToEndStart01 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @keyframes slide01ToEndStart101 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @-webkit-keyframes slide01ToEndStart101 { 89.99% {left: 0;} 90%, 100% {left: 100%;} } @keyframes slide01ToEndStart02 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @-webkit-keyframes slide01ToEndStart02 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @keyframes slide01ToEndStart102 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @-webkit-keyframes slide01ToEndStart102 { 49.99%, 90.01% {left: 0;} 50%, 90% {left: 100%;} } @keyframes slide01ToEndStart03 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @-webkit-keyframes slide01ToEndStart03 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @keyframes slide01ToEndStart103 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @-webkit-keyframes slide01ToEndStart103 { 24.99%, 65.01% {left: 0;} 25%, 65% {left: 100%;} } @keyframes slide01ToEndStart04 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @-webkit-keyframes slide01ToEndStart04 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @keyframes slide01ToEndStart104 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } @-webkit-keyframes slide01ToEndStart104 { 40.01% {left: 0;} 0%, 40% {left: 100%;} } /* 3. Animationen für den Farbwechsel in den Controls */ @keyframes slideControl01 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @-webkit-keyframes slideControl01 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @keyframes slideControl101 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @-webkit-keyframes slideControl101 { 24.99% {background: #68b022;} 25%, 100% {background: none;} } @keyframes slideControl02 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @-webkit-keyframes slideControl02 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @keyframes slideControl102 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @-webkit-keyframes slideControl102 { 24.99%, 50% {background: none;} 25%, 49.99% {background: #68b022;} } @keyframes slideControl03 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @-webkit-keyframes slideControl03 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @keyframes slideControl103 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @-webkit-keyframes slideControl103 { 49.99%, 75% {background: none;} 50%, 74.99% {background: #68b022;} } @keyframes slideControl04 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @-webkit-keyframes slideControl04 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @keyframes slideControl104 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } @-webkit-keyframes slideControl104 { 74.99% {background: none;} 75%, 100% {background: #68b022;} } /* Basisfunktionalität des Sliders */ .slider { overflow: hidden; } .slider input { position: absolute; left: -10000px; top: 0; } .slideList { width: 400%; /* Anzahl der Slides mal 100 */ position: relative; /* über die relative Positionierung wird der Slider durchs Sichtfenster geschoben */ -webkit-transition: left 2s; -moz-transition: left 2s; -o-transition: left 2s; transition: left 2s; /* für den fließenden Schub */ margin: 0; padding: 0; } .slideList:after { content: "."; display: block; height: .1px; clear: both; visibility: hidden; font-size: 0; overflow: hidden; } .slide { list-style: none; width: 25%; /* Breite gleich 100 / Anzahl Slides */ float: left; position: relative; left: 0; -webkit-transition: left 0s .5s; -moz-transition: left 0s .5s; -o-transition: left 0s .5s; transition: left 0s .5s; /*bei Klick auf ein Control werden alle Slides wieder auf Original-Position geschoben, hier für den ersten relevant. Damit die Aktion erst nach der slides-Verschiebung beginnt, kommt ein delay hinzu*/ } #slide04:checked ~ .slideList .slide, #slide104:checked ~ .slideList .slide { -webkit-transition-delay: 2s; -moz-transition-delay: 2s; -o-transition-delay: 2s; transition-delay: 2s; /* damit er nicht zu früh zurückrutscht */ } .slideList img { width: 100%; height: auto; vertical-align: bottom; } /* Zuweisung der Keyframe-Animationen */ .slideList, .slide, .slideControl label { -webkit-animation: 20s 2s infinite; animation: 20s 2s infinite; /* allgemeingültige Werte für die Keyframe-Animation */ } /* Positionierung und Aufruf der passenden Animation in Abhängigkeit des Status der Radiobuttons */ #slide01:checked ~ .slideList { -webkit-animation-name: slidesStart01; animation-name: slidesStart01; left: 0; } #slide02:checked ~ .slideList { -webkit-animation-name: slidesStart02; animation-name: slidesStart02; left: -100%; } #slide03:checked ~ .slideList { -webkit-animation-name: slidesStart03; animation-name: slidesStart03; left: -200%; } #slide04:checked ~ .slideList { -webkit-animation-name: slidesStart04; animation-name: slidesStart04; left: -300%; } /* Damit der Wechsel von 01 zu 101, 02 zu 102 usw. klappt, muss jeweils eine andere Animation aufgerufen werden*/ #slide101:checked ~ .slideList { -webkit-animation-name: slidesStart101; animation-name: slidesStart101; left: 0; } #slide102:checked ~ .slideList { -webkit-animation-name: slidesStart102; animation-name: slidesStart102; left: -100%; } #slide103:checked ~ .slideList { -webkit-animation-name: slidesStart103; animation-name: slidesStart103; left: -200%; } #slide104:checked ~ .slideList { -webkit-animation-name: slidesStart104; animation-name: slidesStart104; left: -300%; } /* Der erste Slide wird jeweils zur rechten Zeit an den Anfang oder das Ende gestellt */ #slide01:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart01; animation-name: slide01ToEndStart01; } #slide02:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart02; animation-name: slide01ToEndStart02; } #slide03:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart03; animation-name: slide01ToEndStart03; } #slide04:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart04; animation-name: slide01ToEndStart04; } /* Separate Animations-Namen für die zweite Steuerung */ #slide101:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart101; animation-name: slide01ToEndStart101; } #slide102:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart102; animation-name: slide01ToEndStart102; } #slide103:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart103; animation-name: slide01ToEndStart103; } #slide104:checked ~ .slideList .slide01 { -webkit-animation-name: slide01ToEndStart104; animation-name: slide01ToEndStart104; } /* nur zur Deko */ .sliderWrapper { position: relative; padding: 6px; border: 1px solid #ddd; margin-bottom: 40px; } .slide p { position: absolute; bottom: 1em; left: 0; background: rgba(0, 0, 0, .6); color: #ddd; padding: .4em 1em; } /* Steuerung durch den Benutzer */ .slideControl { width: 80px; position: absolute; bottom: -40px; left: 50%; margin-left: -40px; padding: 0; } .control01:checked ~ .slideControl01, .control02:checked ~ .slideControl02 { left: -5000px; /* Blendet die nicht benötigten Labels aus */ } .slideControl li { float: left; margin: 0 4px; width: 10px; height: 10px; border-radius: 50%; position: relative; text-indent: -10000px; border: 1px solid #ccc; box-shadow: 0 0 2px 2px #ccc; list-style: none; } .slideControl label { display: block; cursor: pointer; background: none; width: 100%; height: 100%; border-radius: 50%; box-sizing: border-box; border: 2px solid #fff; } .slideControl label:hover { background: #68b022!important; } #slide01:checked ~ .slideControl label[for="slide101"], #slide02:checked ~ .slideControl label[for="slide102"], #slide03:checked ~ .slideControl label[for="slide103"], #slide04:checked ~ .slideControl label[for="slide104"] { -webkit-animation-name: slideControl01; animation-name: slideControl01; background: #68b022; } #slide101:checked ~ .slideControl label[for="slide01"], #slide102:checked ~ .slideControl label[for="slide02"], #slide103:checked ~ .slideControl label[for="slide03"], #slide104:checked ~ .slideControl label[for="slide04"] { -webkit-animation-name: slideControl101; animation-name: slideControl101; background: #68b022; } #slide01:checked ~ .slideControl label[for="slide102"], #slide02:checked ~ .slideControl label[for="slide103"], #slide03:checked ~ .slideControl label[for="slide104"], #slide04:checked ~ .slideControl label[for="slide101"] { -webkit-animation-name: slideControl02; animation-name: slideControl02; } #slide101:checked ~ .slideControl label[for="slide02"], #slide102:checked ~ .slideControl label[for="slide03"], #slide103:checked ~ .slideControl label[for="slide04"], #slide104:checked ~ .slideControl label[for="slide01"] { -webkit-animation-name: slideControl102; animation-name: slideControl102; } #slide01:checked ~ .slideControl label[for="slide103"], #slide02:checked ~ .slideControl label[for="slide104"], #slide03:checked ~ .slideControl label[for="slide101"], #slide04:checked ~ .slideControl label[for="slide102"] { -webkit-animation-name: slideControl03; animation-name: slideControl03; } #slide101:checked ~ .slideControl label[for="slide03"], #slide102:checked ~ .slideControl label[for="slide04"], #slide103:checked ~ .slideControl label[for="slide01"], #slide104:checked ~ .slideControl label[for="slide02"] { -webkit-animation-name: slideControl103; animation-name: slideControl103; } #slide01:checked ~ .slideControl label[for="slide104"], #slide02:checked ~ .slideControl label[for="slide101"], #slide03:checked ~ .slideControl label[for="slide102"], #slide04:checked ~ .slideControl label[for="slide103"] { -webkit-animation-name: slideControl04; animation-name: slideControl04; } #slide101:checked ~ .slideControl label[for="slide04"], #slide102:checked ~ .slideControl label[for="slide01"], #slide103:checked ~ .slideControl label[for="slide02"], #slide104:checked ~ .slideControl label[for="slide03"] { -webkit-animation-name: slideControl104; animation-name: slideControl104; } </pre> </section> <section class="tabResult"> <div class="sliderWrapper"> <div class="slider"> <input type="radio" name="slider" class="control01" id="slide01" checked="checked" /> <input type="radio" name="slider" class="control01" id="slide02" /> <input type="radio" name="slider" class="control01" id="slide03" /> <input type="radio" name="slider" class="control01" id="slide04" /> <input type="radio" name="slider" class="control02" id="slide101" /> <input type="radio" name="slider" class="control02" id="slide102" /> <input type="radio" name="slider" class="control02" id="slide103" /> <input type="radio" name="slider" class="control02" id="slide104" /> <ul class="slideList"> <li class="slide slide01"> <img src="assets/files/images/portfolio/dgKegelschnitte.jpg" alt="" width="600" height="400" /> <p>Kegelschnitte</p> </li> <li class="slide slide02"> <img src="assets/files/images/portfolio/dgMassaufgaben.jpg" alt="Maßaufgaben" width="600" height="400" /> <p>Maßaufgaben</p> </li> <li class="slide slide03"> <img src="assets/files/images/portfolio/dgWuerfelkomposition.jpg" alt="Würfelkomposition" width="600" height="400" /> <p>Würfelkomposition</p> </li> <li class="slide slide04"> <img src="assets/files/images/portfolio/dgZylinderHyperboloid.jpg" alt="Schnitt Zylinder - Hyperboloid" width="600" height="400" /> <p>Schnittkurve von Zylinder und Hyperboloid</p> </li> </ul> <ul class="slideControl slideControl01"> <li><label for="slide01">Nummer 1</label></li> <li><label for="slide02">Nummer 2</label></li> <li><label for="slide03">Nummer 3</label></li> <li><label for="slide04">Nummer 4</label></li> </ul> <ul class="slideControl slideControl02"> <li><label for="slide101">Nummer 101</label></li> <li><label for="slide102">Nummer 102</label></li> <li><label for="slide103">Nummer 103</label></li> <li><label for="slide104">Nummer 104</label></li> </ul> </div> </div> </section> </section> </article> <footer> <a href="kontakt#datenschutz">Datenschutz</a> <address> +49 7266 4540055 | <a href="mailto:info@ebene11.com">info@ebene11.com</a> </address> </footer> <script src="assets/minifyx/js/scripts_pda39a3ee5e.js"></script> <script type="text/javascript"> SyntaxHighlighter.all(); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10