In diesem Artikel betrachten wir HTML-Formularfelder und die Validierungsoptionen von HTML5. Wir werden uns auch ansehen, wie diese durch die Verwendung von CSS und JavaScript verbessert werden können.
Fangen wir am besten ganz einfach an: Jedes Formularfeld hat einen bestimmten Zweck. Und dieser Zweck unterliegt oft Einschränkungen bzw. den Regeln dafür, was in jedes Formularfeld eingegeben werden soll und was nicht. In einem Kontaktformular erfordert die Eingabe einer Mailadresse beispielsweise eine gültige E-Mail-Adresse. Ein Passwortfeld kann bestimmte Zeichentypen erfordern und eine Mindestanzahl erforderlicher Zeichen enthalten und und ein Textfeld kann eine Begrenzung der Anzahl der Zeichen haben, die eingegeben werden können.
Moderne Browser können überprüfen, ob diese Einschränkungen von Benutzern eingehalten werden, und sie warnen, wenn diese Regeln verletzt wurden. Dies wird als "Constraint Validation" (zu deutsch: Einschränkungsvalidierung) bezeichnet.
Der Großteil des JavaScript-Codes, der in den frühen Jahren der Sprache geschrieben wurde, verarbeitete die clientseitige Formularvalidierung. Auch heute noch verbringen Entwickler viel Zeit damit, Funktionen zu schreiben, um Feldwerte zu überprüfen.
Aber ist das in modernen Browsern überhaupt noch notwendig? Eigentlich nicht. Es hängt tatsächlich stark davon ab, was genau umgesetzt werden soll.
Aber bevor wir uns noch tiefer in diese Materie stürzen eine Warnung:
Die clientseitige Validierung ist eine Feinheit, die häufige Fehler bei der Dateneingabe verhindern kann, bevor eine Webanwendung wertvolle Zeit und Bandbreite beim Senden von Daten an einen Server verschwendet. Sie ist kein Ersatz für eine saubere serverseitige Validierung!
Prüfen Sie übermittelte Daten immer auch serverseitig. Nicht jede Anfrage kommt von einem Browser. Selbst wenn dies der Fall ist, gibt es keine Garantie dafür, dass der Browser die Daten validiert hat. Jeder, der weiß, wie man die Entwicklertools eines Browsers öffnet, kann auch dein liebevoll gestaltetes HTML und JavaScript umgehen.
Ein erfahrener Entwickler kann diesen Abschnitt überspringen. Für Anfänger haben wir hier eine Übersicht von verfügbaren HTML-Formularfeldern erstellt.
HTML Eingabefelder sind:
textarea
für mehrzeilige Textfelderselect
für eine Dropdown-Liste mit Optionenbutton
für jede Art von Buttons/SchalternAm häufigsten werden Sie aber input
verwenden.
<input type="text" name="username" />
Das type
Attribut legt den Element-Typ fest, und es gibt eine große Auswahl an Optionen:
Typ | Bezeichnung |
---|---|
button |
eine Schaltfläche ohne Standardverhalten |
checkbox |
ein Häkchen/Häkchen |
color |
ein Farbwähler |
date |
eine Datumsauswahl für Jahr, Monat und Tag |
datetime-local |
eine Datums- und Uhrzeitauswahl |
email |
ein E-Mail-Eingabefeld |
file |
eine Dateiauswahl |
hidden |
ein verstecktes Feld |
image |
eine Schaltfläche, die das durch das src Attribut definierte Bild anzeigt |
month |
eine Monats- und Jahresauswahl |
number |
ein Zahleneingabefeld |
password |
ein Passwort-Eingabefeld mit verdecktem Text |
radio |
ein Radiobutton |
range |
ein Schieberegler |
reset |
eine Schaltfläche, die alle Formulareingaben auf ihre Standardwerte zurücksetzt (aber vermeiden Sie dies, da dies selten nützlich ist) |
search |
ein Sucheingabefeld |
submit |
eine Schaltfläche zum Senden von Formularen |
tel |
ein Telefonnummer-Eingabefeld |
text |
ein Texteingabefeld |
time |
eine Zeitauswahl ohne Zeitzone |
url |
ein URL-Eingabefeld |
week |
eine Wochennummer- und Jahresauswahl |
Wenn kein type
gesetzt wird, sieht der Browser das Feld als normales, einzeiliges Textfeld. Moderne Browser unterstützen alle Typen gut, aber alte Browser zeigen zumindest noch ein Texteingabefeld an.
Andere nützliche <input>
- Attribute sind:
Attribut | Bezeichnung |
---|---|
accept |
Datei-Upload-Typ |
alt |
Alternativtext für die Bildtypen |
autocomplete |
Hinweis für die automatische Feldvervollständigung |
autofocus |
Fokusfeld beim Laden der Seite |
capture |
Eingabemethode für die Medienaufnahme |
checked |
Kontrollkästchen/Radio ist aktiviert |
disabled |
Deaktivieren Sie das Steuerelement (es wird nicht validiert oder sein Wert wird nicht übermittelt) |
form |
mit dieser ID einem Formular zuordnen |
formaction |
URL für die Übermittlung über die Schaltflächen „Einreichen“ und „Bild“ |
inputmode |
Hinweis zum Datentyp |
list |
ID der <datalist> Autocomplete-Optionen |
max |
Maximalwert |
maxlength |
maximale Stringlänge |
min |
Mindestwert |
minlength |
minimale Stringlänge |
name |
Name der Kontrolle, wie an den Server übermittelt |
pattern |
ein Muster [A-Z]+ für reguläre Ausdrücke, z. B. für ein oder mehrere Großbuchstaben |
placeholder |
Platzhaltertext, wenn der Feldwert leer ist |
readonly |
das Feld kann nicht bearbeitet werden, wird aber trotzdem validiert und übermittelt |
required |
Dieses Feld ist erforderlich |
size |
die Größe des Steuerelements (oft in CSS überschrieben) |
spellcheck |
Satz true oder false Rechtschreibprüfung |
src |
Bild URL |
step |
inkrementelle Werte in Zahlen und Bereichen |
type |
Feldtyp (siehe oben) |
value |
der Anfangswert |
Neben Eingabetypen bietet HTML5 auch schreibgeschützte Ausgaben:
output
: ein Ergebnisfeld einer Berechnung oder Benutzeraktionprogress
: ein Fortschrittsbalken mit value
und max
Attributen
meter
: eine Skala, welche entsprechend der gesetzten Attribute value
, min
, max
, low
, high
oder optimum
zwischen Grün, Gelb und Rot wechseln kann.Felder sollten ein zugeordnetes <label>
haben, welches das Input-Element einfasst. Ein Beispiel:
<label>Ihr Vorname <input type="text" name="name" />
Man kann die Verknüpfung aber auch mittels einer gesetzten Feld-ID erreichen:
<label for="vorname">Ihr Vorname</label> <input type="text" id="vorname" name="vorname" />
Etiketten sind für die barrierefreie Nutzbarkeit enorm wichtig.
Ein Eingabefeld kann außerdem noch durch einen placeholder
ergänzt werden um z.B. Platz auf dem Bildschirm zu sparen:
<input type="text" name="name" value="" placeholder="Ihr Vorname" />
Der Platzhaltertext verschwindet, sobald der Benutzer etwas eingibt. Sogar wenn es sich nur um ein einzelnes Leerzeichen handelt. Deshalb ist es meistens besser, ein Label anzuzeigen, da der Nutzer sich sonst daran erinnern muss, was das Feld für eine Eingabe erwartete.
Feldtypen und Einschränkungsattribute ändern das Eingabeverhalten des Browsers. Eine number
-Eingabe zeigt beispielsweise eine numerische Tastatur auf mobilen Geräten.
Das Feld kann auf dem Smartphone einen Spinner anzeigen, am Computer kann das Drücken der Pfeiltasten (hoch/runter) auf der Tastatur den gesetzen Wert erhöhen odder verringern.
Die meisten Feldtypen sind eindeutig zuordenbar. Es gibt aber auch Ausnahmen. Die Eingabe einer Kreditkarten-Nummer ist zum Beispiel numerisch, aber eine Werterhöhung über die Tastatur oder ein Spinner ist dabei komplett nutzlos. In solch einem Fall sollte man also eher den Standardtyp text
verwenden und das Attribut inputmode
auf numeric
setzen.
Dies sorgt dafür, dass eine Zifferntastatur eingeblendet wird, wenn das Feld ausgewählt wird. Die Einstellung autocomplete="cc-number"
schlägt auch alle vorkonfigurierten oder zuvor eingegebenen Kartennummern vor.
Die Verwendung des korrekten Feldtyps und des korrekten autocorrect
-Wertes bietet Vorteile, die in JavaScript schwer zu erreichen wären. Einige mobile Browser können beispielsweise:
Der Browser kann durch HTML5 bereits vordefinierte Einschränkungen prüfen und eine Übermittlung des Formulars verhindern. Es gibt dabei beispielsweise folgende Attribute:
type
, min
, max
, step
, minlength
, maxlength
, pattern
, und required
<input type="number" min="1" max="100" required />
Der Versuch, einen leeren Wert zu übermitteln, verhindert das Senden des Formulars und zeigt die folgende Meldung in Firefox an:
Auf dem Smartphone wird durch das oben gezeigte Formularfeld keine Eingabe außerhalb des Bereichs 1 bis 100 möglich sein. Ähnliche Validierungsmeldungen werden angezeigt, wenn Sie eine Zeichenfolge eingeben, die keine Zahl ist. Und das Alles ohne eine einzige Zeile JavaScript.
Eine Browservalidierung kann auch gestoppt werden, indem Sie:
novalidate
Attribut zum <form>
-Element setzenformnovalidate
Attribut zum Submit-Button hinzufügenDas Schreiben von benutzerdefinierten Eingabesteuerelementen ist enorm schwierig. Wir müssen eine vielzahl von Szenarien abdecken. Denken wir z.B. an Mausinteraktionen, Tastaureingaben, Touch-Berührung, Sprachunterschiede, Barrierefreihet, verschiedene Bildschirmauflösungen. Vor allem: Was passiert, wenn Javascript gar nicht funktioniert bzw. deaktiviert wurde?
Es gibt im Moment drei Hauptgründe, warum Entwickler weiterhin JavaScript-basierte Eingaben erstellen:
::before
und ::after
-Pseudo-Elementen. Die Situation verbessert sich stetig, aber Funktion sollte immer eine höhere Priorität als Design haben.<input>
Typen werden in alten Browsern nicht unterstütztZusammenfassend gilt aber folgendes: Vermeiden Sie es, Eingabeelemente neu zu erfinden. Die Abdeckung aller Nutzerszenarien treibt Sie in den Wahnsinn
Sie können die folgenden Pseudoklassen auf Eingabefelder anwenden , um sie entsprechend dem aktuellen Status zu formatieren:
Selektor | Erklärung |
---|---|
:focus |
das Feld mit Fokus |
:focus-within |
ein Element enthält ein Feld mit Fokus (ja, es ist ein übergeordneter Selektor!) |
:focus-visible |
ein Element hat aufgrund der Tastaturnavigation einen Fokus, daher ist ein Fokusring oder ein deutlicheres Styling erforderlich |
:required |
ein Feld mit einem required Attribut |
:optional |
ein Feld ohne required Attribut |
:valid |
ein Feld, das die Validierung bestanden hat |
:invalid |
ein Feld, das die Validierung nicht bestanden hat |
:user-valid |
ein Feld, das die Validierung bestanden hat, nachdem der Benutzer damit interagiert hat (nur Firefox) |
:user-invalid |
ein Feld, das die Validierung nicht bestanden hat, nachdem der Benutzer damit interagiert hat (nur Firefox) |
:in-range |
der Wert liegt innerhalb des Bereichs an einem number oder range Eingang |
:out-of-range |
der Wert liegt außerhalb des Bereichs an einem number oder range Eingang |
:disabled |
ein Feld mit einem disabled Attribut |
:enabled |
ein Feld ohne disabled Attribut |
:read-only |
ein Feld mit einem read-only Attribut |
:read-write: |
ein Feld ohne read-only Attribut |
:checked |
ein aktiviertes Kontrollkästchen oder ein Optionsfeld |
:indeterminate |
ein unbestimmtes Kontrollkästchen oder ein unbestimmtes Optionsfeld, wenn beispielsweise alle Optionsfelder deaktiviert sind |
:default |
die standardmäßige Senden-Schaltfläche oder das Standardbild |
Den placholder
-Text können Sie mit dem ::placeholder
Pseudoelement verschönern. Ein Beispiel:
/* Platzhalter-Text in der E-Mail-Feld soll blau sein */ input[type="email"]::placeholder { color: blue; }
Die obigen Selektoren haben die gleiche Spezifität, daher kann die Reihenfolge der Definitionen sehr wichtig sein. Betrachten wir dieses Beispiel:
input:invalid { color: red; } input:enabled { color: black; }
Ungültige Eingaben bekommen einen roten Text, aber er wird nur auf Eingaben mit einem disabled
-Attribut angewendet – alle aktivierten Eingaben sind also schwarz, weil wir dies nachher so definiert haben.
Der Browser wendet Validierungsstile beim Laden der Seite an. Im folgenden Code wird beispielsweise jedes ungültige Feld rot umrandet:
:invalid { border-color: #900; }
Der Benutzer wird mit einer abschreckenden Reihe von roten Kästchen konfrontiert, bevor er mit dem Formular interagiert. Das Anzeigen von Fehlern nach dem ersten Senden oder wenn ein Wert geändert wird, würde eine bessere Erfahrung bieten. Und hier kommt kommt wieder JavaScript ins Spiel …
Die Constraint-Validation-API bietet Formularanpassungsoptionen, die die standardmäßige HTML-Feldprüfung verbessern können. Anwendungsbeispiele:
Bevor Sie die API verwenden, sollten Sie in Ihrem Code die Standardvalidierung und Fehlermeldungen deaktivieren, indem Sie die noValidate
-Eigenschaft des Formulars auf "true" setzen:
const myform = document.getElementById('myform'); myform.noValidate = true;
Anschließend können Sie Ereignishandler hinzufügen – beispielsweise beim Senden des Formulars:
myform.addEventListener('submit', validateForm);
Der Handler kann überprüfen, ob das gesamte Formular gültig ist, indem er die checkValidity()
oder diereportValidity()
-Methoden verwendet. Diese geben "true" zurück, wenn alle Formulareingaben gültig sind.
(Der Unterschied zwischen den beiden Methoden besteht darin, dass checkValidity() überprüft, ob Eingaben einer Constraint-Validierung unterliegen.)
In einem Code-Beispiel erklärt:
// Prüfung der Eingaben bei Übermittlung function validateForm(e) { const form = e.target; if (form.checkValidity()) { // Formular ist in Ordnung - weitere Prüfungen durchführen } else { // Formular hat Fehleingaben - Submit wird abgebrochen e.preventDefault(); } };
Ein gültiges Formular kann nun also weitere Validierungsprüfungen nach sich ziehen. Ebenso können in einem ungültigen Formular die fehlerhaften Felder hervorgehoben werden.
Einzelne Felder haben die folgenden Validierungseigenschaften:
willValidate
: gibt true wenn das Element ein Kandidat für eine Constraint Validierung istvalidationMessage
: die Validierungsnachricht. Dies ist eine leere Zeichenfolge, wenn das Feld gültig ist.valitity
: dies hat eine "valid"-Eigenschaft die auf true gesetzt wird, wenn das Feld gültig ist. Wenn die Eigenschaft false ist, ist eine (oder mehrere) der folgenden Eigenschaften true:
.badInput
der Browser kann die Eingabe nicht verstehen.customError
eine benutzerdefinierte Gültigkeitsnachricht wurde festgelegt.patternMismatch
der Wert stimmt nicht mit dem angegebenen pattern
Attribut überein.rangeOverflow
der Wert ist größer als das max
Attribut.rangeUnderflow
der Wert ist kleiner als das min
Attribut.stepMismatch
der Wert passt nicht zu den step
Attributregeln.tooLong
die Stringlänge ist größer als das maxlength
Attribut.tooShort
minlength
Attribut.typeMismatch
der Wert ist keine gültige E-Mail oder URL.valueMissing
ein required
Wert ist leerEinzelne Felder haben folgende Beschränkungsvalidierungsmethoden:
setCustomValidity(message)
: Setzt eine Fehlermeldung für ein ungültiges Feld. Wenn das Feld gültig ist, muss eine leere Zeichenfolge übergeben werden, sonst bleibt das Feld für immer ungültig.checkValidity()
: gibt true zurück, wenn die Eingabe gültig ist. checkValidity()
hat den Vorteil, dass es anders als valitity.valid
auch ein invalid-Ereignis auslösen kann.
Die validateForm()
-Funktion könnte also jedes Formular-Feld durchlaufen und beim Fall invalid dann eine zusätzliche CSS-Klasse auf ihr übergeordnetes Element setzen:
function validateForm(e) { const form = e.target; if (form.checkValidity()) { // Formular ist in Ordnung - weitere Prüfungen durchführen } else { // Formular hat Fehleingaben - Submit wird abgebrochen e.preventDefault(); // invalid-Klasse hinzufügen Array.from(form.elements).forEach(i => { if (i.checkValidity()) { // Das Feld ist valid - entferne die Klasse i.parentElement.classList.remove('invalid'); } else { // Das Feld ist invalid - füge die Klasse hinzu i.parentElement.classList.add('invalid'); } }); } };
Anwendungsbeispiel: Wir haben ein Formular mit einem einfachen E-Mail-Feld:
<label for="email">email</label> <input type="email" id="email" name="email" required /> <p class="hilfe">Geben Sie eine gültige Mailadresse an</p>
Dazu packen wir etwas CSS
.hilfe { display: none; } .invalid .hilfe { display: block; } .invalid label, .invalid input, .invalid .hilfe { color: red; border-color: red; }
Das oben stehende JavaScript wird die .invalid-Klasse auf das übergeordnete <div>
packen, sobald die Mailadresse nicht angegeben oder ungültig ist.
Ein vollständiges Beispiel können Sie hier herunterladen
Formulare sind die Grundlage aller Webanwendungen und Entwickler verbringen viel Zeit damit, Benutzereingaben auszuwerten und Fehleingaben möglichst gut auszuwerten. Die Constraint-Validierung (Einschränkungsvalidierung) wird von den Browsern gut unterstützt. Diese können also Fehleingaben bereits sehr gut auswerten.
Unsere Empfehlungen für die Nutzung von Constraint-Validierung:
Sofern Ihre Clients nicht überwiegend IE-Benutzer sind, müssen Sie keine eigenen Fallback-Validierungsfunktionen implementieren. Alle HTML5-Eingabefelder funktionieren im IE, erfordern jedoch möglicherweise mehr Benutzeraufwand.
Wenn ein Nutzer also einen veralteten Browser verwenden will, dann muss dieser in den sauren Apfel beißen. Eine serverseitige Validierung der Eingaben sollte nach Übermittlung des Formulars in jedem Fall erfolgen.