HTML/Tutorials/Formulare/Semantischer Code

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Das erste Suchformular enthält drei Elemente: Ein label-, ein input- und ein button-Element. Diese drei Elemente können gut in einer Zeile angeordnet werden. 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 Gedanken zu machen.

Da wir aus visueller Sicht eine einzige Zeile für das Suchformular erwarten, wäre ein Textabsatz bereits eine sinnvolle Lösung:

Beispiel: fertiges Suchformular für eine Google-Suche ansehen …
<form action="https://google.de/search">
  <p>
    <label for="q">Suchbegriff</label>
    <input id="q" name="q">
    <button>finden</button>
  </p>
</form>

Man kann sich nun streiten, ob der Textabsatz im Formular, oder das Formular im Textabsatz zu stehen habe. Für dieses konkrete Beispiel ist das völlig irrelevant, da beide Möglichkeiten gleichermaßen funktionieren:

Beispiel: fertiges Suchformular für eine Google-Suche - andere Code-Reihenfolge ansehen …
<p>
  <form action="https://google.de/search">
    <label for="q">Suchbegriff</label>
    <input id="q" name="q">
    <button>finden</button>
  </form>
</p>

Visuelle Gestaltungsmöglichkeiten aufgrund semantischen Codes[Bearbeiten]

Will man ein Formular gestalten, benötigt man sowohl die Layoutsprache CSS, als auch eine Dokumentstruktur, die passende Elemente zum Gestalten anbietet. Notiert man beispielsweise alles in einer Zeile und sorgt ausschließlich mit br-Elementen für Zeilenumbrüche, so hebt man auf der einen Seite die wichtige Trennung zwischen Markup und Layout auf, indem man HTML-Elemente ausschließlich wegen ihrer (voreingestellten) Darstellung ins Dokument schreibt, und hat auf der anderen Seite nicht genügend Elemente im Dokument, für die man ausgeklügelte Darstellungsregeln in der Layoutsprache festlegen könnte. Es lohnt sich also sehr, semantisch sinnvolles Markup zu verwenden.

Wenden wir uns nun einem Login-Formular zu. Für dieses brauchen wir zwei Eingabefelder (1. Benutzername und 2. Passwort), sowie einen Submit-Button. Bereits hier stellt sich aber die Frage, wie man diese drei Elemente in eine sinnvolle Dokumentstruktur einbindet. Drei mögliche Ansätze seien hier einmal vorgestellt:

Der Klassiker aus den Urzeiten des Webs: Tabellenlayout[Bearbeiten]

Beispiel: Login-Formular mit Tabelle ansehen …
<form action="login.php" method="post">
  <table>
    <tbody>
      <tr>
        <th>
          <label for="login">Benutzer</label>
        </th>
        <td>
          <input id="login" name="login">
        </td>
      </tr>
      <tr>
        <th>
          <label for="pass">Passwort</label>
        </th>
        <td>
          <input id="pass" name="pass" type="password">
        </td>
      </tr>
      <tr>
        <td>
        </td>
        <td>
          <button>anmelden</button>
        </td>
      </tr>
    </tbody>
  </table>
</form>
Diese Wahl der Dokumentstruktur ist nicht unbegründet, handelt es sich doch um tabellarische Daten: Benutzername bzw. Passwort und der jeweils zugehörende Wert. Problematisch wird diese Wahl beim Submit-Button. Er gehört nicht zu den tabellarischen Daten, wird in der Dokumentstruktur jedoch als Wert (deswegen zweite Spalte) ausgezeichnet, zu dem es keinen Namen (deswegen eine leere erste Zelle) gibt.

Listen anstelle von Tabellen[Bearbeiten]

Eine elegantere Möglichkeit ist die Verwendung einer Liste. HTML bietet hierzu eine (un)geordnete Liste oder eine Definitionsliste an.

Beispiel: Login-Formular mit ungeordneter Liste ansehen …
<form action="login.php" method="post">
  <ul><!-- alternativ wäre <ol> für geordnete Liste -->
    <li>
      <label for="login">Benutzer</label>
      <input id="login" name="login">
    </li>
    <li>
      <label for="pass">Passwort</label>
      <input id="pass" name="pass" type="password">
    </li>
    <li>
      <button>anmelden</button>
    </li>
  </ul>
</form>
Der Reiz dieser Dokumentstruktur liegt in ihrem überschaubarerem Quelltext. Möchte man die Listenpunkte ohne Aufzählungszeichen (bei Verwendung von <ul>) bzw. ohne Nummerierung (bei Verwendung von <ol>) haben, so kann man mit der Gestaltungssprache CSS eine passende Darstellungsregel einsetzen.

Auch mit einer Definitionsliste lässt sich das Login-Formular sinnvoll auszeichnen:

Beispiel: Login-Formular mit Definitionsliste ansehen …
<form action="login.php" method="post">
  <dl>
    <dt>
      <label for="login">Benutzer</label>
    </dt>
    <dd>
      <input id="login" name="login">
    </dd>
    <dt>
      <label for="pass">Passwort</label>
    </dt>
    <dd>
      <input id="pass" name="pass" type="password">
    </dd>
    <dd>
      <button>anmelden</button>
    </dd>
  </dl>
</form>
Das Standard-Layout des Browsers sieht vor, dass eine Definitionsliste „hängend formatiert“ dargestellt wird. Das bedeutet, dass das dd-Element mit einer Einrückung vom linken Rand angezeigt wird. Außerdem stehen dt- und dd-Elemente jeweils in einer neuen Zeile. Will man das anders haben, muss man wieder CSS bemühen und andere Darstellungsregeln verwenden.

Wenn die Beschriftung den Gestalter stört[Bearbeiten]

Beachten Sie: Eingabe-Elemente sollten Sie niemals ohne zugehörendes label-Element verwenden, da Sie sonst die Bedienbarkeit erschweren und Barrieren errichten.
Beachten Sie: Wenn Sie aus gestalterischen Gründen die Beschriftung entfernen wollen, achten Sie darauf, dass Sie dadurch Menschen mit Behinderungen nicht benachteiligen, die auf assistive Technologien angewiesen sind.
Beispiel: benutzerfreundliches Suchformular ohne sichtbare Beschriftung ansehen …
<form action="https://google.de/search">
  <p>
    <label for="q">Suchbegriff</label>
    <input id="q" name="q">
    <button>finden</button>
  </p>
</form>
label[for=q] {
  position: absolute;
  clip: rect(1px, 1px, 1px, 1px);
}
Das Label-Element bekommt hier eine Schriftgröße und eine Zeilenhöhe von Null zugewiesen. Screenreader oder Braillezeile geben es trotzdem aus.

Eine weitere Möglichkeit ist die Verwendung des Attributs aria-label.

Beispiel: benutzerfreundliches Suchformular ohne sichtbare Beschriftung ansehen …
<form action="https://google.de/search">
  <input id="q" name="q" aria-label="Suchbegriff">
  <button>finden</button>
</form>
Assistive Technologien „beschriften“ das Eingabefeld mit "Suchbegriff".

Man kann die Bedienbarkeit intuitiver gestalten, wenn man im Eingabefeld einen Platzhalter-Begriff eingibt. Das erreicht man mit dem placeholder-Attribut:

Beispiel: benutzerfreundliches Suchformular mit Beschriftung im Suchfeld ansehen …
<form action="https://google.de/search">
  <p>
    <label for="q">Suchbegriff</label>
    <input id="q" name="q" aria-label="Suchbegriff" placeholder="Suchbegriff">
    <button>finden</button>
  </p>
</form>
label[for=q] {
  position: absolute;
  clip: rect(1px, 1px, 1px, 1px);
}
Das placeholder-Attribut sorgt dafür, dass im Suchfeld bereits ein Begriff angezeigt wird, der aber sofort verschwindet, wenn der Benutzer eine Eingabe vornimmt. Der Inhalt des placeholder-Attributes ist selbst kein absendbarer Wert, sondern dient nur zur Beschriftung.

Komplexere Formulare mit fieldset gliedern[Bearbeiten]

Manchmal braucht man ein Formular mit verschiedenen Abschnitten, in denen unterschiedlichste Arten von Daten erfasst werden. Hierzu bietet es sich an, diese Abschnitte im Markup voneinander zu trennen. Hierzu bietet sich das fieldset-Element an. Betrachten wir uns einmal folgendes Bestellformular:

Beispiel: 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.