Zur Suche springen Zur Navigation springen Zum Hauptinhalt springen Zum Footer springen

Formular-Styling mit CSS – Select-Listen, Radio-Buttons und Checkboxen individuell gestalten

Die Gestaltung von Formularfeldern gehört zu den eher lästigen Aufgaben eines Web-Designers. Insbesondere Select-Listen, Radio-Buttons und Checkboxen ließen sich lange Zeit kaum mit CSS ansprechen, so dass für gewöhnlich mit JavaScript nachgeholfen werden musste, wenn eine individuelle Gestaltung gewünscht war. Mittlerweile lassen sich Formularfelder in modernen Browsern ohne JavaScript individuell gestalten. In diesem Zusammenhang möchte ich einige CSS-Snippets archivieren.

appearance: none;

Mit Hilfe des CSS-Befehls appearance: none; kann die Standard-Gestaltung von Bedienelementen im Browser deaktiviert werden. Das ist nicht nur hilfreich um Selectlisten, Radio-Buttons und Checkboxen zu gestalten, sondern auch um das Standard-Styling von Suchfeldern, Buttons und weiteren UI-Elementen zu entfernen, deren Gestaltung zunehmend vom Browser übernommen wird. Der appearance-Befehl ermöglicht es übrigens auch, dass Standard-Styling des Browsers/OS bewusst zuzuweisen.

Progressive Enhancement

Der appearance-Befehl funktioniert nicht im Internet Explorer. Damit es in alten Versionen des Browsers (<=IE9) nicht zu unerwünschten Effekten kommt, behalten wir in inkompatiblen Systemen das Standard-Aussehen der Eingabefelder bei. Nach dem Prinzip des Progressive Enhancement gestalten wir die Felder nur dann, wenn der Browser den Befehl auch unterstützt.

Select-Listen gestalten

Die individuelle Gestaltung von Select-Listen ist einfach. Über den appearance-Befehl entfernen wir zunächst das Standard-Styling.

/* remove standard-styles */
select {
  appearance: none;
  border:none;
  border-radius: 0;
  font-size: 1em;
  width: 100%
} 

Anschließend gestalten wir das Element mit CSS unseren Vorstellungen entsprechend. Ein individuelles Pfeil-Icon weisen wir in diesem Beispiel als CSS-background-image zu – eine DataURI bietet sich ebenfalls an.

/* styling */
select {
  width:100%;
  border: 1px solid #bbb;
  padding:.75em 1em .5em 1em;
  box-shadow: 0 2px 1px 0 rgba(0,0,0,0.2);
  background-color:white;
  background-image:url(select-arrow.png);
  background-position: right;
  background-repeat: no-repeat;
}

select:hover {
  box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
}
Die Select-Liste im Vergleich: IE8, IE9, IE10 und – stellvertretend für die modernen Browser – Chrome
Die Select-Liste im Vergleich: IE8, IE9, IE10 und – stellvertretend für die modernen Browser – Chrome

Damit der Internet Explorer 10 den Pfeil des Browsers ebenfalls verliert, ist ein kleiner Hack nötig.

/* hide browser-styling (arrow) in IE10 */
select::-ms-expand {
  display:none;
}

Die inkompatiblen Browser (IE8 & IE9) identifizieren wir hier mit einer CSS-Klasse, die über einen Conditional Comment eingefügt wurde. Auch hier sind verschiedene Herangehensweisen denkbar. Wir entfernen somit die Pfeil-Grafik, da ansonsten zwei Pfeile in der Select-Liste angezeigt würden.

.lt-ie10 select {
    background-image: none;
}

Das option-Element gestalten

Das Drop-Down-Element der Select-Liste (<option>) lässt sich nur sehr eingeschränkt mit CSS ansprechen. In Webkit-Browsern haben wir – sofern ich recht informiert bin – keine Möglichkeit das <option>-Element zu gestalten. Firefox hingegen verwendet für <option> die Hintergrund- und Textfarbe des <select>-Elements, sofern <option> nicht selbst angesprochen wurde.

Gestaltetes option-Element in Firefox
Gestaltetes option-Element in Firefox

Mit folgendem Code erreicht ihr daher im Firefox eine Darstellung wie im Screenshot zu sehen:

select {
  /* irrelevante Eigenschaften gekürzt */
  border: 1px solid black;
  padding:.75em 1em .5em 1em;
  box-shadow: 0 2px 1px 0 rgba(0,0,0,1);
  background-color:#333;
  color:white;
}

option {
  background:#222;
  border-top:1px solid #444;
  padding:.3em 1em .3em 1em;
}

Radio-Buttons und Checkboxen gestalten

Radio-Buttons und Checkboxen benötigen etwas mehr Arbeit. Zunächst erledigen wir die Basis-Gestaltung für alte Versionen des Internet Explorers: Wir behalten die Browser-Standards bei, und passen nur die Positionierung und die Abstände ein wenig an.

Radio-Buttons und Checkboxen im Vergleich: IE8, IE9, IE10 und – stellvertretend für moderne Browser – Chrome
Radio-Buttons und Checkboxen im Vergleich: IE8, IE9, IE10 und – stellvertretend für moderne Browser – Chrome

In modernen Browsern blenden wir die Standard-UI-Element für Radio-Buttons und Checkboxen komplett aus. Wir identifizieren die modernen Browser über die Pseudoklasse :checked. Alle Browser die :checked verstehen, sind auch in der Lage die anderen notwendigen Befehle zu interpretieren.

/* remove standard-styles */
input {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border:none;
  border-radius: 0;
  font-size: 1em;
  width: 100%
} 

/* graceful degradation for ie8 */
input[type='checkbox'],
input[type='radio'] {
  width:auto;
  float:left;
  margin-right: .75em;
  background:transparent;
  border:none;
}

input[type='checkbox']:checked,
input[type='checkbox']:not(:checked),
input[type='radio']:checked,
input[type='radio']:not(:checked) {
  background: transparent;
  position: relative;
  visibility: hidden;
  margin:0;
  padding:0;
}

input[type='checkbox'] + label,
input[type='radio'] + label {
  cursor: pointer;
}

Nachdem wir die Standard-UI-Elemente versteckt haben, fügen wir Sie als ::before-Pseudoelement des jeweiligen <label>-Elements wieder ein. Da man die Auswahlfelder auch durch Klicken auf <label> aktivieren kann, nutzen wir anschließend die Pseudoklasse :checked um das Pseudoelement ::before mit CSS umzugestalten, sobald ein Radio-Button oder eine Checkbox aktiviert wurde. Hier kann anstelle der schlichten CSS-Gestaltung natürlich auch eine Grafik eingesetzt werden.

input[type='checkbox']:checked + label::before,
input[type='checkbox']:not(:checked) + label::before,
input[type='radio']:checked + label::before,
input[type='radio']:not(:checked) + label::before {
    content:' ';
    display:inline-block;
    width: 17px;
    height:17px;
    position: relative;
    top:4px;
    border: 1px solid #bbb;
    background: white;
    margin-right: 1em;
    box-shadow: inset 0 1px 1px 0 rgba(0,0,0,.1);
}

input[type=radio]:checked + label::before,
input[type=radio]:not(:checked) + label::before {
  border-radius: 30px;
}

input[type='checkbox']:hover  + label::before,
input[type='radio']:hover  + label::before {
  background:#ddd;
  box-shadow: inset 0 0 0 2px white;
}

input[type='checkbox']:checked  + label::before,
input[type='radio']:checked  + label::before {
  background:black;
  box-shadow: inset 0 0 0 2px white;
}

Vollständiges Beispiel

Das Beispiel mit zusammengefassten Code-Passagen und zusätzlichem Styling für Textfelder könnt ihr euch hier anschauen.

Beispiel anzeigen

Geschrieben von Jonas

Benutzerbild

Jonas ist Gründer der Agentur kulturbanause und des kulturbanause Blogs. Er arbeitet an der Schnittstelle zwischen UX/UI Design, Frontend und Redaktion und hat zahlreiche Fachbücher und Video-Trainings veröffentlicht. Jonas Hellwig ist regelmäßig als Sprecher auf Fachveranstaltungen anzutreffen und unterstützt mit Seminaren und Workshops Agenturen und Unternehmen bei der Planung, der Gestaltung und der technischen Umsetzung von Web-Projekten.

Jonas Hellwig bei Xing

Feedback & Ergänzungen – 26 Kommentare

  1. Philipp
    schrieb am 17.01.2019 um 23:23 Uhr:

    Funktioniert nicht mehr. On Click wird kein checked mehr ausgeführt. Wenn man manuell checked im HTML setzt werden die styles richtig gesetzt.

    Antworten
    • Jonas Hellwig
      schrieb am 18.01.2019 um 12:59 Uhr:

      Hallo Philipp, das Beispiel funktioniert noch. Wir können nicht nachvollziehen was du meinst. Wenn du uns ein paar mehr Details geben kannst, schauen wir gerne mal nach.

      Antworten
  2. Thomas
    schrieb am 07.01.2019 um 11:08 Uhr:

    Hallo, wie formatiert man Select-Felder mit Mehrfachauswahlen? Mit Einfachauswahl funktioniert es gut, aber bei Mehrfachauswahlen sieht das Select-Element immer noch schlecht aus.
    Ich möchte ganz einfach nur eine Zeile angezeigt haben mit einem einzigen Pfeil nach unten. Und wenn ich auf diesen Pfeil draufdrücke, dann soll eine Liste erscheinen, in der ich dann mehrere Einträge selektieren kann. Geht sowas?
    Gruß Thomas

    Antworten
  3. Daniel
    schrieb am 24.07.2018 um 17:53 Uhr:

    Hi, sehr gutes Tutorial, das funktioniert echt wunderbar.
    Ich probiere gerade, das mit dem Plugin „Calculated Fields Form“ in Einklang zu bringen. Dort werden die Checkboxen und Radio Buttons aber etwas anders angelegt.
    Nicht wie hier, wo das Input Feld vor dem Label ist, sondern dort ist das Input Feld im Label. Da greift dann diese Variante nicht. Habe es auch schon versucht, entsprechend anzupassen aber bisher erfolglos.
    Ich kann das natürlich auch selbst dann so anlegen, dann gehen mir aber Funktionen des Plugins verloren.
    Habt ihr eine Lösung dafür?

    Antworten
  4. Aleksandar
    schrieb am 08.09.2017 um 10:41 Uhr:

    Vielen Dank für die tolle Anleitung. Hat mir sehr geholfen und viel Zeit gespart.

    Antworten
  5. Karl
    schrieb am 26.07.2017 um 17:53 Uhr:

    Das sind alles super Sachen!
    Doch habe ich da noch eine Frage.
    Kann man programmieren, dass bei einem ausgeklappten Selectfeld alle Einträge auf einer Seite stehen? Dann ist es nämlich übersichtlicher und man muss nicht scrollen.

    Antworten
  6. maik
    schrieb am 13.03.2017 um 08:53 Uhr:

    hi, die Anleitung ist super. Brauche gerade genau das.
    Allerdings, wie kriege ich die labels neben die boxen horizontal zentriert wenn ich die boxen und die radios größer mache?

    Antworten
  7. Torsten Jerschabek
    schrieb am 14.11.2016 um 09:23 Uhr:

    Vielen Dank für die tolle Anleitung. Ich habe lange gesucht nach guten Ressourcen für das Formularstyling. Hat mir sehr geholfen und viel Zeit gespart.

    Antworten
  8. Jens Ubert
    schrieb am 07.11.2016 um 09:56 Uhr:

    Wunderbare Lösung! Viel gelernt durch Dein Tutorial und Beispiel.
    Da ist aber noch eine Kleinigkeit. Checkboxen benötigen im Firefox scheinbar ein paar Punkte mehr Platz nach links als im Chrome, sie werden also im Firefox etwas weiter rechts dargestellt. Nun versuche ich dieses zu verhindern, so dass die Position zumindest in etwa identisch ist und wie im Chrome dargestellt wird.
    Gibt es da ein Workaround?

    Antworten
  9. Jens Trainer
    schrieb am 17.08.2016 um 10:15 Uhr:

    Danke für die Übersicht!
    Besonders das Styling der Checkboxen hat mich Stunden gekostet.

    Antworten
  10. Das HTML Select-Element: Styling mit pure CSS - macro
    schrieb am 30.07.2016 um 15:50 Uhr:

    […] Beim Styling von Form-Elementen sollte die Aufmerksamkeit darauf liegen, das das Design der Funktion folgt und die Benutzer nicht übermäßig herausfordert. Sehr gut beschrieben für Text-Input, Radiobuttons und Checkboxen hat das Jonas Hellwig hier: https://blog.kulturbanause.de/2015/03/formular-styling-mit-css-select-listen-radio-buttons-und-check&#8230;. […]

    Antworten
  11. Hella
    schrieb am 19.04.2016 um 12:39 Uhr:

    Sehr schön, aber was mach ich, wenn ich kein Label habe? (Skala steht oben, mehrere Fragen darunter, somit kein Label am Radio-Button)

    Ich bin leider auf keine Lösung gekommen, denn wenn ich die checkbox verstecke, kann ich ja :before und :after nicht mehr nutzen.

    Antworten
    • Carsten A.
      schrieb am 26.08.2016 um 08:53 Uhr:

      Hallo Hella,

      die Pseudoelemente :before und :after funktionieren sowieso nicht an Elementen, sondern nur an Elementen, die auch echte Kind-Elemente aufnehmen können.
      Man wird also nicht darum herumkommen ein solches Element noch zu den Radio-Buttons hinzuzufügen. Ein Label-Element hat zu dem den Vorteil, das man es einem Input-Element zuordnen kann. Dadurch werden Klicks auf ein Label behandelt wie Klicks auf das Input-Feld selbst (wodurch man u.A. Checkboxen umschalten, Radiobuttons auswählen und Textfelder fokussieren kann).

      Beste Grüße,
      Carsten

      Antworten
      • Florence Maurice
        schrieb am 07.09.2016 um 12:33 Uhr:

        danke, Carsten, für deine äußerst nützlichen Anmerkungen!

  12. Mafrieger
    schrieb am 04.04.2016 um 16:23 Uhr:

    schicker Beitrag! Danke!

    Zur Weiterentwicklung:

    1) Hier gibts ein Beispiel mit schönen Symbolen aus fontawesome:
    http://codepen.io/rstrahl/pen/yyEYBx

    2) und hier gibts nen Ansatz der Tastatursteuerung erlaubt:
    http://weblog.west-wind.com/posts/2015/Feb/26/Using-FontAwesome-Fonts-for-HTML-Radio-Buttons-and-Checkboxes

    das jetzt zusammen mit der im obigen Beitrag beschrieben „Browserweiche“
    wäre doch die perfekte Lösung – oder?

    => vielleicht ein guter Anlass für eine Aktualisierung des Blogbeitrags?
    Oder eine Fortsetzung?

    Antworten
  13. Wanst
    schrieb am 23.02.2016 um 15:30 Uhr:

    Hi, soweit ganz gut, aber kann man die OPTIONs und OPTGROUPs eines SELECT-Feldes auch so gestalten, dass es ein IE oder Webkit-Browser darstellt? Bei mir klappt das zwar im FF, aber die anderen ignorieren die Anweisungen einfach und kochen ihr eigenes Süppchen.

    Danke!

    Antworten
    • Carsten A.
      schrieb am 26.08.2016 um 08:58 Uhr:

      Hallo Wanst,

      das ist leider nicht möglich. Die genannten Browser verwenden zur Darstellung und für die Funktion an sich Systemelemente des Betriebssystems. Deswegen sehen diese, trotzdem man den gleichen Browser verwenden, auf unterschiedlichen Betriebssystemen (z.B. Mac OS gegenüber Windows) auch unterschiedlich aus.
      Einzige Abhilfe wäre das Element und dessen Funktionalitäten mit eigenem HTML, CSS und Javascript nachzubauen. Es gibt auch bereits fertige Javascript-Bibliotheken im Netz, mit denen man ein normales Select pflegt, aber frei style-bare Elemente generiert werden.

      Beste Grüße,
      Carsten

      Antworten
  14. Michael
    schrieb am 11.12.2015 um 13:52 Uhr:

    leider fehlen die folgenden (für eine Radio box) Standard Effekt
    – Focused-Effect
    – Tastursteuerung
    – Tabindex-Support

    Antworten
  15. Ruth Richter
    schrieb am 05.08.2015 um 14:46 Uhr:

    Vielen Dank für diesen konstruktiven Beitrag Schade dass dieser nicht als erster Eintrag in Google gefunden wird, war Zufall aber hat mir geholfen und hat mich beeindruckt.

    Antworten
  16. Florence Maurice
    schrieb am 06.05.2015 um 15:34 Uhr:

    Schöne Techniken!

    ein Nachteil ist nur, dass sich die so gestylten Radio- und Checkboxen nicht mehr per Tastatur auswählen lassen (getestet gerade auf Firefox und Chrome).
    Abhilfe besteht wahrscheinlich darin, dass man eine andere Technik zum Verbergen der ursprünglichen Radiobuttons/checkboxen verwendet; also nicht auf visibility: hidden setzt.
    Bei jQuery Mobile etwa lassen sich die Radiobuttons/Checkboxen auch mit der Tastatur bedienen: Die nativen Inputs werden absolut positioniert und durch einen niedrigeren z-index von den gestalteten Elementen mit höherem z-index verdeckt.

    Antworten
    • Carsten A.
      schrieb am 26.08.2016 um 09:21 Uhr:

      Hallo Florence,

      der Übeltäter ist die CSS-Eigenschaft visibility:hidden. Wenn man diese durch opacity:0 ersetzt, bleibt das Element im auswählbaren Context erhalten und ist einfach 100% transparent.
      Was fehlt ist, dass man genau so wie :checked gestylet wurde, auch für :focus stylet (und z.B. einen blauen Rahmen und Schatten vergibt – ähnlich wie bei Textfeldern), damit man auch sehen kann auf welchem Element der Fokus durch Tastaturauswahl liegt.

      Ich habe für mich neben der oben beschriebenen Änderung auch folgendes in dem Beispiel vom Autor ergänzt:

      input[type=’checkbox‘]:focus + label::before, input[type=’radio‘]:focus + label::before {
      border-color: rgb(156,190,245);
      box-shadow: 0 0 0px 1px rgb(156,190,245), inset 0 0 0 2px white;
      }

      Beste Grüße,
      Carsten

      Antworten
      • Peter S.
        schrieb am 20.11.2018 um 13:27 Uhr:

        Der Vorschlag von Carsten A. hat noch einen weiteren Vorteil: die mit required gekennzeichneten Checkbox- und Radio-Tags zeigen die automatisch Meldung des Browsers nicth an, wenn man sie so ausblendet, wie oben angegeben.

        Mit opacity:0 dagegen wird der Browser-Hinweis weiterhin angezeigt. Mann muss nur ein wenig daran failen, dass er trotz der Manipulationen an der richtigen Stelle angezeigt wird.

  17. Alex
    schrieb am 03.05.2015 um 18:41 Uhr:

    Sehr cooler Beitrag. Weshalb nutzt du :not(checked)? Ich habe eben mal etwas rumgespielt und da funktioniert auch alles ohne diese Angabe, ist ja sozusagen die Standardformatierung oder hat das noch einen Grund?

    Antworten
    • Jonas Hellwig
      schrieb am 03.05.2015 um 21:17 Uhr:

      Mit :not(checked) können unerwünschte Effekte in Browsern die :checked nicht verstehen verhindert werden. Die Fallback-Lösungen in alten IEs sind somit einfacher, also mit weniger Code, umsetzbar.

      Antworten
  18. Hans
    schrieb am 30.03.2015 um 09:30 Uhr:

    phantastisch, „appearance“ ist toll, nie von gehört. habe bis jetzt immer select listen in einen wrapper getan und einfach 30PX rechts rausgeschoben so das man den pfeil nicht sieht, der nachteil ist halt das die ausgeklappte liste dann breiter ist.

    Antworten
  19. Birgit
    schrieb am 23.03.2015 um 14:15 Uhr:

    Super, vielen Dank für die ausführliche Anleitung! Listen sind ein Horror für mich ;-)
    Wo es bei mir jedoch immer hakt, sind nicht die Settings, die du oben beschrieben hast, sondern wenn ich eben diesen eine bestimmte Klasse zusätzlich zuordnen muss, um z.B. die Standard-Listen-Settings meines WP-Themes n i c h t zu überschreiben.
    Da weiß ich dann nie, wie man dann die Listenbefehle korrekt schreibt:
    .meineliste .input oder umgekehrt oder ohne Leerraum … Vielleicht eine Option für einen neuen Blogpost von dir? :-)

    Antworten

Kommentar zu dieser Seite

Wir freuen uns über Anregungen, Ergänzungen oder Hinweise zu Fehlern. Wir lesen jeden Eintrag, veröffentlichen aber nur, was den Inhalt sinnvoll ergänzt.

Website-Projekte mit kulturbanause

Wir wissen wovon wir reden. Wir realisieren komplette Projekte oder unterstützen punktuell in den Bereichen Design, Development, Strategy und Content.

Übersicht Kompetenzen →

Schulungen von kulturbanause

Wir bieten Seminare und Workshops zu den Themen Konzept, Design und Development. Immer up-to-date, praxisnah, kurzweilig und mit dem notwendigen Blick über den Tellerrand.

Übersicht Schulungsthemen →