CSS Schalter

On / Off muss nicht hässlich sein

1. Worum es geht…

Ich nutze den "Hidden Checkbox Hack" und CSS, um iOS-like Kippschalter (Toggles, Switches) zu gestalten. Diese sehen am Ende so aus:


2. Das HTML

Das HTML ist ein umwrappendes div, ein Checkbox-input-Element mit dazugehörigem label und zwei spans, die ich mit CSS gestalten kann:

HTML

<div class="switch">
  <input id="switch1" type="checkbox">
  <label for="switch1">
    <span class="buttonbackground">
      <span class="buttonslider"></span>
    </span>
  </label>
</div>

Zu beachten:

  1. Das input-Element muss vom Typ "Checkbox" sein und über die id (hier: switch + n) mit dem label (via for="") verknüpft sein.
  2. labels dürfen keine Block-Elemente beinhalten (also bitte keine divs, Buttons oder ähnliches verwenden): Daher spans.

3. Das Design

Das span mit der Klasse buttonbackground bildet die Hintergrundfläche des Schalters. Es soll in der "Aus"-Variante

  • hellgrau und
  • doppelt so breit wie hoch sein,
  • einen border-radius (1/2 Höhe für eine gleichmäßige Rundung) und
  • zwei "Innenschatten" (inset) haben.
  • Die Positionierung relative ist notwendig, da die beweglichen Knöpfe (Klasse: buttonslider) gleich eine absolute Positionierung erhalten.
  • Die Zentrierung in einem evtl. vorhandenen umschließenden Element passiert via margins (links und rechts auto).
  • Und da das span ab Werk ein Inline-Element ist, bekommt es noch ein display:block; mitgegeben.

CSS

.switch {
  background: #aaa;
  padding: 2rem;
  width: 9rem;
  margin: 0 auto;
  border-radius: 0.75rem;
}

.buttonbackground {
  background-color:#ccc;
  width: 5rem;
  height: 2.5rem;          /* = width/2 */
  border-radius: 1.25rem;  /* = height/2 */
  box-shadow:
    0 2px 2px rgba(0,0,0,0.5) inset,
    0 -2px 0px rgba(255,255,255,0.5) inset;
  position: relative;
  margin: 0.5rem auto;
  display:block;
}

Ach ja, das input muss noch unsichtbar gemacht werden …

CSS

#switch1 {
  display:none;
}

… und dann kann der eigentliche Schalter gestaltet werden:

Das span mit der Klasse buttonslider soll

  • ebenfalls hellgrau (aber heller als der Hintergrund),
  • und etwas größer sein, als der buttonbackground hoch ist.
  • Darüber hinaus bekommt es eine Kontur (border) und
  • einen border-radius von 50% (für "rund").
  • Es wird absolute, left:0; und etwas nach oben (top:-.15rem;) positioniert,
  • bekommt einen Schlagschatten und
  • ebenfalls ein display:block;

und sieht dann so aus:

CSS

.buttonslider {
  background:#ddd;
  width:2.7rem;
  height:2.7rem;
  border-radius:50%;
  border:1px solid #aaa;
  position: absolute;
  left:0;
  top:-0.15rem;
  box-shadow: 0 4px 3px rgba(0,0,0,0.3);
  display:block;
}

Ein aktivierter Schalter unterscheidet sich in der Hintergrundfarbe des buttonbackground und Position sowie Hintergrundfarbe des buttonslider. Die Adressierung des "On"-Status basiert – wie erwähnt – auf dem "Checkbox Hack". Dabei macht man sich zunutze, dass die Checkbox "gechecked" wird, auch wenn man nicht auf das Anhak-Kästchen, sondern nur auf das Label klickt. Das "Kunststück" besteht in diesem Beispiel darin, die Klassen buttonbackground und buttonslider für den Fall zu adressieren, dass die Checkbox gechecked ist. Das geht mittels der Pseudo-Klasse :checked (MDN Doku) und einem "angrenzenden" (+) oder einem "allgemeinen Geschwisterselektor" (~).

CSS

/* (IDs) ersetzen! */

#switch(ID):checked + label .buttonbackground {
  background-color:#64b464;
}
#switch(ID):checked + label .buttonslider {
  left: 2.5rem;         /* = buttonbackground-width / 2 */
  background:#eee;
}

Ein "checked" und klickbarer Schalter sieht dann so aus:

4. Feinschliff

Damit Maus-Benutzern klarer wird, dass hier geklickt werden kann, ändert man am besten den Cursor via

CSS

/* (ID) ersetzen! */

#switch(ID) + label .buttonbackground:hover {
  cursor:pointer;
}

Dann kann man buttonbackground und buttonslider noch mit CSS Transitions anmimieren:

CSS

.buttonbackground {
  /*bisheriges CSS*/
  ...
  transition: background-color 0.2s ease;
}
.buttonslider {
  /*bisheriges CSS*/
  ...
  transition: all 0.2s ease;
}

Fertig:

Viel Spaß damit 🙂

Eine HTML-Datei mit dem kompletten HTML und CSS gibt es hier.

"CSS Schalter" von Martin Smaxwil ist unter einer CC BY 4.0-Lizenz veröffentlicht.
Darüber hinausgehende Hinweise zu Bestandteilen wie Code Snippets u.ä. findet man hier.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert