Formulare entwickeln

Kurz zusammengefasst vorweg: Benutze immer einen <form> tag, benutze die richtigen input types, gibt jedem input ein label und füge immer einen Submit-Button hinzu.

Am besten beginnt man die Entwicklung mit einem Prototypen mit nativen Formular-Elementen, hier sind Dinge wie Serverabfragen oder eine funktionierende Datenübermittlung noch nicht relevant. Dieser Prozess soll dabei helfen, einen Einblick darüber zu erlangen, ob das, was von PO und Design ausgearbeitet wurde, tatsächlich sinnvoll ist. Beim Testen des Prototypen sollten auch die Funktionen für Barrierefreiheit, welche bereits im Browser integriert sind, getestet werden. Diese Funktionen befinden sich in den meisten Browsern unter den Entwicklerwerkzeugen. In Firefox kann man z. B. unter dem Reiter Barrierefreiheit die komplette Seite nach Problemen in der Barrierefreiheit scannen. Somit gewinnt man einen ersten Überblick über mögliche Probleme.

Nachdem der erste Prototyp erfolgreich erstellt und provisorisch getestet wurde, kann nun die technische Umsetzung erfolgen. Bei diesem Schritt ist wichtig,  dass hinzukommende Funktionen keinen negativen Einfluss auf die Barrierefreiheit haben.

Danach muss das Formular dann auf Herz und Nieren geprüft werden. Es können Tools wie z.B. Accessibility Checker von IntentLighthouse von Google oder browserinterne Tools) genutzt werden, um die Navigation, die Lesbarkeit, den Kontrast, die Fehlermeldungen und die Darstellung auf mobilen Endgeräten zu testen.

Aufbau von Formularen genauer betrachtet

Semantik

Semantik spielt in jedem Teil eine Rolle, deshalb macht es Sinn, damit zu beginnen.

  • Immer mit einem <form> Tag starten (hilft bei der Barrierefreiheit und bei ausgeschaltetem Javascript)

Benutzen von nativen Form-Elementen, diese kommen mit den richtigen eingebauten nativen Formular-Elementen. Dies gilt vor allem auch für Checkboxen und Radios. Sowie: Verwenden des richtigen input-types.

Grafik als Hilfe zum Bestimmen des Formular-Elements und Input-Types
Hilfe zum Bestimmen des Formular-Elements und Input-Types
  • Auch wenn das Design nicht so aussieht wie die zur Verfügung stehenden input types, sollte man sie erstmal semantisch richtig und als solide Basis anlegen. Das Aussehen kommt dann später.
  • Wenn input Felder zueinander gehören, sollten sie in einem fieldset gruppiert werden (wichtig z. B. bei mehreren Feldern, die alle nach einem Vornamen und Nachnamen fragen). Der häufigste Anwendungsfall ist hier gruppierte Radios und Checkboxen. Fieldset braucht dann auch ein legend.
  • Sehr wichtig: Jeder Input bekommt einen Namen und immer ein Label (kein Platzhalter, kein title, sondern ein – am besten „explicit label„!)
  • Immer einen Submit-Button vorsehen (es ist kein valides html ohne, Probleme für Screenreader, manche Browser können so nicht abschicken). Submit-Button geht mit input type=“submit“ oder button type=“submit“. Bei letzterem braucht es eigentlich kein type, es ist aber guter Stil, es anzugeben.

Quelle: How to Build HTML Forms Right: Semantics

Barrierefreiheit bei Formularen

Richtig eingesetzte Semantik führt auch gleich zu mehr Barrierefreiheit.

Labels

Dazu gehören labels und die beste Art, diese einzusetzen ist „explicit“, also ein <label for=“xy“> mit <input id=“xy“>. Sie ist für besser geeignet für die Stimmkontrolle über Geräte. Aria-labels sind auch möglich, aber explicit labels sind immer am besten.

Für explicit label braucht man „for“ und eine „id“. Sich diese zu überlegen, kann schwierig werden bei langen Formularen, oder mehreren auf einer Seite. Deshalb kann man sich mit einem String-Generator behelfen, der eindeutige Strings generiert. Die for und id’s müssen keinen Sinn ergeben.

Bekommt der Entwickler vom Design eine Vorlage, die nur aus einem Feld mit Placeholder und keinem Absende-Button besteht, kann er sich mit css behelfen und eine Klasse anlegen, die Dinge visuell versteckt, z. B.

.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
width: 1px;height: 1px;
margin: -1px;border: 0;
padding: 0;}

Html:

<form> <label for="search"> <span class="visually-hidden">Search</span></label>  <input id="search" name="search" /> <button class="visually-hidden">Submit</button> </form>

Um auch Tab-Tasten Nutzer zu helfen kann man noch folgendes im css anlegen, dann erscheint der Button, wenn er den Fokus erhält.

button.visually-hidden:focus, input[type="submit"].visually-hidden:focus {
position: fixed;
top: 10px;
left: 10px;
clip: unset;
width: unset;
height: unset;
border: 3px solid;
padding: 5px;
background: #fff;
}

name

Bei jeden Input muss ein name=““ dabei stehen, da manche inputs (vor allem radio) ohne name sich nicht so verhalten wie erwartet. Außerdem lässt sich das Formular so einfacher absenden.

Status von Formular-Inputs

  • Pflichtfelder: durch das Einfügen von „required“ bekommt assistive Technologie schon mehr Informationen
  • Tipp: Wenn man gemäß dem Design einen Stern hinter das Label machen muss, um das Feld als Pflichtfeld zu kennzeichen (z. B. E-Mail*), sollte man den Stern mit aria-hidden verstecken, damit er nicht vorgelesen wird. Wird der Stern über css und content: eingebunden, sollte man im css „speak: never;“ definieren. Damit dann aber auch Screenreader-Nutzer wissen, dass es sich um ein Pflichtfeld handelt, geht man so vor:

    Eine robuste Lösung für alle ist die folgende: das Wort Pflichtfeld oder * dazu schreiben, und dann per aria-hidden vor Screenreadern verstecken, plus das Pflichtfeld für Screenreader und Braille output dann mit aria-required oder required anzeigen lassen.
    <label for="email">Email <span aria-hidden="true">(required)</span></label>
    <input type="text" aria-required="true" id="email" name="email">


  • Sperren von Feldern geht einfach über das Einfügen von „disabled“
  • Fokus: Den Fokus Status überall gut umzusetzen ist einer der herausfordernsten Themen der Barrierefreiheit. Niemals den Fokus-Ring komplett entfernen!
  • Bei Checkboxen und Radios gibt es nicht so viele Möglichkeiten, die nativen Elemente zu stylen, deshalb kann man sich hier mit ein paar Tricks behelfen, hier ein Beispiel, bei dem die Beschriftung den Fokus erhält:

    <input name="example" type="checkbox" class="visually-hidden" /> <span class="custom-checkbox">Input label text</span>

    Css:
    input:focus + .custom-checkbox {
    outline-width: 1px;
    outline-style: auto;
    outline-color: Highlight;
    outline-color: -webkit-focus-ring-color;
    }
  • Ungültig: Man kann auch hier auf die bei html eingebauten Validierungsmechanismen verwenden

Quelle: How to Build HTML Forms Right: Accessibility

Checkliste für Barrierefreiheit bei Formularen

Styling

Vor dem Styling muss auf jeden Fall erst mal die Semantik und die Barrierefreiheit stimmen. Das Stylen mancher Formular-Elemente kann schwierig sein, mehr dazu findet man bei MDN’s “Advanced Form Styling”. Ein guter Ansatz ist, mit globalen Styles für alle inputs und einer „visually-hidden“ Klasse zu beginnen.

Beispiel:

input, select, textarea {
width: 100%;
max-width: 100%;
font: inherit;
color: inherit;
}

input[type="checkbox"], input[type="radio"], input[type="submit"], input[type="button"] {
width: auto;
}

fieldset, legend {
margin: 0;
border: 0;
padding: 0;
}

.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
}

Die Hauptpunkte sind:

  • Auf Semantik und Barrierefreiheit fokussieren bevor es ans Stylen nach Design geht
  • Die „visually-hidden” Klasse ist eine wichtige Sache in jedem Projekt
  • Die „appearance property” und CSS Kombinatoren bringen einen sehr weit
  • Testen! Die verschiedenen inputs müssen in all ihren Stati getestet werden
  • Versuchen, alles zu verwenden, was die Plattform bietet, um konsistente und barrierefreies Erleben zu ermöglichen

Mehr dazu und viele Code-Beispiele finden sich auf der Website von Austin Gil:

Quelle: How to Build HTML Forms Right: Styling

Stylen eines Pfichtfeldes

required-Felder können mit der CSS-Pseudoklasse :required gestaltet werden.

input:required {
  border: 2px solid purple;
}

Stylen für ungültige Eingaben

Mit der Pseudoklasse :invalid kann man ungültigen Formularsteuerelementen Stile hinzufügen. Man sollte sich bei der Gestaltung aber nie nur auf Farbe verlassen, sondern noch etwas dazufügen, z. B. Rahmenstärke oder ein Icon.

input:invalid {
border: 3px solid red;
}

Hinweis: Die Arbeit mit :invalid ist in der Praxis nicht ganz einfach. Ungültige Formularfelder sind bereits vor der Nutzerinteraktion als :invalid gekennzeichnet, was Nutzer verwirren könnte. Die Pseudoklasse :user-invalid löst dieses Problem, da die Stile erst nach einer Nutzerinteraktion angewendet werden. Weitere Informationen zu :user-invalid.

Generelles

  • Den Browser davon abhalten neu zu laden (Info, wenn man auf Aktualisieren klickt – per javascript)
  • Ungesicherte Änderungen speichern
  • Copy/Paste erlauben

Input Funktionalität

  • inputmode: Nutzer an Mobilgeräten bekommen dadurch eine andere Tastatur angezeigt
  • autocomplete: praktisch für sich wiederholende Informationen, siehe unten.
  • autofocus: Gut für Seiten, auf denen das Formular der Hauptinhalt ist
  • auto-expanding textarea: Nettes Feature, wenn man nicht immer so viel Platz für die Textarea vorsehen möchte (js)
  • Verhindern des Scrollens mit dem Mausrad bei input type „number“: Kann praktisch sein, damit der Wert nicht verändert wird, wenn der Nutzer auf der Seite nach unten oder oben scrollen will.

Mehr zu autocomplete:

Mit Autocomplete-Attributen können Nutzer visuelle Präsentationen personalisieren und beispielsweise ein Geburtstagskuchensymbol in einem Feld anzeigen, dem das Attribut für die automatische Vervollständigung von Geburtstagen (bday) zugewiesen ist. Im Allgemeinen machen Attribute für die automatische Vervollständigung das Ausfüllen von Formularen einfacher und schneller. Dies ist besonders hilfreich für Menschen mit kognitiven und Lesestörungen sowie für Menschen, die ATs wie Screenreader verwenden.

<form id="sundae-order-form">
  <p>Name: <input type="name" autocomplete="name"></p>
  <p>Telephone: <input type="tel" autocomplete="tel"></p>
  <p>Email address: <input type="email" autocomplete="email"></p>
</form>

Quelle: HTML attribute: autocomplete

Validierung

  • Man kann beim Absenden des Formulars validieren oder auch beim „blur“ Event (also wenn ein Input den Focus verliert)
  • Wichtig ist, den Nutzer zu informieren, was valide ist und was nicht. Guter Ansatz: Die Info in normalem Text unter das input schreiben und mit aria-labelledby am input  für assistive Technologien zugänglich machen
  • Alle Fehler auf einmal zurückgeben und gut beschreiben wo der Fehler ist und wie er korrigiert werden kann, damit das Formular nicht mehrmals abgelehnt wird
  • Mehr Info zu Validierung

Versenden

  • Mit Javascript versenden ist besser
  • Update des Status: Wird gersendet, wurde erfolgreich gesendet, wurde nicht erfolgreich gersendet
  • Zum ersten auftretenden Fehler hinscrollen

Quelle zu Generelles, Input Funktionaliät, Auto, Validerung und Versenden: How to Build HTML Forms Right: User Experience

Sicherheit

Infos und Gedanken dazu auf „How to Build HTML Forms Right: Security„. Der Artikel ist allerdings etwas veraltet.

Welche input types gibt es und was ist sonst wichtig?

Mehr dazu welche Eingabe-Felder es gibt und Überlegungen dazu finden sich im Blogartikel zum Formular-Design.

Wichtig zu erwähnen bei Text-Eingabefeldern:

  • Immer überdenken, welcher input type am besten geeignet sein könnte.
  • Statt number eher mit pattern arbeiten, z. B. [0-9]*
    Beispiel für nur Kleinbuchstaben und nicht mehr als 20 Zeichen:
    <label for="animal">What is your favorite animal? (required)</label>
    <input required pattern="[a-z]{2,20}" type="text" id="animal" name="animal">

Beschreibungen sind wichtig

Auch wenn es in HTML eingebaute Validierung Mechanismen und es auch einige robuste Javascript-Validierungs Bibliotheken gibt, ist es effektiver, den Nutzern vor dem Ausfüllen des Formulars mitzuteilen, welche Informationen in welcher Form gefordert werden. Manche Felder sind ziemlich offensichtlich, andere brauchen etwas mehr Beschreibung, wie zum Beispiel beim Einrichten eines Passworts, hierbei darf man auch die Nutzer von assistiver Technologie nicht vergessen.

Ein solche Beschreibung kann man visuell durch Nähe mit dem Feld in Verbindung bringen und auch über das aria-describedby Attribut. So kann man auch Validierungs-Regeln gut mitteilen.

<div>
<label for="password">Password</label>
<input required minlength="8" id="password" name="password" type="password" aria-describedby="password-requirements">
<p id="password-requirements">Enter at least 8 characters.</p>
</div>

Flexibel sein

Flexibel zu sein ist besser, z. B. bei Telefonnummern sollte man ein normales Textfeld nehmen, damit der Nutzer es eingeben kann wie er möchte. Man könnte aber eine Info dazu schreiben, welches Format man möchte. Für Nutzer an Mobilgeräten kann man über das Attribut „inputmode“ die passende Tastatur anzeigen lassen (z. B. <input inputmode=“tel“>

Hier gibt es Beispiele dazu (mit Mobilgerät öffnen zum testen)

Man kann auch mit javascript die unerwünschten Zeichen vom Wert des Inputs herausfiltern (über das Hinzufügen eines Event-Handlers zum blur Event).

Einfach halten

Der angesprochene „inputmode“ macht es für Mobilgerät-Nutzer einfacher, ein Formuar auszufüllen.

Umsetzungs-Beispiele

Ein „echtes“ Beispiel von der Website der britischen Regierung: ein Feedback-Formular über der Fußzeile (Report a problem with this page), das sich hinter einem Button versteckt, nutzt die ARIA-Attribute, um Screenreader-Benutzern zu helfen, das Formular zu finden und es korrekt auszufüllen.

Beispiel Markup und Erklärungen

Text-Eingabefelder

<label for="name">Name:</label>
<input id="name" type="text" name="textfield">

Passende „for“ und „id“ Werte assoziieren das Label mit dem entsprechenden Eingabefeld. Da jede id auf der Seite eindeutig sein muss, kann nur ein Label zu jedem einzelnen Formularelement zugeordnet werden. Das bedeutet, dass Sie nicht ein Label für mehrere Formularelemente benutzen können. Darüber hinaus unterstützen Bildschirmlesegeräte nicht die Anzeige von mehreren Labels, die mit einem Formularelement assoziiert sind.

Anmerkung
Ein weiterer Vorteil der Verwendung von Labels ist, dass der Benutzer auf das Label klicken kann und damit den Fokus auf das zugehörige Formularelement setzt. Dies ist nützlich für Menschen mit motorischen Behinderungen, insbesondere bei der Auswahl von kleinen Checkboxen und Radio-Buttons. Auf benachbarte Label zu klicken, bietet einen einfachen Weg um zu überprüfen, ob das Formular richtig gekennzeichnet ist.

Textbereiche

<label for="address">Fügen Sie ihre Adresse ein:</label><br>
<textarea id="address" name="addresstext"></textarea>

Checkboxen

<fieldset>
<legend>Wählen Sie ihre Pizza Zutaten aus:</legend>
<input id="ham" type="checkbox" name="toppings" value="Schinken">
<label for="ham">Ham</label><br>
<input id="pepperoni" type="checkbox" name="toppings" value="Pepperoni">
<label for="pepperoni">Pepperoni</label><br>
<input id="mushrooms" type="checkbox" name="toppings" value="Pilze">
<label for="mushrooms">Mushrooms</label><br>
<input id="olives" type="checkbox" name="toppings" value="Oliven">
<label for="olives">Olives</label>
</fieldset>

Das <fieldset> umgibt die gesamte Gruppierung von Radio-Buttons. Das <legend> liefert eine Beschreibung für die Gruppierung. Bildschirmlesegeräte stellen den Legendentext für jedes Eingabefeld aus <fieldset> einzeln dar. Der Legendentext sollte aus diesem Grund kurz und aussagekräftig sein.

Radio-Buttons

<fieldset>
<legend>Wählen Sie eine Versandart aus:</legend>
<input id="overnight" type="radio" name="shipping" value="Über Nacht">
<label for="overnight">Über Nacht</label><br>
<input id="twoday" type="radio" name="shipping" value="2 Tage">
<label for="twoday">2 Tage</label><br>
<input id="ground" type="radio" name="shipping" value="3 bis 6 Tage>
<label for="ground">3 bis 6 Tage</label>
</fieldset>

Anmerkung
<fieldset> und <legend> sollten nur dazu verwendet werden, um Gruppen von Eingabefeldern zu verknüpfen, wenn eine umfassendere Beschreibung (d.h. die Legende) notwendig ist. Einzelne Checkboxen oder einfache Radio-Buttons (wie männlich / weiblich für Geschlecht), die aufgrund ihrer Labels sinnvoll und eindeutig sind, benötigen kein <fieldset> oder <legend>. Verschachtelte <fieldset>s sollten generell vermieden werden.

Mehr zu legend und fieldset unter Fieldsets, Legends and Screen Readers again
Weiteres gutes Beispiel: MagentaA11y – Radio Button
Weitere Formular-Elemente: MagentaA11y – Demos

Auswahlmenüs

<label for="favcity">Choose your favorite city?</label>
<select id="favcity" name="select">
<option value="1">Amsterdam</option>
<option value="2">Buenos Aires</option>
<option value="3">Delhi</option>
<option value="4">Hong Kong</option>
<option value="5">London</option>
<option value="6">Los Angeles</option>
<option value="7">Moscow</option>
<option value="8">Mumbai</option>
<option value="9">New York</option>
<option value="10">Sao Paulo</option>
<option value="11">Tokio</option>
</select>

Um die Barrierefreiheit dieser Liste noch weiter zu verbessern, könnten wir die Option optgroup, zu der Gruppe hinzufügen:

<label for="favcity2">Choose your favorite city?</label>
<select id="favcity2" name="favcity2">
<optgroup label="Asia">
<option value="3">Delhi</option>
<option value="4">Hong Kong</option>
<option value="8">Mumbai</option>
<option value="11">Tokio</option>
</optgroup>
<optgroup label="Europe">
<option value="1">Amsterdam</option>
<option value="5">London</option>
<option value="7">Moskau</option>
</optgroup>
<optgroup label="North America">
<option value="6">Los Angeles</option>
<option value="9">New York</option>
</optgroup>
<optgroup label="South America">
<option value="2">Buenos Aires</option>
<option value="10">Sao Paulo</option>
</optgroup>
</select>

Beachten Sie, dass optgroup nicht von allen Endgeräten und Bildschirmlesegeräten unterstützt wird, aus dem Grund sollten wichtige Gruppeninformationen nicht damit dargestellt werden. In Fällen, in denen optgroup nicht unterstützt wird, wird es einfach ignoriert. Verwechseln Sie nicht das label-Attribut des optgroup-Elements mit dem label Element. Hier handelt es sich um grundverschiedene Dinge.

Multiple Select Auswahlmenüs erlauben dem Nutzer mehr als nur eine Option aus einer Liste zu wählen.

<select id="favcities" multiple="multiple" name="select">
<option value="1">Amsterdam</option><option value="2">Buenos Aires</option><option value="3">Delhi</option><option value="4">Hong Kong</option><option value="5">London</option><option value="6">Los Angeles</option><option value="7">Moscow</option><option value="8">Mumbai</option><option value="9">New York</option><option value="10">Sao Paulo</option><option value="11">Tokyo</option>
</select>

Anmerkung
Es wird empfohlen, multiple select Auswahlmenüs zu vermeiden. Nicht alle Browser bieten eine intuitive Navigation mit der Tastatur für mehrere Auswahlmenüs. Viele Anwender wissen nicht, dass Sie STRG/ CMD oder Shift + Klick verwenden müssen, um mehrere Elemente auszuwählen. Normalerweise kann ein Satz von Checkboxen ähnliche Optionen, aber mehr barrierefreie Funktionalität bereitstellen.

Buttons

Für Formular-Buttons (absenden und Eingabefelder leeren), ist keine weitere Information für die Barrierefreiheit erforderlich. Das Wert-Attribut für Eingabe-Buttons und der verschachtelte Text für <button>-Elemente werden von Bildschirmlesegeräten erkannt, wenn der Button ausgewählt wird. Dieses Attribut darf nie leer sein.

<input type="submit" name="Suchen" value="Submit Search">
<input type="reset" name="reset" value="Reset">
<button>Aktivieren</button>

Da Reset-Buttons versehentlich ausgewählt werden können, gibt es nur wenige Fälle, in denen sie bereitgestellt werden sollten.

Bilder-Buttons

Wenn Sie einen Bild-Button (<input type=“image“>) einem Standard-Button bevorzugen, muss der Input einen entsprechenden alt-Text haben.

<input type="image" name="submitbutton" alt="search" src="submit.png">

JavaScript Sprungmenü

Da diese Arten von Menüs aktiviert werden, wenn der oberste Menüpunkt geändert wird, können diese Menüs Probleme mit der Barrierefreiheit bei Tastatureingaben mit sich führen, weil sie nicht durch Listen blättern können, ohne eine der Optionen auszuwählen.

Die Bereitstellung des Absende-Buttons getrennt von der Auswahlliste erlaubt, aktuell ausgewählte Elemente barrierefrei für Tastaturen zu aktivieren.

Anmerkung:
Manche Browser (inklusive Firefox) überschreiben diese Sprungmenüs, sodass sie nicht durch Tastaturänderungen aktiviert werden, sondern nur, wenn Sie entweder mit der Maus oder durch Enter drücken ausgewählt werden.

Quelle: Barrierefreie Formulare erstellen

nach oben