Imageslider ohne Javascript Ein einfacher Slider mit reinem CSS

In diesem Artikel wird der Aufbau eines einfachen Sliders (z.B. für eine Bildergalerie) ohne den Einsatz von Javascript (also ausschließlich per CSS) erklärt. Diese Beschreibung ist als kleines weiterführendes Beispiel zu den Möglichkeiten der Pseudoklasse :checked, wie sie in Accordion, Slider, Tabs & Co. mit purem CSS beschrieben sind, zu sehen.

Skizze zur Funktion
Bestandteile eines einfachen Sliders

Die Strategie

Die Idee ist letzten Endes ziemlich simpel: Wir schieben ein Band von Elementen durch ein „Sichtfenster”. Welches Stück von dem Band sich dabei gerade im Fenster befindet, wird von Radiobuttons gesteuert. Das Ganze bekommt dann noch ein bißchen CSS als Makeup.

Das HTML-Gerüst

Wir brauchen:

  1. ein Sichtfenster (cssSlider)
  2. ein Band zum schieben (sliderElements)
  3. Radiobuttons zum steuern
  4. Labels für eine hübsche Navigation (slideControl)

Wie man diese Inhalte auszeichnet, hängt natürlich vom konkreten Einzelfall ab. Für dieses Beispiel habe ich folgende Bedeutungen angenommen: Der Container für den Slider hat keine semantische Bedeutung, deshalb ein div. Die einzelnen Slides sehe ich als beliebige Abfolge von einzelnen Elementen, deshalb die Wahl der unsortierten Liste, bei der jedes li einem Slide entspricht. Jedes dieser Slides besteht aus einem Bild und zugehöriger Beschreibung; ob das Konstrukt aus figure und figcaption korrekt ist, muss man im Einzelfall sehen. Die einzelnen input wären sicherlich auch sehr gut mit einer Liste ausgezeichnet, allerdings müssen wir darauf leider verzichten, da es in CSS keinen passenden Selektor (müsste ein Eltern-Selektor sein) gibt, um dann noch die einzelnen Slides in Abhängigkeit des Status der Radiobuttons ansprechen zu können. Bei den label haben wir das Problem nicht, da sie Kinder eines Geschwisterelements, also problemlos ansprechbar sind.


  • Hier könnte deine Beschreibung stehen.
  • Eine tolle Beschreibung
  • Die Beschreibung zum dritten Bild
  • Und noch ein toller Untertitel

Die grundlegenden Funktionen

Essentiell für die Funktion ist, dass wir die Slides nebeneinander bringen (also unser Band entstehen lassen) und dafür sorgen, dass sie am Rande des Containers (Sichtfenster) abgeschnitten werden. Der Übersichtlichkeit halber lassen wir den Slider hier generell über die komplette Seitenbreite laufen. Er funktioniert aber natürlich auch mit allen anderen Größenverhältnissen und kann selbstverständlich auch auf Mediaqueries reagieren.

Die Berechnung der Breiten ist bei der Arbeit mit Prozent evtl. auf den ersten Blick nicht sofort klar, aber wenn man bedenkt, dass sich die Angaben immer auf die Breite des Elternelements beziehen, nachvollziehbar. Die Gesamtbreite der Liste mit den Slides entspricht der Summe der Einzelbreiten. Jedes Slide ist 100% (des Elternelements) breit, bei 4 Slides ergibt sich also eine Gesamtbreite von 400%. Von dieser errechneten Gesamtbreite nimmt ein Slide den Kehrwert der Anzahl der Slides ein - bei 4 Slides also 1/4. Ein Viertel in Prozent auszudrücken, bekommen wir gerade so noch ohne Taschenrechner hin - es sind genau 25%.

.slider {
	overflow-x: hidden;
	/* width: 1000px; bei Bedarf anpassen, da hier 100% gewünscht sind, kann man die Angabe einsparen */
}

.sliderElements {
	width: 400%; /* Summe der Einzelbreiten der Slides */
}

.sliderElements > li {
	float: left;
	width: 25%; /* 100 durch Anzahl der Slides */
}

/* Clearfix für die Liste */
.sliderElements:after {
	content: ".";
	display: block;
	height: .1px;
	clear: both;
	visibility: hidden;
	font-size: 0;
	overflow: hidden;
}

Soweit so gut. Den Wechsel der Bilder können wir über die Positionierung der Liste mit der Klasse sliderElements in Abhängigkeit des Status der Radiobuttons lösen. Also ein kleine Ergänzung im CSS:

.sliderElements {
	position: relative;
	left: 0;
}

.slider input:nth-of-type(2):checked ~ .sliderElements {
	left: -100%;
}

.slider input:nth-of-type(3):checked ~ .sliderElements {
	left: -200%;
}

/* Statt der Pseudoklasse nth-of-type können wir auch mit der ID des inputs arbeiten */
#slide04:checked ~ .sliderElements {
	left: -300%;
}

Die Verpackung

Damit aus dem Konstrukt ein ansehnlicher Slider wird, ergänzen wir noch ein wenig CSS. Fangen wir mit den weichen Übergängen von Slide zu Slide an. Die Positionsänderung soll nicht von jetzt auf gleich, sondern über eine Zeitspanne erfolgen - das Zauberwort heißt hier „Transitions”. Eine nette Eigenschaft, die CSS3 mit sich bringt und deren Einzelheiten hier zu erklären ein wenig zu weit führen würde. Wir nutzen sie trotzdem.

Bleiben nur noch die Radiobuttons und die Labels übrig. Erstere schieben wir über eine absolute Positionierung ins Nirwana. Letztere werden klassisch als Kreise mittig unter dem Slider angeordnet. Die kompletten CSS-Anweisungen im Überblick:

.sliderElements,
.sliderElements figure,
.sliderControls {
	margin: 0;
}

.sliderElements:after {
	content: ".";
	display: block;
	height: .1px;
	clear: both;
	visibility: hidden;
	font-size: 0;
	overflow: hidden;
}

.cssSlider {
	overflow-x: hidden;
}

.sliderElements {
	list-style: none;
	position: relative;
	left: 0;
	width: 400%;
	margin-bottom: .8em;
	padding: 0;
	-webkit-transition: left .8s ease-in-out;
	-moz-transition: left .8s ease-in-out;
	-o-transition: left .8s ease-in-out;
	transition: left .8s ease-in-out;
}

.sliderElements > li {
	float: left;
	width: 25%;
	position: relative;
}

#slide02:checked ~ .sliderElements {
	left: -100%;
}

#slide03:checked ~ .sliderElements {
	left: -200%;
}

#slide04:checked ~ .sliderElements {
	left: -300%;
}

/* Bildunterschrift auf dem Bild positionieren */
.sliderElements figcaption {
	display: block;
	color: #fff;
	position: absolute;
	left: 0;
	bottom: 1em;
	padding: .4em;
	background: rgba(0,0,0,.5);
}

/* Bilder responsive */
.sliderElements img {
	width: 100%;
	height: auto;
}


/* inputs aus dem Blickfeld schieben */
.cssSlider input {
	position: absolute;
	left: -99999px;
}

/* mittige Ausrichtung der Controls - funktioniert im Zusammenspiel mit inline-block */
.sliderControls {
	text-align: center;
}

/* Controls nebeneinander bringen */
.sliderControls li {
	display: inline-block;
}

/* Controls auf einheitliche Maße bringen und die Ecken abrunden */
.sliderControls label {
	width: 20px;
	height: 20px;
	line-height: 20px;
	text-align: center;
	border-radius: 50%;
	display: block;
	cursor: pointer;
	background: #68B022;
	color: #68B022;
}

/* Attributselektor und indirekter Nachfahrkombinator zum ansteuern der labels */
.sliderControls label:hover,
#slide01:checked ~ .sliderControls label[for="slide01"],
#slide02:checked ~ .sliderControls label[for="slide02"],
#slide03:checked ~ .sliderControls label[for="slide03"],
#slide04:checked ~ .sliderControls label[for="slide04"] {
	background: #ddd;
	color: #ddd;
}

Lauffähigkeit und Fallback

Die Lauffähigkeit steht und fällt mit der Unterstützung der Pseudoklasse :checked. Alle modernen Browser und der IE ab Version 9 haben damit keine Probleme. Ähnlich sieht es mit der CSS3-Eigenschaft transition aus, wobei diese ausschließlich für den weichen Übergang genutzt wird, also nicht essentiell wichtig ist. Eine Möglichkeit des Fallbacks wird im Artikel Accordion, Slider, Tabs & Co. beschrieben. Wie sinnvoll diese bei einem Slider ist, muss jeder für sich selbst beurteilen. Im Beispiel auf dieser Seite würde im Fall der Fälle nur der erste Slide sichtbar sein

So sieht es aus


  • Hier könnte deine Beschreibung stehen.
  • Eine tolle Beschreibung
  • Die Beschreibung zum dritten Bild
  • Und noch ein toller Untertitel
.sliderElements,
.sliderElements figure,
.sliderControls {
	margin: 0;
}

.sliderElements:after {
	content: ".";
	display: block;
	height: .1px;
	clear: both;
	visibility: hidden;
	font-size: 0;
	overflow: hidden;
}

.cssSlider {
	overflow-x: hidden;
}

.sliderElements {
	list-style: none;
	position: relative;
	left: 0;
	width: 400%;
	margin-bottom: .8em;
	padding: 0;
	-webkit-transition: left .8s ease-in-out;
	-moz-transition: left .8s ease-in-out;
	-o-transition: left .8s ease-in-out;
	transition: left .8s ease-in-out;
}

.sliderElements > li {
	float: left;
	width: 25%;
	position: relative;
}

#slide02:checked ~ .sliderElements {
	left: -100%;
}

#slide03:checked ~ .sliderElements {
	left: -200%;
}

#slide04:checked ~ .sliderElements {
	left: -300%;
}

/* Bildunterschrift auf dem Bild positionieren */
.sliderElements figcaption {
	display: block;
	color: #fff;
	position: absolute;
	left: 0;
	bottom: 1em;
	padding: .4em;
	background: rgba(0,0,0,.5);
}

/* Bilder responsive */
.sliderElements img {
	width: 100%;
	height: auto;
}


/* inputs aus dem Blickfeld schieben */
.cssSlider input {
	position: absolute;
	left: -99999px;
}

/* mittige Ausrichtung der Controls - funktioniert im Zusammenspiel mit inline-block */
.sliderControls {
	text-align: center;
}

/* Controls nebeneinander bringen */
.sliderControls li {
	display: inline-block;
}

/* Controls auf einheitliche Maße bringen und die Ecken abrunden */
.sliderControls label {
	width: 20px;
	height: 20px;
	line-height: 20px;
	text-align: center;
	border-radius: 50%;
	display: block;
	cursor: pointer;
	background: #68B022;
	color: #68B022;
}

/* Attributselektor und indirekter Nachfahrkombinator zum ansteuern der labels */
.sliderControls label:hover,
#slide01:checked ~ .sliderControls label[for="slide01"],
#slide02:checked ~ .sliderControls label[for="slide02"],
#slide03:checked ~ .sliderControls label[for="slide03"],
#slide04:checked ~ .sliderControls label[for="slide04"] {
	background: #ddd;
	color: #ddd;
}
  • Hier könnte deine Beschreibung stehen.
  • Eine tolle Beschreibung
  • Die Beschreibung zum dritten Bild
  • Und noch ein toller Untertitel