Accordion – Effekt nur CSS

Accordion oder Akkordeon - Effekt nur CSS, kein Javascript

Die einfachste Lösung für ein platzsparendes Akkordeon ist sicher jQuery, aber wer will eine Javascript-Library mit zig-Kilobyte laden, nur um einen einfachen Effekt in Szene zu setzen?

Für alle Anhänger der reinen CSS-Lösungen …

Der Akkordeon-Effekt hier basiert auf einem input type="radio" -Feld. Ist der Zustand des input-Felds checked, öffnet sich das jeweilige Panel des Akkordeons und schließt sich mit dem nächsten Klick.

Kleiner Ausflug in HTML-Formulare

input type="radio" kennen wir als Optionen in einem Formular.

Rot Grün Blau Gelb

Es ist das gemeinsame name-Attribut, das die Radio-Buttons synchronisiert, so dass immer nur ein Feld den Wert checked aufweist.

<input type="radio" name="myradio" value="rot"> Rot
<input type="radio" name="myradio" value="grün"> Grün
<input type="radio" name="myradio" value="blau"> Blau
<input type="radio" name="myradio" value="gelb"> Gelb

Ein label-Tag ist über das id bzw. for-Attribut mit seinem Eingabefeld verbunden – gleich, ob das label-Markup vor oder irgendwo nach dem Eingabefeld notiert ist.

Ein Klick auf das label-Element löst den Radio-Button genauso aus wie der Klick auf das input-Element. Das input-Element selber kann mit display:none verborgen bleiben. Dieses Verhalten macht eigene Stile für Eingabefelder so schön einfach.

<span>
    <input type="radio" name="myradio2" value="rot" id="rot"> 
    <label for="rot" class="bigbutton">Rot</label>
</span>

<span>
    <input type="radio" name="myradio2" value="grün" id="blau"> 
    <label for="blau" class="bigbutton">Blau</label>
</span>

Das CSS für die Label-Buttons: input-Tag verbergen, anstelle dessen die label-Elemente kräftig aufgeblasen. input:checked~.bigbutton ist ein Attribut-Selektor, auch als indirekter Nachbar-Selektor bezeichnet.

Dafür müssen input und label nur unter einem gemeinsamen Elternelement sitzen.

input[name="myradio2"] { 
   display: none
}
.bigbutton { 
   background: #3BBDE4; 
   color: #0E6F98;  
   transition: 0.5s;
}
input:checked~.bigbutton { 
   background: #0E6F98; 
   color: white; 
   transition: 0.5s; 
} 

Accordion mit CSS :checked

Das war ein langer Vorspann, dafür ist der Trick hinter dem Akkordeon ohne Javascript hoffentlich besser verständlich.

  • Liquorice wafer lollipop sesame
  • snaps gummi bears. Wafer jelly beans chupa chups cotton candy
  • caramels carrot cake topping oat cake.
  • Cake carrot cake marshmallow cheesecake cake lemon drops pudding apple pie.
  • Chocolate gingerbread marshmallow croissant.
  • Liquorice jujubes cake ice cream cake liquorice croissant ice cream.
  • Lollipop jelly-o fruitcake chocolate cake tootsie roll marzipan dragée halvah.
  • Chocolate gingerbread marshmallow croissant.
  • Liquorice jujubes cake ice cream cake liquorice croissant ice cream.

Fruitcake marshmallow sugar plum soufflé biscuit.

Sesame snaps pie lemon drops.

In dem Element mit der CSS-Klasse panel kann alles stecken: Ungeordnete Listen wie in diesem Beispiel, Texte oder Bilder.

<div>
    <input type="radio" name="acc" id="Fruitcake">
    <label for="Fruitcake"><b>❤</b> Fruitcake?</label>
    <div class="panel">
        <p>Fruitcake marshmallow sugar plum soufflé biscuit.</p>
        <p>Sesame snaps pie lemon drops.</p>
    </div>
</div>

Jede Ebene besteht aus einem input-Element vom Typ radio, die alle durch dasselbe Name-Attribut miteinander verbunden sind. So kann immer nur ein Radio-Button aktiv sein (checked).

Jedes Input-Element hat eine eindeutige ID, die mit dem for-Attribut des label-Tags übereinstimmt.

Etwas Formular-Magie: Das Input-Feld ist nicht sichtbar (display:none), aber das label-Tag mit dem passenden for-Attribut bekommt den Mausklick genauso mit.

Panel animieren

.accordion input{
  display: none;
}

.accordion .panel {
  margin: 0 auto;
  height: 0;
  color: hsla(0, 0%, 0%, 0);
  background-color: hsla(350, 60%, 50%, 0.2);
  line-height: 28px;
  padding: 0 30px;
  box-sizing: border-box;
  transition: 0.5s;
}

.accordion input:checked~.panel {
  height: auto;
  font-size: 16px;
  padding: 30px;
  transition: 0.5s;
  color: black;
}

CSS für label

Das Beispiel ändert nur die Hintergrundfarbe von hsla(350, 60%, 70%, 1) zu hsla(350, 90%, 40%, 1) und die Schriftfarbe von Schwarz nach Weiß color: #fff;.

.accordion label {
  cursor: pointer;
  background-color: hsla(350, 60%, 70%, 1);
  border-bottom: 2px solid #fff;
  display: block;
  padding: 1em;
  width: 100%;
  font-weight: 400;
  font-size: 1.2em;
  box-sizing: border-box;
  z-index: 100;
}

.accordion input:checked+label {
  background-color: hsla(350, 90%, 40%, 1);
  color: #fff;
}

Plus / Minus im label

Nur ein Pseudo-Element kombiniert mit einem Pseudo-Selektor, auch wenn der Selektor so kompliziert aussieht:

.accordion label::after  { content: " + "; color: white; float: right; font-size: 1.6em}
.accordion input:checked+label::after { content: " – ";  }

.accordion label::after hinter dem label-Tag ein +-Symbol setzen.

.accordion input:checked+label::after wenn das input-Element das checked-Attribut gesetzt hat (label wurde angeklickt), dann nach dem darauffolgenden label-Element ein Minus setzen.

Das Auf und Ab

Das Auf- und Abschwingen des Akkordeon-Effekts lässt sich nur durch eine feste Höhe für die Ebenen des Akkordeons lösen oder letztendlich doch wieder per Javascript.

Ein paar Zeilen Javascript müssten die maximale Höhe des Akkordeons bestimmen und das CSS in ein Stylesheet schreiben.

Accordion input type="checkbox"

Wenn mehrere Panels des Accordions geöffnet bleiben sollen, werden Checkboxen anstelle von Radio-Buttons eingesetzt.

Download

Ohne Anspruch auf Vollständigkeit: Akkordeon mit CSS – (fast) ohne Javascript

accordion