Formulare/Auswahllisten
Oft gibt es in Formularen aber auch Buttons, die mehrere Möglichkeiten zur Auswahl bieten. Hier würde eine Verwendung von button-Elementen zwingend den Einsatz von JavaScript zur Auswertung erfordern.
Einfacher und „unkaputtbarer“ ist eine Verwendung von input-Elementen wie Radio-Buttons bzw. Checkboxen, die auch ohne JavaScript oder CSS noch funktionsfähig sind.
Alternativ kann man das select-Element verwenden, das aber nicht so gut mit CSS formatiert werden kann und deshalb etwas aus der Mode geraten ist.
Inhaltsverzeichnis
Radio-Buttons
Radio-Buttons (<input type="radio" ...>
) sind eine Gruppe von beschrifteten Knöpfen, von denen der Anwender einen auswählen kann. Sobald ein Radiobutton markiert wird, wird eine eventuell vorhandene Markierung eines anderen Radiobuttons derselben Gruppe gelöscht.
Folgende Attribute sind möglich:
-
name
: Alle Radio-Buttons, die den gleichen internen Bezeichnernamen haben, gehören zu einer Gruppe, d. h. von diesen Buttons kann der Anwender genau einen markieren. -
value
: bestimmt einen internen Bezeichnerwert für jeden Radio-Button (value = Wert). Wenn der Anwender das Formular abschickt, wird der Bezeichnerwert des markierten Buttons übertragen. -
checked
: Wenn du eine der Auswahlmöglichkeiten vorselektieren willst, dann notiere im<input>
-Tag des entsprechenden Radio-Buttons das boolesche Attributchecked
, also z. B.:<input type="radio" name="Typ" value="Kassenpatient" checked>
Beachte: Mehr als eine Auswahlmöglichkeit darf bei Radio-Buttons nicht vorselektiert werden.
Zu jedem input "type=radio" gehört ein label-Element, das als Beschriftung der jeweiligen Option erscheint. Es kann vor oder hinter dem Radio-Button stehen und ist mittels des for-Attributes mit der ID des zugehörigen Radio-Buttons verknüpft.
Eine solche Mehrfachauswahl ist für alle zugänglich:
- Mit der Tastatur kann man die Gruppe mit der Tab-Taste ( ⭾ ) ansteuern und dann mit der Leertaste auswählen. Mit Pfeil rechts ( → ) / unten ( ↓ ) geht es zum nächsten Button, der ausgewählt wird.
- Mit der Maus können die Radio-Buttons, aber auch die dazu gehörigen Beschriftungen angeklickt werden.
Checkboxen
Eine Checkbox (<input type="checkbox">
) ist ein ankreuzbares Kontrollfeld. Der Benutzer kann es auswählen oder die Auswahl entfernen.
<fieldset>
<legend>Zutaten</legend>
<input type="checkbox" name="zutat" value="kaese" id="check1" checked>
<label for="check1">Käse</label>
<input type="checkbox" name="zutat" value="schinken" id="check2">
<label for="check2">Schinken</label>
<input type="checkbox" name="zutat" value="salami" id="check3">
<label for="check3">Salami</label>
<input type="checkbox" name="zutat" value="oliven" id="check4">
<label for="check4">Oliven</label>
<input type="checkbox" name="zutat" value="paprika" id="check5">
<label for="check5">Paprika</label>
<input type="checkbox" name="zutat" value="pilze" id="check6">
<label for="check6">Pilze</label>
</fieldset>
Im Beispiel gibt es
- Radio-Buttons für den Boden, bei dem nur eine Auswahl möglich ist.
- Checkboxen für die Zutaten, von denen beliebig viele ausgewählt werden können.
Zu jedem input "type="checkbox" gehört ein Label-Element, der als Beschriftung der jeweiligen Option erscheint. Es kann vor oder hinter dem Ankreuzfeld stehen und ist mittels des for-Attributs mit der ID der zugehörigen Checkbox verknüpft.
Folgende Attribute sind möglich:
-
checked
: Wenn du eine (oder mehrere) Auswahlmöglichkeiten vorselektieren willst, dann notiere im<input>
-Tag der entsprechenden Checkbox das boolesche Attributchecked
-
readonly
: Boolean ; wenn vorhanden, wird das Erscheinungsbild abgeändert, so dass angezeigt wird, dass der Wert nicht geändert werden kann. -
value
: bestimmt einen internen Bezeichnerwert für jede Checkbox (value = Wert). Wenn der Anwender das Formular abschickt, wird der Bezeichnerwert des oder der markierten Buttons übertragen.
Die Werte von ausgewählten Checkboxen werden beim Absenden des Formulars mit übertragen.
Im Gegensatz zu Radio-Buttons müssen Checkboxen keine identische Namen haben, um zu funktionieren. Es ist aber hinsichtlich des auswertenden Skripts eventuell sehr sinnvoll, identische Namen zu verwenden, weil das Skript dann automatisch ein Array anlegen kann. PHP legt das Array automatisch an, wenn der Name auf "[]" endet.
Checkboxen in HTML kennen nur die Zustände ausgewählt und nicht ausgewählt. Der aus der grafischen Oberfläche von Betriebssystemen bekannte dritte Zustand mit der Bedeutung unbestimmt (engl. indeterminate), der oft gräulich oder mit einem Quadrat statt einem Haken dargestellt wird, kann nur mit JavaScript gesetzt werden.[1]
Normalerweise sind Radio-Buttons, Checkboxen und ihre labels Inline-Elemente, d.h. sie werden innerhalb einer Zeile nebeneinander dargestellt. Du kannst eine Gruppe durch div-Elemente oder innerhalb einer Liste untereinander platzieren.
In den oberen Beispielen wurde dies ohne weitere Elemente durch ein (leeres) Pseudoelement erreicht:
label::after {
content: "";
display: block;
}
Gestaltung mit CSS
Eine Formatierung mit color und background-color ist bei Radio-Buttons und Checkboxen nicht möglich.
Klassischer Umweg war das Ausblenden der Checkbox, die durch ein frei formatierbares Pseudoelement ersetzt wurde:
input[type="checkbox"] {
opacity: 0;
width: 0;
height: 0;
}
label::before {
content: '';
width: 1em;
height: 1em;
padding: 0.2em;
border: 2px solid green;
border-radius: 0 0.5em 0.5em;
margin-right: 0.5em;
display: flex;
justify-content: center;
align-items: center;
}
input:checked + label::before {
content: '✓';
background-color: lime;
border: 2px solid green;
}
Die Checkboxen werden visuell ausgeblendet, bleiben aber mit der Tastatur bedienbar. An ihre Stelle tritt ein Pseudoelement mit einem grünen, abgerundeten Rand.
Das oben erwähnte checked-Attribut kann mit dem :checked-Selektor ausgewählt und dann formatiert werden. In diesem Beispiel wird das Kästchen hellgrün gefärbt und erhält über die content-Eigenschaft ein Häkchen.
Der gleiche Selektor kann in Verbindung mit dem Nachbarselektor input:checked + label
das dazugehörende Label formatieren.
Checkboxen mit accent-color gestalten
Die Eigenschaft accent-color ermöglicht die Wahl einer Akzentfarbe, die Elemente wie input type="checkbox" oder type="radio" einfärbt. [2]
#base input {
accent-color: brown;
}
#toppings input {
accent-color: red;
}
#toppings .veg {
accent-color: lime;
}
input:checked + label {
font-weight: bold;
}
Probier' im Frickl andere Farben zu setzen (z.B. orange
anstelle des brown
und teste die Bedienung des Formulars mit der Tab-Taste. Die mit accent-color gesetzte Farbe wird je nach Helligkeit der Schriftfarbe als Hintergrund- oder Vordergrundfarbe verwendet.
Mit input:checked + label
werden die Beschriftungen ausgewählter Elemente selektiert und der Text fett dargestellt.
Radio-Buttons verstecken
Wenn Du Nutzern deiner Webseite eine Auswahl aus mehreren Möglichkeiten anbieten willst, ist ein Menü aus Radio-Buttons semantisch die beste Wahl. Häufig soll dies aber an das Seitendesign angepasst werden. Im folgenden Beispiel werden die Radio-Buttons versteckt – die Funktionalität bleibt als Standardverhalten auch ohne JavaScript erhalten.
<div class="toggle-buttons">
<input type="radio" id="b1" name="group-b"/>
<label for="b1">Pizza</label>
<input type="radio" id="b2" name="group-b"/>
<label for="b2">Pasta</label>
<input type="radio" id="b3" name="group-b" />
<label for="b3">Pommes</label>
</div>
Unser Menü besteht aus input-Feldern vom type="radio"
. Über den gemeinsamen name
ist festgelegt, dass nur eine Auswahl erlaubt wird.
Die folgenden label-Elemente werden über das for
-Attribut mit der id
des zugehörenden input-Elements verbunden. Damit kannst du den Radio-Button auch mit einem Klick auf die Erklärungen auswählen.
.toggle-buttons input[type="radio"] {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
.toggle-buttons label {
border: 1px solid #333;
border-radius: 0.5em;
padding: 0.5em;
}
.toggle-buttons input:checked + label {
background: #ebf5d7;
color: #5a9900;
box-shadow: none;
}
input:hover + label,
input:focus + label {
background: #ffebe6;
}
Über den Attributsselektor input[type="radio"]
werden alle Radio-Buttons mit Image Replacement visuell so ausgeblendet, dass ihre Funktionalität auch für Screenreader gewährleistet bleibt.
Labels erhalten einen (abgerundeten) Rand, der durch ein padding von 0.5em vergrößert wird.
Dabei müssen sowohl die Zustände, wie auch das Verhalten mit CSS gekennzeichnet werden:
- Bei der Auswahl eines Radio-Buttons wird über den Nachbarselektor
input:checked + label
das dazugehörende Label grün eingefärbt. Ein evtl. vorher angeklickter Button verliert dann seine Pseudoklassechecked
und fällt wieder in seinen Urzustand zurück. - Wenn man einen (unsichtbaren) Radio-Button mit der Tastatur ansteuert, wird das Label entsprechend (
input:focus + label
) mit einem roten Hintergrund gekennzeichnet.
Es gibt im SELF-Wiki einige Anwendungsbeispiele, die dieses Prinzip verwenden:
- Im Mathe-Quiz kann so der gewünschte Operator ausgewählt werden.
- Im Lotto-Tutorial wird so ein Lotto-Auswahlfeld nachgebaut.
- Das Multiple-Choice-Quiz ermöglicht eine Auswahl zwischen möglichen Antworten.
Toggle-Schalter
Ein toggle-Switch oder FlipFlop-Schalter ist ein Software-Feature, das zwischen zwei Zuständen hin- und her schaltet.
<label>
An-/Aus-Schalter
<input type="checkbox">
<span></span>
</label>
Für das Beispiel verwenden wir ein input-Feld vom type="checkbox"
, das zusammen mit einem span-Element in einem label-Element verschachtelt ist.
.toggle label {
position: relative;
display: inline-block;
width: 10em;
height: 3.5em;
}
.toggle input {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
.toggle .slider { /* Grundfläche */
position: absolute;
cursor: pointer;
top: 1.5em;
left: 3em;
width: 4em;
height: 2em;
background-color: #c82f04;
border-radius: 1em;
transition: all .3s ease-in-out;
}
.toggle .slider::before { /* verschiebbarer Button */
position: absolute;
content: "";
height: 1.6em;
width: 1.6em;
left: .2em;
bottom: .2em;
background-color: white;
border-radius: 50%;
transition: all .3s ease-in-out;
}
Das Label wird zum Ausgangspunkt des Schalters, an dem absolut ausgerichtete Elemente orientiert sind.
Die Checkbox wird ausgeblendet. Allerdings ist sie trotzdem funktionsfähig und ihr Zustand kann mit einem Klick auf das Label aktiviert werden.
Die Grundfläche des Sliders span class="slider"
wird absolut unterhalb der Beschreibung positioniert.
Mit .slider::before{}
wird nun ein Pseudoelement absolut über die Grundfläche positioniert. Es erhält die Form eines kreisförmigen, weißen Buttons.
.toggle input:checked + .slider {
background-color: #5a9900;
}
.toggle input:checked + .slider::before {
transform: translateX(1.9em);
}
Sobald der Schalter angeklickt wird, ändert sich der Zustand der (nicht sichtbaren) Checkbox. Über die Pseudoklasse checked und den Nachbarselektor wird nun die Hintergrundfarbe der Grundfläche und die Position des weißen Buttons verändert.
.text .slider::before { /* Text vor dem Toggle-Schalter */
position: absolute;
content: "AUS";
color: #c82f04;
font-weight: bold;
height: 1.6em;
left: -2.5em;
bottom: .2em;
}
.text input:checked + .slider::after { /* Text hinter dem Toggle-Schalter */
position: absolute;
content: "AN";
color: #5a9900;
left: 4.5em;
}
Das untere Beispiel erhält ein weiteres Pseudoelement. Mit der content-Eigenschaft erhält es eine Beschreibung des Zustands in der passenden Farbe.
Sobald der Schaltzustand geändert wird, wird ein neuer Text an anderer Stelle und in einer anderen Farbe eingeblendet.
Information: Toggle-Switch
Dieses Beispiel ist universell einsatzfähig und benötigt kein JavaScript. Allerdings müssten die Klassen noch einmal angepasst werden, damit sie nicht mit CSS-Festlegungen für andere Checkboxen kollidieren.
Zweites Problem: Toggles innerhalb von Formularen übertragen ihren Zustand beim Absenden mit.
Deshalb gibt es immer mehr Rufe nach einem eigenen Element, in dem dies gekapselt ist.
Siehe auch:
- Web Components
- SELF-Blog: <toggle-switch> - Kippschalter mit Custom Elements vom 31.10.2024
Exkurs: Checkbox-Hack
Achtung!
Das dabei entstehende Stylesheet ist recht komplex und die Seite ist nicht barrierefrei. Zudem verstößt der Einsatz gegen die separation of concerns, die Trennung von Inhalt, Präsentation und Verhalten.
Das folgende Beispiel sollte daher als proof of concept angesehen werden. Es werden (wie für die meisten Varianten des Checkbox-Hacks) einige nicht-triviale CSS-Eigenschaften bzw. Selektoren genutzt:
- Der Klassenselektor
- Der Geschwisterkombinator ~
- Das Pseudoelement before
- Die dynamische Pseudoklasse checked
-- Matthias Scharwies (Diskussion) 08:36, 2. Jan. 2021 (CET)
<h2>Lesbarkeit</h2>
<p>Lieber Kunde und Leser, falls Sie keine Probleme haben, [...weiterer Blindtext...] par excellence.<br>
<input type="checkbox" class="hackbox mehr_lesen" id="mehr_lesen_lesbarkeit">
<span class="volltext">Er hat diesen Copyblock weder [...weiterer Blindtext...] Arbeit haben.<br></span>
<label class="mehr_lesen" for="mehr_lesen_lesbarkeit"> lesen...</label>
</p>
/* allgemeines */
input.hackbox {
display:none;
}
/* default-Zustand */
span.volltext {
display:none;
}
label.mehr_lesen {
color:#0091D2;
}
label.mehr_lesen::before {
content:" mehr";
color:#0091D2;
}
/* bei gesetztem Haken */
input.mehr_lesen:checked ~ span.volltext {
display:inline;
}
input.mehr_lesen:checked ~ label.mehr_lesen::before {
content:" weniger";
color:#0091D2;
}
Auswahllisten mit select
Du kannst dem Anwender mit dem select-Element eine Auswahliste mit festen Einträgen anbieten, aus der er einen Eintrag auswählen kann. Diese Einträge werden innerhalb eines option-Elements notiert. Der Text des ausgewählten Eintrags wird übertragen, wenn der Anwender das Formular abschickt.
Das select-Element zeichnet Auswahllisten aus.
Folgende Attribute sollten / können hinzugefügt werden:
-
name
: interner Bezeichnername, damit ihr Wert von der Zielseite verarbeitet werden kann. -
size
: bestimmt die Anzeigegröße der Liste, also die Anzahl der Zeilen bzw. gleichzeitig anzuzeigenden Einträge. Wenn die Liste mehr Einträge enthält als angezeigt werden, kann der Anwender in der Liste scrollen.
Wennsize="1"
beträgt oder das Attribut fehlt, ensteht eine so genannte „Dropdown-Liste“.
label
-Element hinzufügst. Insbesondere Nutzer mit assistiven Technologien könnten sonst unter Umständen dein Formular nicht mehr benutzen.option definiert jeweils einen Eintrag der Auswahlliste. Hinter <option>
muss der Text des Listeneintrags stehen. Du kannst so viele Listeneinträge definieren, wie du willst. Ein Abschluss-Tag </option>
ist zwar optional, im Hinblick auf verarbeitende Programmiersprachen aber dringend zu empfehlen.
Die Breite der Listenanzeige wird automatisch ermittelt, abhängig vom längsten Eintrag an, es sei denn, du formatierst die Breite mit CSS.
Auswahllisten mit Mehrfachauswahl
Wenn nichts anderes angeben, kann der Anwender aus einer Auswahlliste genau einen Eintrag auswählen. Du kannst mit dem multiple-Attribut eine Mehrfachauswahl erlauben.
Du solltest deshalb für eine Mehrfachauswahl nicht select, sondern besser Checkboxen verwenden.
Falls du für eine spezielle Zielgruppe dennoch Mehrfachauswahl verwendest, solltest du darauf hinweisen, dass mehrere Einträge auswählbar sind. Auf modernen PC-Tastaturen geschieht das normalerweise durch Halten der Strg-Taste bei gleichzeitigem Anklicken der gewünschten Listeneinträge. Macintosh-Benutzer verwenden dafür die Befehlstaste.
Bitte beachte auch, dass die Notation von []
im Namen des select
Elements abhängig davon ist, wie die Formulardaten auf dem Webserver verarbeitet werden. Wenn du PHP benutzt, sind die eckigen Klammern unbedingt erforderlich, weil du andernfalls nur einen der ausgewählten Werte in $_POST
oder $_GET
vorfindest. Durch die Klammern erzeugt PHP im $_GET bzw. $_POST Array ein Subarray mit den ausgewählten Werten. Du findest dazu an dieser Stelle Hinweise im PHP Handbuch. Andere Programmiersprachen machen das möglicherweise anders.
Solltest du das select
Element mittels JavaScript über seinen Namen ansprechen wollen, so beachte bitte die Hinweise für den Zugriff mit JavaScript; ein Name wie "top5[]" ist nur über die Indexschreibweise (Schema 4) erreichbar.
Einträge vorselektieren
Wenn nichts anderes angeben, ist zunächst kein Eintrag einer Auswahlliste vorselektiert. Du kannst einen Eintrag mit dem selected-Attribut vorselektieren. Vorselektierte Einträge haben einen sichtbaren Markierungsbalken.
In Verbindung mit Mehrfachauswahl können auch mehrere Einträge vorselektiert werden.
Absendewert von Einträgen bestimmen
Normalerweise wird beim Absenden des Formulars der Text eines ausgewählten Listeneintrags übertragen, der zwischen <option>
und </option>
notiert ist.
Um für einen Eintrag der Auswahlliste einen anderen Absendewert zu bestimmen, gib im einleitenden <option>
-Tag des betreffenden Eintrags das Attribut value
an (value = Wert). Als Wert weist du den gewünschten Absendewert zu. Beim Absenden des Formulars wird dann der hier bestimmte Text eines ausgewählten Eintrags übertragen, nicht der Text, der dem Anwender beim Listeneintrag angeboten wurde.
<script>
document.addEventListener('DOMContentLoaded', function () {
document.Testform.Pizza.addEventListener('change', CheckAuswahl);
function CheckAuswahl () {
var menu = document.Testform.Pizza;
document.querySelector('output').innerHTML = menu.options[menu.selectedIndex].value;
}
});
</script>
<form name="Testform">
<label>Bitte wählen Sie Ihre Pizza-Bestellung:
<select name="Pizza" size="9">
<option value="P101">Pizza Napoli</option>
<option value="P102">Pizza Funghi</option>
<option value="P103">Pizza Mare</option>
<option value="P104">Pizza Tonno</option>
<option value="P105">Pizza Mexicana</option>
<option value="P106">Pizza Regina</option>
<option value="P107">Pizza della Casa</option>
<option value="P108">Pizza Calzone</option>
<option value="P109">Pizza con tutto</option>
</select>
</label>
</form>
Im obigen Beispiel ist im einleitenden <select>-Tag ein so genannter Event-Handler notiert. Diesem wird im Beispiel eine JavaScript-Anweisung zugewiesen, die bewirkt, dass ein Meldungsfenster den internen Absendewert des Eintrags zur Kontrolle ausgibt, sobald der Anwender einen Eintrag selektiert.
select und CSS
Die Gestaltung mit CSS ist bei select-Menüs nur begrenzt möglich. Sie übernehmen ihr Aussehen vom Betriebssystem des Nutzers. Auf mobilen Geräten werden sie sogar aus der Seite herausgelöst und in einem eigenen Popup dargestellt.
Die CSS-Eigenschaft appearance (engl. Aussehen, Erscheinung) sollte es ursprünglich ermöglichen, Formularelementen ihr betriebssystemspezifisches Aussehen zu nehmen. Die Umsetzung ist aber nicht zufriedenstellend.[4][5]
select {
display: block;
font-size: 1.5em;
padding: .6em 1.4em .5em .8em;
width: 20em;
max-width: 100%; /* useful when width is set to anything other than 100% */
box-sizing: border-box;
margin: 0;
border: 1px solid #aaa;
box-shadow: 0 1px 0 1px rgb(0 0 0 / .04);
border-radius: .5em;
-webkit-appearance: none;
appearance: none;
background-color: transparent;
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082,0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
background-repeat: no-repeat, repeat;
/* arrow icon position (1em from the right, 50% vertical) , then gradient position*/
background-position: right .7em top 50%, 0 0;
/* icon size, then gradient */
background-size: .65em auto, 100%;
}
/* Hide arrow icon in IE browsers */
select::-ms-expand {
display: none;
}
Alternativ könntest du ein Menü mit Radio-Buttons realisieren, diese mit CSS verstecken und die dazugehörigen label-Elemente entsprechend stylen.
Ausblick: selectlist
Aufgrund der oben beschriebenen Probleme das select-Element individuell zu gestalten schufen Designer eigene Lösungen, die oft nicht zugänglich waren. Die open-ui-Initiative will das select-Element mit Attributen und Kindelementen wie selectlist erweitern und entwickelt derzeit einen Vorschlag.[6]
In Chrome, Edge und Opera kannst du die hinter einem flag versteckte Implementation bereits testen.
Siehe auch
- JavaScript und Formulare
- JavaScript/DOM/Document/forms/elements/options
- change-Event
Weblinks
- ↑ MDN: Checkboxen mit unbestimmbarem Wert
Mit JavaScript kann man eine Checkbox auf aufinputInstance.indeterminate = true;
setzen.
Eine Checkbox im indeterminate-Status hat in den meisten Browsern eine horizontale Linie in der Box anstatt eines Häkchens. - ↑ smashing magazine: Simplifying Form Styles With accent-color von Michelle Barker, 23.09.2021
- ↑ css-Tricks: Stuff you can do with the “Checkbox Hack”
- ↑ macrone.de: Das HTML Select-Element: Styling mit pure CSS
- ↑ css-tricks: Styling a Select Like It’s 2019
- ↑ Stylable Select Element (Explainer) (open-ui.org)
- Inclusively Hiding & Styling Checkboxes and Radio Buttons 16 Jun, 2020 (Sara Soueidan)