CSS :invalid Pseudo-Klasse
Erfahren Sie, wie CSS :invalid Formularfelder mit fehlgeschlagener Validierung gestaltet, mit Beispielen, Fallstricken, Barrierefreiheitstipps und Browser-Unterstützung.
Die CSS :invalid Pseudo-Klasse trifft auf formularbezogene Steuerelemente zu — wie <input>, <select> und <textarea> — deren aktueller Wert die eingebauten Validierungsregeln des Browsers nicht erfüllt. Sie ist die visuelle Hälfte der HTML-Constraint-Validation-API: Der Browser bewertet die Gültigkeit, und :invalid ermöglicht es, das Ergebnis mit reinem CSS zu gestalten, ohne JavaScript.
Diese Seite behandelt genau, wann :invalid zutrifft, wie man es gestaltet, ohne Benutzer zu alarmieren, bevor sie etwas eingegeben haben, den Sonderfall bei Radio-Buttons, die moderne Alternative :user-invalid sowie die barrierefreie Darstellung von Fehlermeldungen.
Wann trifft :invalid auf ein Element zu?
Ein Steuerelement trifft auf :invalid zu, wenn es mindestens eine Validierungsregel hat und sein aktueller Wert gegen diese Regel verstößt. Häufige Auslöser:
| Bedingung | Attribut / Typ | Schlägt fehl, wenn… |
|---|---|---|
| Pflichtfeld leer | required | das Feld keinen Wert hat |
| Falsches E-Mail-Format | type="email" | der Wert keine syntaktisch gültige E-Mail-Adresse ist |
| Falsches URL-Format | type="url" | der Wert keine gültige absolute URL ist |
| Außerhalb des Wertebereichs | min / max bei type="number", type="date" usw. | der Wert außerhalb des erlaubten Bereichs liegt |
| Falscher Schritt | step | der Wert nicht mit dem Schrittintervall übereinstimmt |
| Muster stimmt nicht überein | pattern | der Wert nicht dem regulären Ausdruck entspricht |
| Zu lang / zu kurz | minlength / maxlength | die Länge des Werts außerhalb des erlaubten Bereichs liegt |
Hat ein Steuerelement keinerlei Bedingungen (ein einfaches <input type="text"> ohne zusätzliche Attribute), gilt es als uneingeschränkt, und weder :valid noch :invalid greift.
Ein <fieldset>-Element trifft auf :invalid zu, wenn eines seiner untergeordneten Formularsteuerelemente ungültig ist.
Die Gegenseite dazu ist die :valid-Pseudo-Klasse, die auf Steuerelemente zutrifft, die alle Bedingungen erfüllen. Die :required-Pseudo-Klasse trifft auf Pflichtfelder zu, unabhängig davon, ob sie einen Wert haben.
Syntax
:invalid {
/* declarations applied to all invalid form controls */
}Schränken Sie :invalid auf einen bestimmten Elementtyp ein, um die Stile vorhersehbar zu halten:
input:invalid,
textarea:invalid {
border: 2px solid #c00;
outline: none;
}Grundlegendes Beispiel
Das folgende E-Mail-Feld ist mit einer fehlerhaften Adresse ("not-an-email") vorausgefüllt, trifft daher beim Laden auf input:invalid zu und erhält einen roten Rahmen.
<!DOCTYPE html>
<html>
<head>
<title>:invalid example</title>
<style>
input:invalid {
border: 2px solid #c00;
background-color: #fff0f0;
}
input:valid {
border: 2px solid #090;
background-color: #f0fff0;
}
</style>
</head>
<body>
<h2>:invalid selector example</h2>
<form>
<label for="email">Email:</label>
<input id="email" type="email" value="not-an-email" required />
</form>
</body>
</html>„Vorzeitiges Rot" vermeiden
Die häufigste Falle bei :invalid: Ein leeres required-Feld ist bereits im Moment des Seitenladens ungültig, sodass ein frisches Formular rot aufleuchten kann, bevor der Benutzer irgendetwas eingegeben hat. Das wirkt anklagend.
Option 1 — nur während der Fokussierung stylen
Zeigen Sie den Fehlerrahmen nur an, während der Benutzer aktiv in das Feld eingegeben hat:
input:invalid:focus {
border-color: #c00;
outline: 2px solid #c00;
outline-offset: 1px;
}Das ist einfach, aber der Stil verschwindet, sobald der Benutzer das Feld verlässt, sodass ein leeres Pflichtfeld wieder unauffällig aussieht.
Option 2 — Fehler ausblenden, solange der Platzhalter sichtbar ist
:placeholder-shown ist wahr, wenn der Platzhaltertext angezeigt wird (d. h., das Feld ist leer). In Kombination mit :not greift der :invalid-Stil erst, wenn der Benutzer etwas eingegeben hat:
/* Only show the error style when the field has a value that is invalid */
input:invalid:not(:placeholder-shown) {
border-color: #c00;
}Das ist effektiv, erfordert aber, dass jedes Feld ein placeholder-Attribut hat — andernfalls ist :placeholder-shown nie wahr und der Schutz greift nicht.
Option 3 — :user-invalid verwenden (moderner Standard)
Die :user-invalid-Pseudo-Klasse wurde speziell zur Lösung dieses Problems entwickelt. Sie verhält sich wie :invalid, greift aber erst, nachdem der Benutzer mit dem Steuerelement interagiert hat (hineingeklickt, es verlassen oder das Formular abgeschickt hat):
/* Supported in all modern browsers as of 2024 */
input:user-invalid {
border-color: #c00;
}
/* Fallback for older browsers */
@supports not selector(:user-invalid) {
input:invalid:not(:placeholder-shown) {
border-color: #c00;
}
}:user-invalid ist die sauberste Lösung, wenn man sich darauf verlassen kann. Firefox unterstützte es jahrelang als :-moz-ui-invalid; das standardisierte :user-invalid ist inzwischen in allen modernen Browsern vorhanden.
Gestaltungsansatz
Ein harter 2-px-roter Rahmen ist lesbar, wirkt aber abrupt. Kombinieren Sie eine Rahmenänderung mit einem dezenten box-shadow für ein sanfteres Erscheinungsbild:
input:invalid:not(:placeholder-shown) {
border-color: #c00;
box-shadow: 0 0 0 3px rgba(204, 0, 0, 0.15);
}Verlassen Sie sich nicht allein auf Farbe — lesen Sie dazu den Abschnitt Barrierefreiheit.
Fallstricke
Radio-Buttons
Wenn eine Radio-Button-Gruppe bei einem ihrer Eingaben required hat, trifft :invalid auf jeden Button in der Gruppe zu, solange keiner ausgewählt ist. Das Gestalten kleiner Radio-Kreise ist unpraktisch; gestalten Sie stattdessen das umgebende <fieldset> oder das <label>:
/* Style the fieldset, not the radio buttons themselves */
fieldset:invalid {
border: 2px solid #c00;
border-radius: 4px;
padding: 8px 12px;
}Alle Radio-Buttons einer Gruppe teilen dasselbe name-Attribut — das macht sie im Gültigkeitsmodell des Browsers zu einer Gruppe.
Leere optionale Felder
Ein einfaches <input type="text"> ohne required, ohne pattern und ohne Längenbeschränkungen ist immer :valid, auch wenn es leer ist. :invalid greift nur, wenn eine Bedingung existiert und verletzt wird.
select und textarea
<select> trifft auf :invalid zu, wenn es required ist und sein aktueller value ein leerer String ist (ein häufiges Muster ist eine „-- bitte wählen --"-Platzhalter-<option value=""> am Anfang). <textarea> folgt denselben Regeln wie <input> für required, minlength und maxlength.
Firefox und :-moz-ui-invalid
Firefox hat lange Stile über :-moz-ui-invalid angewendet, das nur nach Benutzerinteraktion aktiv wird — im Wesentlichen das eingebaute :user-invalid-Verhalten. Wenn Sie eigene :invalid-Regeln hinzufügen und in Firefox testen, sieht das Feld möglicherweise in Ordnung aus (weil der eingebaute Interaktionsschutz des Browsers aktiv ist), verhält sich aber in Chrome anders (wo der Standardschutz deaktiviert ist). Definieren Sie explizite Regeln und verwenden Sie :user-invalid mit einem Fallback für einheitliches Verhalten.
Barrierefreiheit
Farbe allein reicht nie aus, um einen Fehler zu kommunizieren — Benutzer mit Farbsehschwäche erkennen möglicherweise keinen roten Rahmen. Kombinieren Sie :invalid-Styling mit:
- Einer sichtbaren Textnachricht, die erklärt, was falsch gelaufen ist und wie es zu beheben ist.
- Einem Symbol oder Icon neben der Farbänderung (z. B. ein ✕ oder Warnsymbol).
aria-invalid="true"am Steuerelement, damit Screenreader es als ungültig ankündigen.aria-describedby, das auf das Fehlermeldungselement zeigt, damit die Beschreibung automatisch vorgelesen wird.
<label for="email">Email address</label>
<input
id="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
required
/>
<span id="email-error" role="alert">
Please enter a valid email address.
</span>Das role="alert" am Fehler-Span sorgt dafür, dass Screenreader die Meldung ankündigen, sobald sie im DOM erscheint, auch ohne Fokus.
Verwandte Pseudo-Klassen
| Pseudo-Klasse | Trifft zu, wenn… |
|---|---|
:valid | das Steuerelement alle Bedingungen erfüllt |
:required | das Steuerelement das required-Attribut hat |
:optional | das Steuerelement kein required hat |
:out-of-range | der Wert eines numerischen/Datumseingabefelds min/max überschreitet |
:in-range | der Wert eines numerischen/Datumseingabefelds innerhalb von min/max liegt |
:placeholder | der Platzhaltertext eines Eingabefelds |
:focus | das Steuerelement aktuell den Tastaturfokus hat |
Browser-Unterstützung
:invalid ist Teil von Selectors Level 4 und wird seit vielen Jahren in allen wichtigen Browsern unterstützt. :user-invalid (die interaktionsbewusste Variante) ist seit Chrome 119, Firefox 88 (als :-moz-ui-invalid schon früher) und Safari 16.5 verfügbar.
Weitere Informationen zu den nativen Constraint-Attributen von HTML finden Sie unter <input> und HTML Forms.