Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

UI-Pseudoklassen

In den vorherigen Artikeln haben wir das allgemeine Styling verschiedener Formularelemente behandelt. Dies beinhaltete auch die Nutzung von Pseudoklassen, zum Beispiel die Verwendung von :checked, um ein Kontrollkästchen nur dann anzusprechen, wenn es ausgewählt ist. In diesem Artikel erkunden wir die verschiedenen UI-Pseudoklassen, die für das Styling von Formularen in unterschiedlichen Zuständen verfügbar sind.

Voraussetzungen: Grundkenntnisse in HTML und CSS, einschließlich allgemeinem Wissen über Pseudoklassen und Pseudoelemente.
Ziel: Verstehen, welche Teile von Formularen schwer zu stylen sind und warum; lernen, was getan werden kann, um sie anzupassen.

Welche Pseudoklassen stehen zur Verfügung?

Sie sind möglicherweise bereits mit den folgenden Pseudoklassen vertraut:

  • :hover: Wählt ein Element nur aus, wenn es von einem Mauszeiger überfahren wird.
  • :focus: Wählt ein Element nur aus, wenn es fokussiert ist (z.B. wenn es über die Tastatur angesteuert wurde).
  • :active: Wählt ein Element nur aus, wenn es aktiviert wird (z.B. während es angeklickt wird oder die Return / Enter-Taste bei einer Tastaturaktivierung gedrückt wird).

CSS-Selektoren bieten mehrere andere Pseudoklassen, die sich auf HTML-Formulare beziehen. Diese bieten mehrere nützliche Zielbedingungen, die Sie nutzen können. Wir werden diese im Folgenden detaillierter besprechen, aber kurz gesagt, die Hauptklassen, die wir uns ansehen werden, sind:

  • :required und :optional: Zielgerichtete Elemente, die erforderlich sein können (z.B. Elemente, die das required HTML-Attribut unterstützen), basierend darauf, ob sie erforderlich oder optional sind.
  • :valid und :invalid, sowie :in-range und :out-of-range: Formularelemente, die gültig/nicht gültig gemäß den auf ihnen gesetzten Validierungsbeschränkungen sind, oder innerhalb/außerhalb des Bereichs.
  • :enabled und :disabled, und :read-only und :read-write: Wählen Sie Elemente aus, die deaktiviert werden können (z.B. Elemente, die das disabled HTML-Attribut unterstützen), basierend darauf, ob sie momentan aktiviert oder deaktiviert sind, und schreib-/nicht-schreibgeschützte Formularelemente (z.B. Elemente mit dem readonly HTML-Attribut).
  • :checked, :indeterminate, und :default: Zielgerichtete Kontrollkästchen und Optionsfelder, die markiert, in einem unbestimmten Zustand (weder markiert noch nicht markiert) sind, sowie die standardmäßig ausgewählten Optionen beim Laden der Seite (z.B. ein <input type="checkbox"> mit gesetztem checked Attribut, oder ein <option> Element mit gesetztem selected Attribut).

Es gibt viele weitere, aber die oben genannten sind die offensichtlich nützlichsten. Einige von ihnen sind dazu gedacht, sehr spezifische Nischenprobleme zu lösen. Die oben genannten UI-Pseudoklassen haben eine exzellente Browser-Unterstützung, aber natürlich sollten Sie Ihre Formularimplementierungen sorgfältig testen, um sicherzustellen, dass sie für Ihre Zielgruppe funktionieren.

Hinweis: Einige der hier besprochenen Pseudoklassen befassen sich mit dem Styling von Formularelementen basierend auf ihrem Validierungszustand (ist ihre Eingabe gültig oder nicht?). Sie werden in unserem nächsten Artikel — Client-seitige Formularvalidierung — viel mehr über das Setzen und Kontrollieren von Validierungsbeschränkungen lernen, aber vorerst halten wir die Dinge bezüglich der Formularvalidierung einfach, um Verwirrung zu vermeiden.

Eingaben stylen basierend darauf, ob sie erforderlich sind oder nicht

Eines der grundlegendsten Konzepte bezüglich der clientseitigen Formularvalidierung ist, ob eine Formulareingabe erforderlich ist (sie muss ausgefüllt werden, bevor das Formular eingereicht werden kann) oder optional.

<input>, <select>, und <textarea> Elemente haben ein verfügbares required Attribut, das, wenn es gesetzt ist, bedeutet, dass Sie dieses Feld ausfüllen müssen, bevor das Formular erfolgreich eingereicht wird. Zum Beispiel sind im folgenden Formular Vorname und Nachname erforderlich, aber die E-Mail-Adresse ist optional:

html
<form>
  <fieldset>
    <legend>Feedback form</legend>
    <div>
      <label for="fname">First name: </label>
      <input id="fname" name="fname" type="text" required />
    </div>
    <div>
      <label for="lname">Last name: </label>
      <input id="lname" name="lname" type="text" required />
    </div>
    <div>
      <label for="email"> Email address (if you want a response): </label>
      <input id="email" name="email" type="email" />
    </div>
    <div><button>Submit</button></div>
  </fieldset>
</form>

Sie können diese beiden Zustände mit den :required und :optional Pseudoklassen abgleichen. Zum Beispiel, wenn wir das folgende CSS auf das obige HTML anwenden:

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

input:optional {
  border: 2px dashed;
}

Die erforderlichen Felder haben einen durchgezogenen Rahmen, und das optionale Feld hat einen gestrichelten Rahmen. Sie können auch versuchen, das Formular einzureichen, ohne es auszufüllen, um die clientseitigen Validierungsfehlermeldungen zu sehen, die Ihnen die Browser standardmäßig geben:

Im Allgemeinen sollten Sie vermeiden, mit Farben allein zwischen 'erforderlichen' und 'optional' Elementen in Formularen zu unterscheiden, da dies für Farbenblinde nicht ideal ist:

css
input:required {
  border: 2px solid red;
}

input:optional {
  border: 2px solid green;
}

Der Standard im Web für den Status 'erforderlich' ist ein Sternchen (*) oder das Wort "erforderlich" in Verbindung mit den jeweiligen Bedienelementen. Im nächsten Abschnitt sehen wir uns ein besseres Beispiel für die Kennzeichnung erforderlicher Felder mit :required und generiertem Inhalt an.

Hinweis: Wahrscheinlich werden Sie die :optional Pseudoklasse nicht sehr häufig verwenden. Formularelemente sind standardmäßig optional, sodass Sie Ihr optionales Styling standardmäßig vornehmen können und zusätzliche Styles für erforderliche Elemente hinzufügen können.

Hinweis: Wenn ein Radio-Button in einer gleichnamigen Gruppe von Radio-Buttons das required Attribut gesetzt hat, sind alle Radio-Buttons ungültig, bis einer ausgewählt ist, aber nur der mit dem zugewiesenen Attribut wird tatsächlich von :required betroffen sein.

Verwendung von generiertem Inhalt mit Pseudoklassen

In früheren Artikeln haben wir den Gebrauch von generiertem Inhalt gesehen, aber wir dachten, dass jetzt ein guter Zeitpunkt wäre, darüber etwas ausführlicher zu sprechen.

Die Idee ist, dass wir die ::before und ::after Pseudoelemente zusammen mit der content Eigenschaft verwenden können, um einen Inhaltsabschnitt vor oder nach dem betroffenen Element erscheinen zu lassen. Der Inhaltsabschnitt wird nicht zum DOM hinzugefügt, sodass er möglicherweise für einige Bildschirmleser unsichtbar ist. Da es sich um ein Pseudoelement handelt, kann es mit Styles auf die gleiche Weise angesprochen werden wie ein tatsächlicher DOM-Knoten.

Dies ist sehr nützlich, wenn Sie einem Element einen visuellen Indikator wie ein Label oder ein Icon hinzufügen möchten, wenn alternative Indikatoren ebenfalls verfügbar sind, um die Zugänglichkeit für alle Benutzer zu gewährleisten. Zum Beispiel verwenden wir in unserem benutzerdefinierten Radio-Button-Beispiel generierten Inhalt, um die Platzierung und Animation des inneren Kreises des benutzerdefinierten Radio-Buttons zu handhaben, wenn ein Radio-Button ausgewählt wird:

css
input[type="radio"]::before {
  display: block;
  content: " ";
  width: 10px;
  height: 10px;
  border-radius: 6px;
  background-color: red;
  font-size: 1.2em;
  transform: translate(3px, 3px) scale(0);
  transform-origin: center;
  transition: all 0.3s ease-in;
}

input[type="radio"]:checked::before {
  transform: translate(3px, 3px) scale(1);
  transition: all 0.3s cubic-bezier(0.25, 0.25, 0.56, 2);
}

Dies ist wirklich nützlich — Bildschirmleser informieren ihre Benutzer bereits, wenn ein angetroffenes Kontrollkästchen oder Optionsfeld markiert oder ausgewählt ist, sodass Sie nicht möchten, dass sie ein weiteres DOM-Element vorlesen, das die Auswahl anzeigt — das könnte verwirrend sein. Ein rein visueller Indikator löst dieses Problem.

Nicht alle <input> Typen unterstützen die Anzeige von generiertem Inhalt. Alle Eingabetypen, die dynamischen Text anzeigen, wie text, password oder button, zeigen keinen generierten Inhalt an. Andere, einschließlich range, color, checkbox, usw., zeigen generierten Inhalt an.

Zurück zu unserem vorherigen Beispiel zu erforderlichen/optionalen Eingaben, dieses Mal werden wir das Erscheinungsbild der Eingaben selbst nicht ändern — wir verwenden generierten Inhalt, um ein kennzeichnendes Label hinzuzufügen (sehen Sie es live hier, und sehen Sie sich den Quellcode hier an).

Zuerst fügen wir dem Formular einen Absatz hinzu, um zu sagen, wonach Sie suchen:

html
<p>Required fields are labeled with "required".</p>

Bildschirmleserbenutzer bekommen "erforderlich" als zusätzliche Information vorgelesen, wenn sie zu jeder erforderlichen Eingabe kommen, während sehende Benutzer unser Label sehen.

Wie bereits erwähnt, unterstützen Texteingaben keinen generierten Inhalt, daher fügen wir ein leeres <span> hinzu, um den generierten Inhalt daran aufzuhängen:

html
<div>
  <label for="fname">First name: </label>
  <input id="fname" name="fname" type="text" required />
  <span></span>
</div>

Das unmittelbare Problem war, dass das span eine neue Zeile unterhalb der Eingabe annahm, weil die Eingabe und das Label beide mit width: 100% gesetzt sind. Um dies zu beheben, stylen wir das übergeordnete <div>, um ein Flex-Container zu werden, sagen ihm aber auch, dass es seinen Inhalt auf neue Zeilen verteilen soll, wenn der Inhalt zu lang wird:

css
fieldset > div {
  margin-bottom: 20px;
  display: flex;
  flex-flow: row wrap;
}

Die Wirkung davon ist, dass das Label und die Eingabe auf separaten Zeilen sitzen, da sie beide width: 100% haben, aber das <span> hat eine Breite von 0, sodass es auf der gleichen Linie wie die Eingabe sitzen kann.

Jetzt zum generierten Inhalt. Wir erstellen ihn mit diesem CSS:

css
input + span {
  position: relative;
}

input:required + span::after {
  font-size: 0.7rem;
  position: absolute;
  content: "required";
  color: white;
  background-color: black;
  padding: 5px 10px;
  top: -26px;
  left: -70px;
}

Wir setzen das <span> auf position: relative, damit wir den generierten Inhalt auf position: absolute setzen und ihn relativ zum <span> positionieren können, statt relativ zum <body> (Der generierte Inhalt verhält sich, als wäre er ein Knoten des Elements, auf dem er generiert wird, für Positionierungszwecke).

Dann geben wir dem generierten Inhalt den Text "erforderlich", was wir wollten, dass unser Label sagt, und gestalten und positionieren ihn, wie wir es möchten. Das Ergebnis sehen Sie unten.

Steuern von Elementen basierend darauf, ob ihre Daten gültig sind

Das andere wirklich wichtige, grundlegende Konzept in der Formularvalidierung ist, ob die Daten eines Formularelements gültig sind oder nicht (im Fall von numerischen Daten können wir auch von innerhalb oder außerhalb des Bereichs sprechen). Formularelemente mit Beschränkungen der Eingabekontrolle können basierend auf diesen Zuständen angesprochen werden.

:valid und :invalid

Sie können Formularelemente mit den :valid und :invalid Pseudoklassen ansprechen. Einige wichtige Punkte:

  • Elemente ohne Beschränkungsvalidierung sind immer gültig und werden daher mit :valid abgeglichen.
  • Elemente mit required darauf, die keinen Wert haben, werden als ungültig gezählt — sie werden sowohl mit :invalid als auch mit :required abgeglichen.
  • Elemente mit eingebauter Validierung, wie <input type="email"> oder <input type="url">, sind (abgeglichen mit) :invalid, wenn die eingegebenen Daten nicht dem erwarteten Muster entsprechen (aber sie sind gültig, wenn sie leer sind).
  • Elemente, deren aktueller Wert außerhalb der Bereichslimits liegt, die durch die min und max Attribute angegeben sind, werden (abgeglichen mit) :invalid, aber auch :out-of-range, wie wir später sehen werden.
  • Es gibt noch andere Möglichkeiten, ein Element mit :valid/:invalid abzugleichen, wie Sie im Artikel Client-seitige Formularvalidierung sehen werden. Aber wir halten es vorerst einfach.

Schauen wir uns ein Beispiel für :valid/:invalid an (siehe valid-invalid.html für die Live-Version, und überprüfen Sie auch den Quellcode).

Wie im vorherigen Beispiel haben wir zusätzliche <span>s zum Generieren von Inhalten, die wir verwenden werden, um Indikatoren für gültige/ungültige Daten bereitzustellen:

html
<div>
  <label for="fname">First name: </label>
  <input id="fname" name="fname" type="text" required />
  <span></span>
</div>

Um diese Indikatoren bereitzustellen, verwenden wir das folgende CSS:

css
input + span {
  position: relative;
}

input + span::before {
  position: absolute;
  right: -20px;
  top: 5px;
}

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

input:invalid + span::before {
  content: "✖";
  color: red;
}

input:valid + span::before {
  content: "✓";
  color: green;
}

Wie zuvor setzen wir die <span>s auf position: relative, damit wir den generierten Inhalt relativ zu ihnen positionieren können. Wir positionieren dann absolut verschiedene generierte Inhalte, je nachdem, ob die Daten des Formulars gültig oder ungültig sind — ein grüner Haken oder ein rotes Kreuz, jeweils. Um ein wenig zusätzliche Dringlichkeit für die ungültigen Daten hinzuzufügen, haben wir auch den Eingaben einen dicken roten Rahmen gegeben, wenn sie ungültig sind.

Hinweis: Wir haben ::before verwendet, um diese Labels hinzuzufügen, da wir bereits ::after für die "erforderlich" Labels verwendet hatten.

Sie können es unten ausprobieren:

Beachten Sie, dass die erforderlichen Texteingaben ungültig sind, wenn sie leer sind, aber gültig, wenn sie etwas ausgefüllt haben. Das E-Mail-Eingabefeld andererseits ist gültig, wenn es leer ist, da es nicht erforderlich ist, aber ungültig, wenn es etwas enthält, das keine richtige E-Mail-Adresse ist.

Innerhalb und außerhalb des Bereichs liegende Daten

Wie wir oben angedeutet haben, gibt es zwei weitere verwandte Pseudoklassen zu betrachten — :in-range und :out-of-range. Diese stimmen mit nummerischen Eingaben überein, bei denen Bereichslimits durch die min und max Attribute festgelegt sind, wenn ihre Daten innerhalb oder außerhalb des angegebenen Bereichs liegen.

Hinweis: Numerische Eingabetypen sind date, month, week, time, datetime-local, number, und range.

Es ist erwähnenswert, dass Eingaben, deren Daten im Bereich liegen, auch mit der :valid Pseudoklasse abgeglichen werden, und Eingaben, deren Daten außerhalb des Bereichs liegen, auch mit der :invalid Pseudoklasse abgeglichen werden. Warum also beide haben? Das Problem ist wirklich eine Frage der Semantik — außerhalb des Bereichs zu sein, ist eine spezifischere Art der ungültigen Kommunikation, daher möchten Sie eventuell eine andere Nachricht für außerhalb des Bereichs liegende Eingaben bereitstellen, die für Benutzer hilfreicher ist als nur "ungültig" zu sagen. Sie könnten sogar beide bereitstellen.

Schauen wir uns ein Beispiel an, das genau dies tut. Unser out-of-range.html Demo (siehe auch den Quellcode) baut auf dem vorherigen Beispiel auf, um für die numerischen Eingaben Nachrichten außerhalb des Bereichs bereitzustellen, sowie zu sagen, ob sie erforderlich sind.

Die numerische Eingabe sieht folgendermaßen aus:

html
<div>
  <label for="age">Age (must be 12+): </label>
  <input id="age" name="age" type="number" min="12" max="120" required />
  <span></span>
</div>

Und das CSS sieht folgendermaßen aus:

css
input + span {
  position: relative;
}

input + span::after {
  font-size: 0.7rem;
  position: absolute;
  padding: 5px 10px;
  top: -26px;
}

input:required + span::after {
  color: white;
  background-color: black;
  content: "Required";
  left: -70px;
}

input:out-of-range + span::after {
  color: white;
  background-color: red;
  width: 155px;
  content: "Outside allowable value range";
  left: -182px;
}

Das ist eine ähnliche Geschichte wie zuvor im :required Beispiel, außer dass wir hier die Deklarationen, die auf jeden ::after Inhalt angewendet werden, in eine separate Regel aufgeteilt haben und den einzelnen ::after Inhalten für die :required und :out-of-range Zustände ihre eigenen Inhalte und Stile gegeben haben. Sie können es hier ausprobieren:

Es ist möglich, dass die Nummerneingabe sowohl erforderlich als auch außerhalb des Bereichs ist, was passiert dann? Da die :out-of-range Regel später im Quellcode erscheint als die :required Regel, kommen die Kaskadenregeln ins Spiel und die Nachricht "Außerhalb des zulässigen Wertebereichs" wird angezeigt.

Das funktioniert ziemlich gut — wenn die Seite zum ersten Mal geladen wird, wird "Erforderlich" angezeigt, zusammen mit einem roten Kreuz und Rahmen. Wenn Sie ein gültiges Alter eingegeben haben (d.h. im Bereich von 12-120), wird die Eingabe gültig. Wenn Sie jedoch das Alter auf einen Wert ändern, der außerhalb des Bereichs liegt, wird die Meldung "Außerhalb des zulässigen Wertebereichs" anstelle von "Erforderlich" angezeigt.

Hinweis: Um einen ungültigen/außerhalb des Bereichs liegenden Wert einzugeben, müssen Sie tatsächlich das Formular fokussieren und es mithilfe der Tastatur eingeben. Die Cursor-Schaltflächen lassen Sie den Wert nicht außerhalb des zulässigen Bereichs inkrementieren/dekrementieren.

Styling von aktivierten und deaktivierten Eingaben sowie schreibgeschützten und beschreibbaren Eingaben

Ein aktiviertes Element ist ein Element, das aktiviert werden kann; es kann ausgewählt, angeklickt, hineingetippt usw. werden. Ein deaktiviertes Element hingegen kann in keiner Weise interagiert werden, und seine Daten werden nicht einmal an den Server gesendet.

Diese beiden Zustände können mit den :enabled und :disabled Pseudoklassen angesprochen werden. Warum sind deaktivierte Eingabefelder nützlich? Nun, manchmal, wenn einige Daten für einen bestimmten Benutzer nicht zutreffen, möchten Sie diese Daten möglicherweise nicht einmal senden, wenn er das Formular einreicht. Ein klassisches Beispiel ist ein Versandformular — oft werden Sie gefragt, ob Sie die gleiche Adresse für Rechnungs- und Versandzwecke verwenden möchten; wenn ja, können Sie einfach eine Adresse an den Server senden und können die Rechnungsaddressfelder einfach deaktivieren.

Werfen wir einen Blick auf ein Beispiel, das genau dies tut. Zunächst ist der HTML-Code ein einfaches Formular mit Texteingabefeldern sowie einem Kontrollkästchen, um das Aktivieren/Deaktivieren der Rechnungsadresse umzuschalten. Die Rechnungsadressfelder sind standardmäßig deaktiviert.

html
<form>
  <fieldset id="shipping">
    <legend>Shipping address</legend>
    <div>
      <label for="name1">Name: </label>
      <input id="name1" name="name1" type="text" required />
    </div>
    <div>
      <label for="address1">Address: </label>
      <input id="address1" name="address1" type="text" required />
    </div>
    <div>
      <label for="zip-code1">Zip/postal code: </label>
      <input id="zip-code1" name="zip-code1" type="text" required />
    </div>
  </fieldset>
  <fieldset id="billing">
    <legend>Billing address</legend>
    <div>
      <label for="billing-checkbox">Same as shipping address:</label>
      <input type="checkbox" id="billing-checkbox" checked />
    </div>
    <div>
      <label for="name" class="billing-label disabled-label">Name: </label>
      <input id="name" name="name" type="text" disabled required />
    </div>
    <div>
      <label for="address2" class="billing-label disabled-label">
        Address:
      </label>
      <input id="address2" name="address2" type="text" disabled required />
    </div>
    <div>
      <label for="zip-code2" class="billing-label disabled-label">
        Zip/postal code:
      </label>
      <input id="zip-code2" name="zip-code2" type="text" disabled required />
    </div>
  </fieldset>

  <div><button>Submit</button></div>
</form>

Nun zum CSS. Die relevantesten Teile dieses Beispiels sind wie folgt:

css
input[type="text"]:disabled {
  background: #eeeeee;
  border: 1px solid #cccccc;
}

label:has(+ :disabled) {
  color: #aaaaaa;
}

Wir haben direkt die Eingaben, die wir deaktivieren möchten, mit input[type="text"]:disabled ausgewählt, aber wir wollten auch die entsprechenden Textetiketten ausgrauen. Da die Labels direkt vor ihren Eingaben liegen, haben wir sie mit der Pseudoklasse :has ausgewählt.

Nun haben wir finally etwas JavaScript verwendet, um die Deaktivierung der Rechnungsadressfelder umzuschalten:

js
// Wait for the page to finish loading
document.addEventListener(
  "DOMContentLoaded",
  () => {
    // Attach `change` event listener to checkbox
    document
      .getElementById("billing-checkbox")
      .addEventListener("change", toggleBilling);
  },
  false,
);

function toggleBilling() {
  // Select the billing text fields
  const billingItems = document.querySelectorAll('#billing input[type="text"]');

  // Toggle the billing text fields
  for (const item of billingItems) {
    item.disabled = !item.disabled;
  }
}

Es verwendet das change event, um dem Benutzer zu ermöglichen, die Rechnungsfelder zu aktivieren/deaktivieren, und das Styling der zugehörigen Labels umzuschalten.

Sie können das Beispiel unten in Aktion sehen (auch hier live anschauen, und sehen Sie sich den Quellcode an):

Schreibgeschützt und beschreibbar

In ähnlicher Weise zu :disabled und :enabled, die :read-only und :read-write Pseudoklassen zielen auf zwei Zustände, zwischen denen Formulareingaben wechseln. Ähnlich wie bei deaktivierten Eingaben können Benutzer schreibgeschützte Eingaben nicht bearbeiten. Im Gegensatz zu deaktivierten Eingaben werden schreibgeschützte Eingabewerte jedoch an den Server übermittelt. Beschreibbar bedeutet, dass sie bearbeitet werden können — ihr Standardzustand.

Eine Eingabe wird mit dem readonly Attribut schreibgeschützt gesetzt. Stellen Sie sich beispielsweise eine Bestätigungsseite vor, auf der der Entwickler die auf den vorherigen Seiten ausgefüllten Details an diese Seite gesendet hat, mit dem Ziel, dass der Benutzer sie alle an einem Ort überprüft, alle erforderlichen zusätzlichen Daten hinzufügt und dann die Bestellung durch Absenden bestätigt. An diesem Punkt können alle endgültigen Formulardaten in einem Rutsch an den Server gesendet werden.

Schauen wir uns an, wie ein Formular aussehen könnte (sehen Sie sich readonly-confirmation.html für das Live-Beispiel; sehen Sie auch den Quellcode).

Ein Ausschnitt des HTML-Codes sieht wie folgt aus — beachten Sie das readonly Attribut:

html
<div>
  <label for="name">Name: </label>
  <input id="name" name="name" type="text" value="Mr Soft" readonly />
</div>

Wenn Sie das Live-Beispiel ausprobieren, werden Sie sehen, dass die oberste Gruppe von Formularelementen nicht bearbeitet werden kann, dennoch werden die Werte gesendet, wenn das Formular abgesendet wird. Wir haben die Formularkontrollen mit den :read-only und :read-write Pseudoklassen gestylt, wie folgt:

css
input:read-only,
textarea:read-only {
  border: 0;
  box-shadow: none;
  background-color: white;
}

textarea:read-write {
  box-shadow: inset 1px 1px 3px #cccccc;
  border-radius: 5px;
}

Das vollständige Beispiel sieht wie folgt aus:

Hinweis: :enabled und :read-write sind zwei weitere Pseudoklassen, die Sie wahrscheinlich selten verwenden werden, da sie die Standardzustände von Eingabeelementen beschreiben.

Radio- und Kontrollkästchen-Zustände — aktiviert, Standard, unbestimmt

Wie in früheren Artikeln im Modul gesehen, können Radiobuttons und Kontrollkästchen ausgewählt oder nicht ausgewählt sein. Aber es gibt noch ein paar andere Zustände zu berücksichtigen:

  • :default: Passt zu Radiobuttons/Kontrollkästchen, die standardmäßig aktiviert sind, beim Laden der Seite (d.h. durch Setzen des checked Attributs auf ihnen). Diese passen zur :default Pseudoklasse, auch wenn der Benutzer sie deaktiviert.
  • :indeterminate: Wenn Radiobuttons/Kontrollkästchen weder aktiviert noch deaktiviert sind, gelten sie als unbestimmt und passen zur :indeterminate Pseudoklasse. Mehr dazu unten.

:checked

Wenn aktiviert, werden sie mit der :checked Pseudoklasse abgeglichen.

Der häufigste Anwendungsfall hierfür ist, einen anderen Style auf das Kontrollkästchen oder das Optionsfeld anzuwenden, wenn es aktiviert ist, in Fällen, in denen Sie das systemeigene Styling mit appearance: none; entfernt haben und die Styles selbst neu aufbauen möchten. Wir haben Beispiele dafür im vorherigen Artikel gesehen, als wir über Verwendung von appearance: none bei Radiobuttons/Kontrollkästchen sprachen.

Zur Erinnerung, der :checked Code aus unserem Gestylte Radiobuttons Beispiel sieht so aus:

css
input[type="radio"]::before {
  display: block;
  content: " ";
  width: 10px;
  height: 10px;
  border-radius: 6px;
  background-color: red;
  font-size: 1.2em;
  transform: translate(3px, 3px) scale(0);
  transform-origin: center;
  transition: all 0.3s ease-in;
}

input[type="radio"]:checked::before {
  transform: translate(3px, 3px) scale(1);
  transition: all 0.3s cubic-bezier(0.25, 0.25, 0.56, 2);
}

Sie können es hier ausprobieren:

Im Grunde bauen wir das Styling für einen Radiobuttons "inneren Kreis" mit dem ::before Pseudoelement, setzen darauf aber einen scale(0) transform. Wir verwenden dann einen transition, um den generierten Inhalt auf dem Label schön zu animieren, wenn das Radio ausgewählt/aktiviert wird. Der Vorteil der Verwendung eines Transforms anstelle von Übergängen von width/height besteht darin, dass Sie transform-origin verwenden können, um es aus der Mitte des Kreises wachsen zu lassen, anstatt es aus der Ecke des Kreises wachsen zu lassen, und es gibt kein Springen, da keine Boxmodell-Eigenschaftswertänderungen vorgenommen werden.

:default und :indeterminate

Wie oben erwähnt, passt die :default Pseudoklasse zu Radiobuttons/Kontrollkästchen, die standardmäßig aktiviert sind, beim Laden der Seite, selbst wenn sie deaktiviert werden. Dies könnte nützlich sein, um einen Indikator zu einer Liste von Optionen hinzuzufügen, um den Benutzern in Erinnerung zu rufen, was die Standardwerte (oder Startoptionen) waren, falls sie ihre Auswahl zurücksetzen möchten.

Auch die oben genannten Radiobuttons/Kontrollkästchen werden mit der :indeterminatePseudoklasse abgeglichen, wenn sie sich in einem Zustand befinden, in dem sie weder aktiviert noch deaktiviert sind. Aber was bedeutet das? Zu den indeterminierten Elementen gehören:

  • <input/radio> Eingaben, wenn alle gleich benannten Radiobuttons nicht aktiviert sind
  • <input/checkbox> Eingaben, deren indeterminate Eigenschaft über JavaScript auf true gesetzt ist
  • <progress> Elemente, die keinen Wert haben.

Das ist etwas, das Sie wahrscheinlich nicht sehr oft verwenden werden. Ein Anwendungsfall könnte ein Indikator sein, der den Benutzern sagt, dass sie wirklich ein Radiobutton auswählen müssen, bevor sie weitermachen.

Schauen wir uns ein paar modifizierte Versionen des vorherigen Beispiels an, die den Benutzer daran erinnern, was die Standardeinstellung war, und die Labels von Radiobuttons im unbestimmten Zustand stylen. Beide haben die folgende HTML-Struktur für die Eingaben:

html
<p>
  <input type="radio" name="fruit" value="cherry" id="cherry" />
  <label for="cherry">Cherry</label>
  <span></span>
</p>

Für das :default Beispiel haben wir das checked Attribut zum mittleren Radiobutton hinzgefügt, sodass es standardmäßig beim Laden ausgewählt iseing. Wir stylen es dann mit dem folgenden CSS:

css
input ~ span {
  position: relative;
}

input:default ~ span::after {
  font-size: 0.7rem;
  position: absolute;
  content: "Default";
  color: white;
  background-color: black;
  padding: 5px 10px;
  right: -65px;
  top: -3px;
}

Dies bietet ein kleines "Standard" Label auf dem Element, das ursprünglich ausgewählt war, als die Seite geladen wurde. Beachten Sie hier, dass wir den nachfolgenden-Geschwister-Kombinator (~) anstelle des nächsten-Geschwister-Kombinators (+) verwenden — wir benötigen dies, weil das <span> nicht direkt nach dem <input> in der Quellreihe kommt.

Sehen Sie unten das Live-Ergebnis:

Hinweis: Sie können das Beispiel auch live auf GitHub bei radios-checked-default.html finden (sehen Sie auch den Quellcode.)

Für das :indeterminate Beispiel haben wir keinen standardmäßig ausgewählten Radiobutton — das ist wichtig — wenn es einen gäbe, gäbe es keinen unbestimmten Zustand zum Stylen. Wir stylen die unbestimmten Radiobuttons mit dem folgenden CSS:

css
input[type="radio"]:indeterminate {
  outline: 2px solid red;
  animation: 0.4s linear infinite alternate outline-pulse;
}

@keyframes outline-pulse {
  from {
    outline: 2px solid red;
  }

  to {
    outline: 6px solid red;
  }
}

Dies erzeugt eine kleine animierte Umrandung auf den Radiobuttons, die hoffentlich anzeigt, dass Sie einen von ihnen auswählen müssen!

Sehen Sie unten das Live-Ergebnis:

Hinweis: Sie können das Beispiel auch live auf GitHub bei radios-checked-indeterminate.html finden (sehen Sie auch den Quellcode.)

Hinweis: Sie können ein interessantes Beispiel, das indeterminate Zustände beinhaltet auf der <input type="checkbox"> Referenzseite finden.

Weitere Pseudoklassen

Es gibt eine Reihe anderer interessanter Pseudoklassen, und wir haben hier nicht den Platz, um über alle im Detail zu schreiben. Lassen Sie uns über einige weitere sprechen, die Sie sich näher ansehen sollten.

  • Die :focus-within Pseudoklasse passt zu einem Element, das den Fokus erhalten hat oder ein Element enthält, das den Fokus erhalten hat. Dies ist nützlich, wenn Sie ein ganzes Formular auf irgendeine Weise hervorheben möchten, wenn ein Eingabefeld innerhalb davon fokussiert ist.
  • Die :focus-visible Pseudoklasse passt zu fokussierten Elementen, die über eine Tastaturinteraktion (anstatt über Berührung oder Maus) den Fokus erhalten haben — nützlich, wenn Sie einen anderen Stil für Tastaturfokus im Vergleich zu Maus (oder anderem) Fokus zeigen möchten.
  • Die :placeholder-shown Pseudoklasse passt zu <input> und <textarea> Elementen, die ihren Platzhalter zeigen (d.h. den Inhalt des placeholder Attributes), weil der Wert des Elements leer ist.

Die folgenden sind ebenfalls interessant, aber bisher nicht gut in Browsern unterstützt:

  • Die :blank Pseudoklasse wählt leere Formularelemente aus. :empty passt auch zu Elementen, die keine Kinder haben, wie <input>, aber es ist allgemeiner — es passt auch zu anderen leeren Elementen wie <br> und <hr>. :empty hat eine vernünftige Browser-Unterstützung; die :blank Pseudoklassen-Spezifikation ist noch nicht fertig, sie wird daher aktuell in keinem Browser unterstützt.
  • Die :user-invalid Pseudoklasse, wenn sie unterstützt wird, wird ähnlich wie :invalid sein, jedoch mit besserer Benutzererfahrung. Wenn der Wert beim Empfang des Fokus gültig ist, könnte das Element beim Eingeben von Daten während es vorübergehend ungültig ist, :invalid erreichen, aber wird nur :user-invalid erreichen, wenn das Element den Fokus verliert. Falls der Wert ursprünglich ungültig war, wird es für die gesamte Dauer des Fokus sowohl :invalid als auch :user-invalid erreichen. In ähnlicher Weise wie bei :invalid, wird es aufhören, :user-invalid zu erreichen, wenn der Wert dann gültig wird.

Zusammenfassung

Dies vervollständigt unseren Überblick über UI-Pseudoklassen, die sich auf Formulareingaben beziehen. Experimentieren Sie weiter mit ihnen, und erstellen Sie einige unterhaltsame Formularstile! Als nächstes gehen wir zu etwas anderem — client-seitige Formularvalidierung.