Styling für Checkboxen

3 Lösungen, doch nur ein Meisterstreich

Februar 05 , 2016
Styling für Checkboxen

Wo liegt das Problem am stylen von Checkboxen?

HTML-Checkboxen sind widerwillige DOM-Elemente, die sich so ähnlich verhalten wie andere Input-Elemente. Außer mit der Appearance-Eigenschaft lässt sich kaum Styling anwenden. Dennoch möchte man die Checkboxen oftmals browserübergreifend gleich oder ganz anders stylen.

Wie gerade schon angesprochen behandeln unterschiedliche Browser das natürliche Aussehen von Checkboxen anders. Das ist natürlich ein Dorn im Auge jedes Frontend-Entwicklers.

Ansatz 1: Javascript und oftmals jQuery

Zu CSS2-Zeiten hat man sich gerne eine Lösung mit Javascript gebaut. Im Grunde ist es simpel: Wir platzieren irgendwo auf der Webseite eine Checkbox und setzen unsere Design-Checkbox als Bild oder HTML-Element an die gewünschte Stelle. Mittels Event-Listener fangen wir einen Klick auf unsere designte Checkbox ab, verändern darauf hin den Zustand der eigentlichen Checkbox und tauschen das Bild der gestylten Checkbox aus. Die eigentliche Checkbox können wir mit display: none; für den Benutzer unsichtbar machen. Für diese Routine lassen sich im Internet auch unzählige (jQuery)-Plugins finden.

Es mag eine Frage des Glaubens sein, aber ich bin kein Freund von Javascript-Lösungen, wenn das Problem auch mit purem CSS zu lösen ist, sollte man dies tun. Browser mit deaktiviertem Javascript, die ich in der Tat "aus Sicherheitsgründen" schon bei mehreren Kunden sehen konnte, als auch ein Javascript-Fehler kann diese Lösung crashen und damit das HTML-Form untauglich machen.

Ansatz 2: Element "durchklickbar" machen

Heute habe ich von einer Javascriptfreien Lösung gehört, die mir mehr als kurios vorkam. Hier fasst man seine Checkbox in einen Wrapper und steckt noch -Element dazu. Das -Element richtet man so her, wie man die Checkbox gerne haben möchte, möglicherweise mit einem Bild. Jetzt legt man sein Bild genau über die Checkbox und arbeitet mit der CSS-Eigenschaft pointer-events: none;. Somit hat man das Bild quasi durchklickbar gemacht und wenn jetzt der User auf das Bild klickt, klickt er in Wirklichkeit die Checkbox an.

Damit diese Lösung funktioniert, müssen wir unser Input-Element auf die Größe unseres Bildes bringen. CSS-Eigenschaften wie height und width, funktionieren jedoch beispielsweise im Firefox nicht. Demnach müssen wir transform: scale(); verwenden. Dies funktioniert zusammen mit CSS3 soweit gut, jedoch pixelt die Checkbox dann. Größtes Manko ist die Angabe des Multiplikators der transform-Eigenschaft. Von der browserabhängigen Größe der natürlichen Checkbox den passenden Multiplikator zu finden, ist wieder nur durch user-agent-basierendem CSS möglich. Dies benötigt wiederum Javascript. Desweiteren bin ich ebenfalls kein Freund von kuriosen Größenangaben im CSS.

Die saubere Lösung

Mein persönlicher Favorit ist folgende Lösung: Hierfür muss man sich das Label-Element einmal vor Augen führen.

Fakten zum Label-Element:

  • Semantisch ist es für eine nähere Beschreibung für Input-Elemente
  • W3C erlaubt das Label um ein Input-Element zu schließen, als auch daneben
  • Sowohl semantisch, als auch Funktional darf ein Input-Element auch mehrere Labels haben
  • Semantisch dürfen Labels nur jeweils einem Input-Element zugewiesen sein
  • Durch die Angabe des For-Attributs wird ein Label einem Input-Element zugewiesen

Ist ein Label einer Checkbox zugewiesen, kann ebenso auch auf das Label geklickt werden, um die Checkbox zu triggern. Genau das machen wir uns zu Gute und nutzen ein Label-Element unmittelbar nach jeder Checkbox. Dieses dient als Styling für die Checkbox. Das Label-Element kann leer bleiben, muss es aber nicht; Das bedeutet: Innerhalb des Labels können wir mit den Pseudo-Elementen :before und :after hantieren, auch das Label selbst darf später ein Styling erhalten. Dennoch gilt zu beachten, dass die Checkbox das Aussehen ihrer vier Zustände (unchecked, checked, unchecked-disabled, checked-disabled) nur durch CSS-Angaben ändern kann. Oftmals werden hierfür Hintergrundbilder als Sprites verwendet, die nur die background-position verändern.

Der Meistertrick

Genau an diesem Punkt haben wir die fertige Endlösung für alle Browser, die kein CSS3 unterstützen. Das sind selbstverständlich nur noch einzelne User, aber auch diese haben funktionierende Checkboxen, nur halt ohne jedes Styling.

Jetzt kommt der Part, der diese Lösung wahnsinnig souverän macht: Alles weitere lösen wir ausschließlich mit CSS3-Selektoren. input[type="checkbox"] + label selektiert das Label, welches unmittelbar nach der Checkbox kommt. Mit den Pseudoselektoren :checked, :enabled und :disabled können wir die Zustände des Labels stylen. Wichtig: Die Pseudoselektoren müssen auf das Input angewendet werden.

Nachdem wir unserem Label ein Styling verpasst haben, müssen wir noch das Input-Element verschwinden lassen. Damit dies aber nur bei CSS3-fähigen Browsern verschwindet, arbeiten wir auch hier mit einem CSS3-Selektor:

input[type="checkbox"]:checked, input[type="checkbox"]:not(:checked) {
    display: none;
}

Welche Methode gefällt euch am Besten? Wie löst ihr dieses Problem in der Regel? Warum so und nicht anders? Würde gerne mit euch im Kommentar-Bereich eine kleine Diskussion starten.