Formulare/Benutzereingaben zugänglich gestalten

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Gerade bei Benutzereingaben in Formularen ist es wichtig, dass diese nach den Grundsätzen der usability (Benutzerfreundlichkeit) und accessibility Barrierefreiheit für alle verständlich und zugänglich sind.

Dieses Tutorials zeigt, wie man …

1. Eingabefelder so gestalten kann, dass gleich erkennbar ist, …

  • welche Informationen eingegeben werden sollen.
  • welche Pflichtfelder ausgefüllt werden müssen

2. beim Absenden

  • überprüft, ob Eingaben valide sind
  • eine Vorschau, bzw. Kontrollausgabe anzeigt


Kein Mensch füllt gerne Formulare aus. Deshalb sollte man bei der Erstellung von Formularen darauf achten, dass sie für alle Benutzer möglichst leicht zu bedienen sind.


Alle Bedienelemente (z. B. Links und Formularelemente) sind durch die TAB-Taste ( ) erreichbar. Du kannst zwar mit dem tabindex-Universalattribut eine Reihenfolge festlegen, solltest das aber im Allgemeinen nicht tun, da eine Abweichung von der auf der Seite vorgegebenen Struktur nur zur Verwirrung des Benutzers führen würde.

Empfehlung: Im Standardverhalten der Browser ist festgelegt, dass Eingabelemente, die den Fokus haben, besonders gekennzeichnet sind. Entferne diese Formatierung nicht. Wenn du wünschst, kannst du sie noch stärker betonen.
Maus- und Tastaturinteraktionen

Von Tastatatur-Shortcuts ist generell abzuraten, weil es keine Kombinationen gibt, die auf allen Systemen funktionieren und nicht mit Shortcuts von anderen Programmen (z. B. Screenreader) oder den diversen Betriebssystemen kollidieren.[1]

Beschriftungen

Um valide Daten zu erhalten, ist es empfehlenswert dem Benutzer schon vor der Eingabe Hinweise und Hilfen zur richtigen Eingabe zu geben.

Mit dem label-Element (engl. für Etikett) wird Eingabefeldern, Radio-Buttons und Checkboxen bzw. einigen anderen Elementen eine Beschriftung hinzugefügt.

Labels beschriften Formulare ansehen …
<form>
  
  <label for="vorname">
    Vorname
    <input name="vorname" id="vorname" maxlength="30">
  </label> 

  <label for="zuname">Zuname</label>  
  <input name="zuname" id="zuname" maxlength="40">

  <button>Eingaben absenden</button>
</form>

Die Beschreibung im label kann einem Eingabe-Element (hier input) in drei Arten logisch zugeordnet werden:

  1. Wird das betreffende input-Element als Kindelement des label definiert, so ist eine ausdrückliche Zuordnung zwischen input und label mittels for-Attribut nicht mehr zusätzlich nötig. Die Zuordnung erfolgt dabei implizit über die Struktur des Quelltextes. Dies führt jedoch bei Screenreadern zu Schwierigkeiten.
  2. Im zweiten Beispielabschnitt erhält das label-Element ein for-Attribut und wird so mit der eindeutigen id des input-Elements verknüpft, was das Fehlerpotenzial durch zukünftige Umstrukturierungen verringert.
  3. Der Button enthält eine Beschreibung innerhalb der Button-Tags.
Empfehlung:

Beschrifte sämtliche Formular-Elemente mit einem label-Element, damit …

  • Nichtsehende wissen, was in das Eingabefeld eingegeben werden soll
  • die anklickbare Fläche (vor allem bei bei Checkboxen und Radio-Buttons) vergrößert wird, da auch auf das Label geklickt werden kann.
Nutze auch bei einer impliziten Zuordnung der Labels zu den Eingabefeldern for-Attribute.

Position

Untersuchungen zeigen, dass für eine sehr gute Zugänglichkeit die Beschriftung des Eingabefeldes in unmittelbarer Nähe desselben zu finden sein muss.

label ohne Nähe => schlecht zuzuordnen

In diesem Beispiel wird die Breite des Formulars durch die Radio-Buttons bestimmt - den Labels fehlt durch den großen Abstand die optische Zuordnung zu den Eingabefeldern. Die Radio-Buttons könnten untereinander stehen, dann würden die Zahlenwerte alleine durch die Anzahl ihrer Stellen sortiert.

Der optimale Platz ist – in Abhängigkeit von der Schreibrichtung – links- bzw. rechtsbündig oberhalb des Eingabefeldes, weil in diesem Fall selbst bei sehr schmalen Bildschirmen und großen Zoomfaktoren das Eingabefeld und seine Beschriftung gemeinsam zu sehen sind.

zugängliches label-input-Paar in zwei Sprachen

Für Nichtsehende erfolgt die Zuordnung der Beschriftung zu ihrem Eingabefeld über eine ID des input-Elements, welche mit einem entsprechenden for-Attribut des labels referenziert wird.

Tool-Tipps

Damit der Benutzer überhaupt weiß, was er eingeben soll, sind Beschriftungen sinnvoll. Weitergehende Erklärungen, die nichts mit dem Ausfüllen des Formulars zu tun haben, stören die Übersichtlichkeit und sollten daher an anderer Stelle platziert und durch einen Link erreichbar sein.

Häufig sieht man kleine Info-Icons, die beim Klick einen Tooltip öffnen.

Um einer Formularbeschriftung weitere, optionale Informationen mitzugeben, kannst du es mit einem details-Element erweitern. Dies ist erlaubt, da das label-Element zwar keinen labellable content erlaubt, andere Kindelemenente wie details jedoch schon.[2]

label mit weiteren Erklärungen ansehen …
<label class="input-container">
  <span>Vorname</span>
  <details>
    <summary>Wie Sie Ihren Vornamen finden</summary>
    <h1>Fragen Sie Ihre Mama</h1>
    ...
  </details>
  <input id="first-name">
</label>

Auf den ersten Augenblick wirkt das Beispiel aufgeräumt - und trotzdem lenkt der Text meiner Meinung nach vom Ausfüllen des Eingabefelds ab!

Browsereigene Validierung

Mit HTML5 wurden für das input-Element neue Typen und Attribute eingeführt, die ein jeweiliges Format vorschreiben. Bei E-Mail-Adressen, Zahlen und Daten ist es nun möglich, bereits beim Ausfüllen eine browsereigene Validierung vorzunehmen, d. h. die Eingabe auf Gültigkeit zu überprüfen. Ungültige Eingaben werden gleich zurückgewiesen und nicht erst zum Server gesandt. Dabei können browsereigene Fehlertexte, aber auch CSS-Formatierungen genutzt werden.

Achtung!

Eine clientseitige Validierung von Formulardaten kann lediglich den Bedienkomfort für den Nutzer erhöhen, indem das Absenden ungeeigneter Daten vermieden wird.
Die serverseitige Validierung der übermittelten Daten ist trotzdem unbedingt notwendig.

E-Mail- und Passworteingaben

Im folgenden Formular werden zum Login E-Mail-Adresse und Passwort abgefragt.

Empfehlung: Frage anstelle eines frei zu wählenden Benutzernamens lieber die E-Mailadresse ab!
Entweder verwenden die Benutzer aus Bequemlichkeit immer den gleichen Benutzernamen und womöglich sogar dasselbe Passwort oder sie vergessen es bis zum nächsten Einloggen und müssen die Login-Daten erst wieder anfordern. Die E-Mailadresse ist dagegen eindeutig und unverwechselbar.
input-Felder für E-Mails und Passwörter ansehen …
<form> <label for="mail">E-Mail</label> <input id="mail" type="email" required> <label for="passwd">Passwort</label> <input id="passwd" type="password" required> <button type="submit">Absenden</button> </form>

Das Eingabefeld erhält ein input-Element type="email". So überprüfen die Browser mittels eines regulären Ausdrucks, ob die Eingabe den Konventionen einer E-Mail-Adresse entspricht. Bei einer ungültigen Eingabe wird das Feld rot umrandet, wenn es den Fokus verlässt.

Das input-Element type="password" - bereits aus dem vorherigen Kapitel bekannt - ermöglicht eine verdeckte Eingabe des Passworts.

Beide Eingabefelder sind Pflichtangaben. Deshalb erhalten sie ein required-Attribut (engl. für erforderlich). Solange die Eingaben nicht valide sind, wird ein Absenden des Formulars verhindert und eine Fehlermeldung ausgegeben.

Screenshot von Fehlermeldungen bei Pflichtangaben

Beachte: Diese Meldungen sind sehr allgemein gehalten und können unter ungünstigen Umständen in der im Browser eingestellten, und nicht in der in der Webseite verwendeten Sprache sein.
Es könnte empfehlenswert sein, die browsereigene Gültigkeitsüberprüfung abzuschalten und durch eigene JavaScripte zu ersetzen.
Formulare/Eingaben mit JavaScript validieren


Häufig ist man jedoch alleine zuhaus und möchte kontrollieren, ob man das Passwort auch richtig eingegeben hat. Hier findet sich ein Beispiel, wie das mit wenigen Zeilen Javascript erreicht wird:

Eingabe von Zahlen und Daten

Zur Anmeldung auf einer Webseite benötigen wir noch das Alter und Geburtsdatum. (Aus Gründen der Benutzerfreundlichkeit wäre es besser, das Formular so einfach wie möglich zu halten; nur das Geburtsdatum zu erheben und das Alter auszurechnen.)

Altersabfrage ansehen …
<form> <label for="age">Alter</label> <input id="age" type="number" inputmode="dec"> <label for="birthday">Geburtsdatum</label> <input id="birthday" type="date" inputmode="dec"> <button type="submit">Absenden</button> </form>

Bei input type="number" erscheinen im Eingabefeld rechts zwei Pfeile, mit denen der Wert schrittweise erhöht oder gesenkt werden kann – eine Eingabe per Tastatur ist natürlich ebenfalls möglich. Die Eingabe von Buchstaben und Sonderzeichen wird in Chromium abgewiesen, im Firefox hingegen nicht - dort wird erst beim Absenden validiert.

Bei input type="date" erscheint im Eingabefeld ein placeholder mit der Formatierung TT.MM.JJJJ, der dem Nutzer bei der Eingabe hilft. Bei einem Klick in das Feld erscheint bei mobilen Geräten und modernen Browsern ein benutzerfreundliches Kalenderfeld, auf dem das Datum nur angeklickt werden muss.

Das inputmode-Attribut hilft mobilen Geräten, die richtige systemeigene Tastatur-(belegung) zu wählen. Da nur Zahlen eingegeben werden können, soll mit dec eine numerische Tastatur eingeblendet werden.

Weitere Beispiele zu Datumseingaben findest du unter Formulare/Eingabe von Zeitangaben.
Im Kurs Formulare und JavaScript stellen wir noch einen Schieberegler zur stufenlosen Eingabe von numerischen Werten vor.

Eingabemuster mit pattern

Wäre es nicht gut, beim Geburtsdatum „unmögliche“ Werte wie das gestrige oder ein 200 Jahre zurückliegendes Datum auszuschließen? Das ist mit zusätzlichen Attributen des input-Elements möglich!

Mit dem pattern-Attribut kannst du die Eingaben von input-Elemente gegen einen regulären Ausdruck hin überprüfen, ob die Eingabe den Erwartungen entspricht. Für die Eingabe von Zahlen, Telefonnummern und E-Mail-Adressen gibt es bereits eigene Typen, sodass du keine weiteren Einstellungen vornehmen musst.

Damit sind auch komplexere Abfragen möglich; die dabei verwendeten RegEx sind jedoch nicht trivial:

pattern, das Geburtstage vor 1900 ausschließt
<label for="age">Geburtsdatum</label>
<input id="age" type="date" placeholder="YYYY-MM-DD" 
       pattern="(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))" 
       title="Enter a date in this format YYYY-MM-DD" >

Die Eingabe wird vor dem Absenden des Formulars auf Korrektheit überprüft. Hier wird für das englische Datumsformat überprüft, ob die (im Englischen führende) Jahreszahl mit 19 oder 20 beginnt. Anschließend werden für die Monate nur 1-12 akzeptiert, dann für die Monate entweder 30, für den Monat 02 nur 29 und für die Monate 1,3,5,7,8 dann 31 Tage.

Empfehlung: Verzichte auf die Überprüfung mit solchen festen RegEx. Du kannst nie sicherstellen, in welchem lokalen Format die Dateneingabe erfolgt. Wandel Datumseingaben in ein UTC-Datum um und führe die Berechnungen mit diesem aus.

Ober- und Untergrenzen mit max und min

Im Allgemeinen ist der Einsatz solch regulärer Ausdrücke nicht nötig – HTML5 bietet dafür mit den Attributen min und max, mit denen Ober- und Untergrenzen festgelegt werden können, bequemere Alternativen:

Ober- und Untergrenzen mit max und min ansehen …
input {
    border: thin solid black;
}
input:in-range {
    background-color: rgb(0 255 0 / 0.25);
}
input:out-of-range {
    background-color: rgb(255 0 0 / 0.25);
    border: medium solid red;
}
input:in-range + ::after {
    content:' ✔';
}
input:out-of-range + ::after {
    content:' außerhalb des Bereichs!';
}
<form action="" id="form1">
  <label for="alter">Ihr Alter ist: </label>
  <input id="alter" name="altersangabe" type="number" placeholder="6 bis 99" min="6" max="99">
  <span></span>
</form>

Im vorliegenden Beispiel ändert sich die Hintergrundfarbe des Eingabefelds von grün auf rot, sobald etwas außerhalb des Gültigkeitsbereichs eingegeben wurde. Die Hintergrundfarbe ist in den Pseudoklassen :in-range und :out-of-range festgelegt. Sobald der eingegebene Wert wieder im Gültigkeitsbereich der Bereichsbegrenzung liegt, wird der Hintergrund wieder grün.


Die Breite der Input-Felder lässt sich im Übrigen sogar in Abhängigkeit vom Wert für maxlength mit CSS formatieren.[3]

Mindest- und Maximallänge mit min-/maxlength

Durch das maxlength- Attribut kannst du eine Maximallänge - und analog dazu mit dem minlength-Attribut eine Mindestlänge der Eingabe festlegen.

Mindest- bzw. Maximallänge ansehen …
<form>
  <label for="benutzername">Benutzername</label>
  <input id="benutzername" minlength="5" maxlength="8">
 
  <label for="passwd">Passwort</label>
  <input type="password" minlength="5" maxlength="8">
 
  <button>Anmelden</button>
</form>

Chrome, Edge und Opera geben bei einer Eingabe von weniger als 5 Zeichen eine Fehlermeldung aus. Firefox springt nur auf das Eingabefeld zurück.

Bei einer Eingabe von mehr als 8 Zeichen schneiden alle Browser weitere Eingaben ab.

Valide Eingaben mit CSS sichtbar machen

Es ist sinnvoll, Pflichtfelder zu kennzeichnen. Häufig geschieht das durch einen Asterisk *. In diesem Beispiel ändert sich die Kennzeichnung zu einem Haken ✔, sobald die Eingabe valide ist. Durch Verwendung der Pseudoklassen :valid, :invalid kannst du die Eingabe überprüfen:

Abgehakt, wenn's erledigt ist! ansehen …
input:required + label::before {
  position: absolute;
  left: 300%;
  content: "★";
  color: red;
}
input:required:valid + label::before {
  content: "✔";
  color: green;
}
    <form>
         <input id="bname" required><label for="bname">Benutzername</label>
         <input id="passwd" type="password" required><label for="passwd">Passwort</label>      
         <button type="submit">Anmelden</button>
    </form>

Die Kennzeichnung ( bzw. ) erfolgt durch ::before-Pseudoelemente der label-Elemente, die ::after-Pseudoelemente stellen wie in den anderen Beispielen dieser Seite auch bereits die abschließenden Doppelpunkte dar.

Die Reihenfolge im Markup ist ungewöhnlich, aber notwendig:

  • input darf als replaced element keinen, auch keinen generierten Inhalt erhalten,
  • CSS kann nur vorwärts selektieren

Mehrteilige Formulare

Gerade komplexere Formulare wirken alleine durch ihre Länge unübersichtlich. Das Formular sollte in logische Abschnitte gegliedert sein. So sind z.B. in einem WebShop Versand und Zahlungsinformationen oft getrennt.[4]

Dabei sollte

  • auf jeder Seite Hilfeinstruktionen zu finden sein
  • erkennbar sein, welche Abschnitte optional sind und übersprungen werden können
  • erkennbar sein, in welchem Abschnitt man sich gerade befindet

Achtung!

Dabei ist zu beachten, dass der Aufbau des Formulars gründlich durchdacht werden muss, um Nutzern mehrere Auswahlmöglichkeiten zu geben, diese dann aber konsequent einzuhalten, ohne dass es zu Spezialfällen kommt, die von Formular nicht erfasst werden können.[5]

Aus Sicht der Dokumentstruktur ist das form-Element aber kein Textbaustein. Es gruppiert lediglich Eingabeelemente als zu einem gemeinsamen Datensatz gehörend. Daher ist es wichtig, sich über sinnvolle Elemente zur Textstrukturierung und Gliederung größerer Formulare Gedanken zu machen.


Gruppierung mit fieldset

Mit dem fieldset-Element können Elemente innerhalb von Formularen gruppiert werden. Das legend-Element dient dann als Titel und Beschriftung.

Gruppierung mit fieldset ansehen …
<form id="gewinnen"> <label id="h2" form="gewinnen">Ausfüllen und Gewinnen!</label> <fieldset> <legend>Anrede</legend> <label for="männl">Herr</label> <input type="radio" name="anrede" id="männl" value="herr"> <label for="weibl">Frau</label> <input type="radio" name="anrede" id="weibl" value="frau"> <label for="firma">Firma</label><input type="radio" name="anrede" id="firma" value="firma"> <label for="keine"> - </label><input type="radio" name="anrede" id="keine" value="none"> </fieldset> <fieldset> <legend>Name</legend> <label for="vorname">Vorname</label><input name="vorname" id="vorname"> <label for="zuname">Zuname<input name="zuname" id="zuname"> </fieldset> </form>

Das Formular erhält eine Beschreibung in einem label-Element, das über das form-Attribut mit der id des Formulars verknüpft ist.

Es ist mit fieldset-Elementen in zwei Blöcke gegliedert, die jede eine Erklärung in einem legend-Element haben.

Beachte: Standardmäßig zeichnen die Browser einen Rahmen um das fieldset. Das legend-Element liegt genau auf diesem Rahmen. Allerdings kannst du dies zum Beispiel mit border: none auch anders festlegen.

Fortschrittsanzeige mit progress

Das progress-Element veranschaulicht einen Fortschritt einer Aktion etwa bei Bearbeitung eines Fragebogens in einer an Browser und Betriebssystem angepassten Darstellung.

Fortschrittsanzeige mit progress
<progress value="1" max="10">Stand der Abarbeitung: 10%</progress>

Es enthält zwei Attribute:

  • max, gibt an, wieviele Schritte maximal möglich sind
  • value die Anzahl der abgearbeiteten Schritte

Dabei gelten folgende Regeln:

  • ein fehlendes max-Attribut wird mit dem Wert 1 initialisiert
  • der Wert des value-Attributs sollte kleiner als der des max-Attributes sein
Beachte: Aus Gründen der Barrierefreiheit solltest du den aktuellen Status auch in den Inhalt des progress-Elementes schreiben.

Dieses Beispiel zeigt eine dynamische Anpassung des Fortschritts mit JavaScript.

Fortschrittsanzeige ansehen …
<form id="gewinnen"> 
  <fieldset> 
    <legend>persönliche Daten</legend> 
    <label for="vorname">Vorname</label><input name="vorname" id="vorname">
    <label for="zuname">Zuname</label><input name="zuname" id="zuname"> 
    <label for="wohnort">Wohnort</label><input name="wohnort" id="wohnort">      
  </fieldset> 
    
  <fieldset>
  	<label for="fortschritt" >Fortschritt: </label>
    <progress id="fortschritt" value="0" max=""></progress>
    
    <button type="submit" disabled>Absenden</button>
  </fieldset>
</form>

Das progress-Element enthält ein value-Attribut mit dem Wert 0 und einem leeren max-Attribut.

Jetzt muss mit JavaScript ermittelt werden, wie viele Eingabeelemente es gibt und wie viele davon bereits ausgefüllt sind.

Beispiel
  document.addEventListener('DOMContentLoaded', function() {
    const form = document.querySelector('#gewinnen');
    const inputs = form.querySelectorAll('input');
    const progress = document.querySelector('#fortschritt');
    const submitButton = form.querySelector('button[type="submit"]');
    
    // Set the max value of progress to the number of input elements
    const inputCount = inputs.length;
    progress.max = inputCount;
		
		form.addEventListener('change', updateProgress);
    
    // Function to update progress and check if all fields are filled
    function updateProgress() {
      let filledCount = 0;
      
      inputs.forEach(input => {
        if (input.value.trim() !== '') {
          filledCount++;
        }
      });
      
      progress.value = filledCount;
      
      // If all inputs are filled, enable the submit button
      if (filledCount === inputCount) {
        submitButton.disabled = false;
      } else {
        submitButton.disabled = true;
      }
    }
    
  });

Eins nach dem anderen - Multistep-Formular

Diese beiden Beispiele sollen nun verknüpft werden:

  • Nur der erste Formularabschnitt ist aktiv; die anderen sind mit disabled ausgegraut. Erst wenn der aktive Abschnitt erfolgreich ausgefüllt ist, wird der nächste freigeschaltet
  • Durch das progress-Element ist sofort ersichtlich, wie viele Schritte bereits erledigt, bzw. wie viel noch zu tun ist.
Multistep-Formular ansehen …


ToDo (weitere ToDos)

multistep-Formular;

  • Zusätzlich können die Seitenüberschrift, aber auch der title der Seite, der sich auf der Registerkarte des Browsers wiederfindet, geändert werden.
--Matthias Scharwies (Diskussion) 04:30, 2. Mai 2024 (CEST)

Alternativ könnte man in einer inline angeordneten Liste das jeweils aktuelle Element optisch hervorheben:

Formular mit Abschnitten
<ol class="timeline">
	<li class="timeline-past">
		<span class="visuallyhidden">Fertig: </span>
		<a href="billing.html">Rechnungsadresse</a>
	</li>
	<li class="timeline-current">
		<span class="visuallyhidden">Jetzt: </span>
		<span>Versandadresse</span>
	</li>
	<li><span>Bestellung überprüfen</span></li>
	<li><span>Zahlung</span></li>
	<li><span>Kauf abschließen</span></li>
</ol>

Formular-in-Abschnitten.png


Bestellformular mit verschiedenen Abschnitten ansehen …
<form action="order.php">
  <fieldset>
    <legend>Ware</legend>
    <ul>
      <li>
          <label for="article-1">Plüsch-Teddybär</label>
          <input id="article-1" name="article-1" type="number" value="0">
      </li>
      <li>
          <label for="article-2">Sofakissen "Sonnenblume"</label>
          <input id="article-2" name="article-2" type="number" value="0">
      </li>
    </ul>
  </fieldset>
  <fieldset>
    <legend>Bezahlung</legend>
    <p>
      <label for="payment">Art der Bezahlung</label>
      <select id="payment" name="payment">
        <option value="ae">American Express Card</option>
        <option value="master">MasterCard</option>
        <option value="visa">VISA</option>
        <option value="prepayment">Vorkasse</option>
      </select>
    </p>
    <p>
      <input id="email-receipt" name="email-receipt" type="checkbox">
      <label for="email-receipt">Quittung per E-Mail</label>
      <label for="email">an folgende Adresse</label>
      <input id="email" name="email" type="email">
    </p>
  </fieldset>
  <fieldset>
    <legend>Versand</legend>
    <dl>
      <dt>Lieferanschrift</dt>
      <dd>
          <ul>
            <li>
              <label for="recipient-name">Name</label>
              <input id="recipient-name" name="recipient-name">
            </li>
            <li>
              <label for="recipient-address">Anschrift</label>
              <input id="recipient-address" name="recipient-address">
            </li>
            <li>
              <label for="recipient-zip">PLZ</label>
              <input id="recipient-zip" name="recipient-zip">
              <label for="recipient-city">Ort</label>
              <input id="recipient-city" name="recipient-city">
            </li>
          </ul>
      </dd>
      <dt>Rechnungsanschrift</dt>
      <dd>
          <ul>
            <li>
              <label for="buyer-name">Name</label>
              <input id="buyer-name" name="buyer-name">
            </li>
            <li>
              <label for="buyer-address">Anschrift</label>
              <input id="buyer-address" name="buyer-address">
            </li>
            <li>
              <label for="buyer-zip">PLZ</label>
              <input id="buyer-zip" name="buyer-zip">
              <label for="buyer-city">Ort</label>
              <input id="buyer-city" name="buyer-city">
            </li>
          </ul>
      </dd>
    </dl>
  </fieldset>
  <fieldset>
    <legend>Zusatz</legend>
    <p>
      <label for="message">Ihre Nachricht an uns</label>
      <textarea id="message"></textarea>
    </p>
  </fieldset>
  <p><button>jetzt Kostenpflichtig bestellen</button></p>
</form>

Dieses Beispiel verwendet verschiedene Eingabemöglichkeiten wie mehrzeiliges Textfeld, Auswahlliste und Checkboxen neben reinen Textzeilen. Die verschiedenen Bereiche werden mit fieldset-Elementen voneinander abgegrenzt. Die Beschriftung eines fieldsets erfolgt mit einem legend-Element.


Anhang: placeholder - scheinbar genial

Mit HTML5 wurde ein placeholder-Attribut für input-Elemente eingeführt, welches allerdings für Beispielangaben gedacht ist und nicht für Beschriftungen. So könnte man etwa klarmachen, dass keine getrennten Eingabefelder für Name und Vorname verwendet werden.[6][7]

Scheinbar hat ein placeholder-Attribut einige Vorteile:

  • Es befindet sich im Eingabefeld und
    • ist so gleich zuzuordnen
    • spart Platz, den man auf kleinen Bildschirmen evtl. nicht hat.

Allerdings hat sich herausgestellt, dass

  • der Text des Attributs in den Default-Stylesheets aller Browser einen zu geringen Kontrast hat.
  • der Hinweis mit der ersten Texteingabe verschwindet und Nutzer keine Hilfe mehr haben.
Empfehlung: Vermeide Platzhalter wann immer möglich!
  • Stell sicher, dass die Farbe des Platzhaltertextes die WCAG SC 1.4.3-Anforderung eines Kontrastverhältnisses von 4,5:1 erfüllt.
  • Stell Anweisungen als Text im label oder neben dem Formular bereit. Abhilfe könnte die Verwendung von „z. B.“ schaffen.
  • Verknüpfe Anweisungen mit dem entsprechenden Formularfeld unter Verwendung von aria-describedby
  • Wenn es keine andere Möglichkeit gibt, als einen Platzhalter als Ersatz für eine sichtbare Beschriftung zu verwenden, verwende eine der Methoden für schwebende Beschriftungen
placeholder zeigen Beispiele ansehen …
<form> <label for="name">Name</label> <input id="name" placeholder="Max Mustermann"> <label for="passwd">Passwort</label> <input id="passwd" type="password" placeholder="Ihr Passwort"> </form>

Beschriftung direkt im Eingabefeld

Es könnte gewünscht sein, dass die Beschriftung des Eingabefeldes noch näher an das Eingabefeld heranrückt, das ist nur noch möglich, indem es sich im Eingabefeld selbst befindet.[8]

Damit das label-Element beliebig positioniert werden kann, gruppieren wir die label-input-Paare mithilfe eines div- oder span-Elements.

Beispiel ansehen …
.fancy-input {
  margin: 1em 0 1em 0;
  position: relative;
}
.fancy-input label {
  position: absolute;
  top: .5em;
  left: .5em;
  color: #666;
}
.fancy-input input {
  padding: .5em;
}
<div class="fancy-input">
  <label for="name">Name</label>
  <input id="name">
</div>
<div class="fancy-input">
  <label for="ort">Wohnort</label>
  <input id="ort">
</div>


Es ist zu sehen, dass diese Variante nicht zielführend ist, denn man kann nicht lesen, was in das Eingabefeld eingegeben wurde. Es ist wünschenswert, dass die Beschriftung „aus dem Weg geht“ sobald mit der Eingabe begonnen wird. Um zu erkennen, ob schon etwas in das Feld eingegeben wurde, wird JavaScript benötigt. Das Formular ist also bei deaktiviertem JavaScript nicht bedienbar. Deshalb setzen wir mit CSS die Beschriftung an die Stelle, wo sie bei der Eingabe nicht stört.

Beispiel ansehen …
.fancy-input label {
  position: absolute;
  color: #666;
  background: #fff;
  padding: 0 .5em;
  font-size: .8em;
  top: -.6em;
  left: .5em;
}


Mithilfe von JavaScript setzen oder entfernen wir jetzt nach Bedarf am label-Element eine Klasse like-placeholder. Zunächst wird für jedes der entsprechenden Elemente die Klasse gesetzt, aber nur, falls kein Text im Eingabefeld steht. Damit rutschen die Beschriftungen in die Mitte der input-Elemente. Falls JavaScript nicht aktiviert ist, passiert dies nicht und das Formular bleibt bedienbar. Außerdem werden für jedes Element zwei Eventhandler registriert: Einer lauscht, ob das Element den Fokus bekommen hat, der andere ob dem Element der Fokus wieder entzogen wurde. Bekommt das Element den Fokus, wird die Beschriftung „aus dem Weg geräumt“, wird ihm der Fokus entzogen und enthält es keine Eingabe, rutscht die Beschriftung wieder in die Mitte des Eingabefeldes. Eine Transition sorgt für einen weichen Übergang.

Beispiel ansehen …
.fancy-input label {
  position: absolute;
  background: #fff;
  padding: 0 .5em;
  font-size: .8em;
  top: -.6em;
  left: .5em;
  transition: all .3s ease;
}
.fancy-input label.like-placeholder {
  color: #666;
  font-size: 1em;
  top: .5em;
  left: .5em;
}
var fancyInputElements = document.querySelectorAll('.fancy-input input');

for (var i = 0; i < fancyInputElements.length; i++) {
  scaleLabel(fancyInputElements[i], true);
    
  fancyInputElements[i].addEventListener('focus', function () { scaleLabel(this, false) });
  fancyInputElements[i].addEventListener('blur', function () { scaleLabel(this, true) });
}

function scaleLabel(element, isLikePlaceholder) {
  if (isLikePlaceholder) {
    if (element.value === '') {
      element.parentNode.querySelector('label').classList.add('like-placeholder');
    }
  }
  else {
    element.parentNode.querySelector('label').classList.remove('like-placeholder');
  }
}




Siehe auch

Referenz:

Weblinks

  1. webaim.org: Keyboard Accessibility
  2. The label Element (WHATWG)
  3. SELF-Forum: CSS größer und kleiner Selektor bei Attributen von Gunnar Bittersmann von 25.09.2020
    maxlength mit dem Teilübereinstimmungs-Selektor auslesen und input-Feld entsprechend stylen
  4. W3C: Web Accessibility Tutorials Multi-page Forms
  5. Benutzerfreundliche Formulare (war: "Eine von allen" Checkboxen verpflichtend machen?) SELF-Forum vom 29.04.2024
    Bei der Planung eines Spiele-Wochenende sollten Nutzer einerseits Auswahlmöglichkeiten treffen können, andererseits eben nur bestimmte Kombinationen buchen können.
    So etwas muss vorher gut überlegt werden!
  6. Placeholders in Form Fields Are Harmful Katie Sherwin, Sep. 10, 2018
  7. smashingmagazine: Don’t Use The Placeholder Attribute (20.06.2018)
  8. SELFHTML-Forum: Ausrichtung von Formularelementen