Technik: HTML & CSS für Formulare

Teil 3 unserer Serie zu barrierefreien Formularen

Stand: 14.06.2011, Autor: tc
Kommentare zu diesem Artikel

Tags: , , , , ,

Semantik in Formularen – welche Elemente wofür in HTML4 / XHTML1?

Die Menge und Möglichkeiten der in HTML4 und XHTML1 vorhandenen Kontrollelemente in Formularen sind begrenzt, vor allem im Vergleich mit den Möglichkeiten graphischer Betriebssysteme. Sie haben allerdings auch Vorteile:

  • Ihr Zweck und ihre Funktionen sind eindeutig definiert.
  • Sie werden in der Regel auch von älteren Browsern zuverlässig unterstützt.
  • Sie sind mit den üblichen Hilfsmitteln behinderter Nutzer gut zu bedienen.
Fleißige Helferlein:
Formular-Frameworks & -Generatoren

Große Frameworks wie YUI Grids oder YAML mit dem YAML Builder stellen oft eigene Anwendungen zur Erstellung von HTML & CSS-Gerüsten für komplette Websites zur Verfügung. Es gibt aber auch eine ganze Reihe kleinerer Anwendungen, die auf die Erstellung von Formularen spezialisiert sind. Dazu gehören zum Beispiel:

Welche Formularelemente gibt es?

Die folgenden Formularelemente gibt es in HTML

  • einzeilige und mehrzeilige Textfelder zur Eingabe (INPUT mit dem Attribut type="text" sowie mit dem Attribut type="password" für Passwörter und TEXTAREA)
  • Elemente für Datei-Uploads (INPUT mit dem Attribut type="file")
  • Auswahllisten (SELECT und OPTION),
  • der Sonderfall Auswahllisten mit Mehrfachauswahl (SELECT mit dem multiple-Attribut und OPTION)
  • Radiobuttons zur Entweder/Oder-Auswahl (<input type="radio">)
  • Checkboxen zur Sowohl/Als auch-Auswahl (<input type="checkbox">)
  • sowie die Schaltflächen-Elemente (Buttons) zum Übergeben von Daten an den Server und zum Löschen von Formularen:
    • input type="submit"
    • input type="reset"
    • input type="image"
    • input type="button" sowie:
    • button

Im Sinne der Barrierefreiheit sind alle diese Elemente neutral. Ihr Einsatz stellt keine besonderen Hürden im Umgang mit Web-Formularen dar. Allerdings gibt es zwei Ausnahmen:

  • Der Button zum Zurücksetzen eines Formulars auf den ursprünglichen, meist leeren Zustand (<input type="reset">) ist selten sinnvoll. Der Schaden, den ein solcher Button anrichten kann, überwiegt bei weitem dessen Nutzen. Seine ganze fatale Wirkung entfaltet dieser Button, wenn »Abbrechen« vor der primären Aktion steht (also üblicherweise »Absenden« oder »Speichern«): Ein unachtsamer Druck auf Enter leert unter Umständen das Formular und befördert alle Eingaben des Nutzers zuverlässig in den Datenhimmel. Erschwerend kommt hinzu, dass je nach verwendetem Betriebssystem des Nutzers unterschiedliche Konventionen zur Platzierung des »Abbrechen«-Buttons herrschen. Man kann also nie vorhersagen, ob Nutzer diesen Button links oder rechts erwarten. Die Wahrscheinlichkeit, dass Nutzer diesen Button irrtümlich drücken ist also recht hoch – zu hoch um den Einsatz zu rechtfertigen.
  • Die eingangs der Auflistung erwähnten Elemente zur Mehrfachauswahl (<select size="10" multiple="multiple">): Bei diesen Feldern ist für den Benutzer nicht ohne weiteres erkennbar, dass hier tatsächlich mehrere Optionen ausgewählt werden können – damit hätten wir die erste kognitive Barriere. Zudem ist die Bedienung (Auswahl per Maus mit gedrückter STRG- bzw. Apfel-Taste) nicht intuitiv und kann nicht als gelernt vorausgesetzt werden – eine weitere Barriere. Zudem lässt sich dieses Element nur umständlich oder im Ernstfall gar nicht per Tastatur bedienen. Bevor Sie sich hier in langatmigen Hilfetexten verzetteln, sollten Sie gleichwertige Checkboxen für Mehrfachauswahlen einsetzen, wenn deren Anzahl ein vernünftiges Maß nicht übersteigt.

Welche Formularelemente gibt es (noch) nicht?

Für die meisten klassischen Formulare wird der begrenzte Satz von Formularelementen von HTML4 und XHTML1 ausreichen. Bei web-basierten Anwendungen stößt man jedoch sehr schnell an die Grenzen der Markup-Sprache, die eigentlich nie für solche Anwendungen gedacht war. Was in den fertig verabschiedeten HTML-Standards bis heute fehlt sind Elemente, die jenseits des Web-Browsers gang und gäbe sind, wie zum Beispiel:

  • Schieberegler (Slider),
  • Numeric Stepper (Textfelder, in denen mit Pfeiltasten die Werte herauf- oder herabgesetzt werden können),
  • Comboboxen mit Mehrfachauswahl und eigenen Eingaben
  • Fortschrittsbalken
  • Farbauswahl
  • Datumsauswahl
  • Checkboxen mit drei Zuständen (Tri-State: Ja, Nein und Teilweise)
  • u.v.m.

Hier soll in Zukunft HTML5 Abhilfe schaffen, das einen erweiterten Satz an Eingabe- und Kontrollelementen zur Verfügung stellen wird. Zum Zeitpunkt der Veröffentlichung dieser Artikelserie befand sich HTML5 aber immer noch im Zustand eines Entwurfes, der in aktuellen Browsern teilweise schon implementiert ist. Da es sich aber um einen Working Draft handelt, kann sich immer noch vieles ändern. Ein Einsatz der neuen Elemente sollte also erst nach genauer Abwägung der Vor- und Nachteile und nach eingehenden Tests geschehen.

Falls Ihre Anwendung diese Elemente bzw. deren Funktionalität benötigt, so können Sie für moderne Browser die neuen Elemente aus HTML5 auch heute schon verwenden. Allerdings benötigen nicht ganz so moderne Browser und Hilfsmittel Fallback-Lösungen und/oder JavaScript, um die gewünschten Funktionen zur Verfügung zu stellen.

Teilweise wird dieser Spagat durch den Einsatz von WAI-ARIA erleichtert, das als eine Art Spachtelmasse die Lücke zwischen der begrenzten Welt von HTML4 und den erweiterten Möglichkeiten von HTML5 zu überbrücken sucht. Hierzu mehr in einem späteren Kapitel der Serie.

Welches Element ist das Richtige?

Bei der Festlegung der Kontrollelemente sollten Sie sich folgende Fragen stellen:

  • Was ist für den Nutzer nahe liegender – das Eintippen eines freien Textes oder die Auswahl aus einer Liste von Optionen? Was fängt die möglichen Eingaben des Nutzers am besten ab? So kann man in einem Bestellvorgang die Anzahl der zu bestellenden Produkte als Textfeld oder als Auswahllisten (z.B. 1-10) hinterlegen. Im Zweifelsfall sollten Sie sich hier für die größtmögliche Freiheit für den Nutzer entscheiden.Ein Beispiel: Bei »Einfach für Alle« gab es früher eine Broschüre, die über ein Bestellformular angefordert werden konnte. In diesem Bestellformular war die Anzahl der Broschüren über ein Textfeld frei einzugeben; zur Verhinderung von Scherzbestellungen war dieses Textfeld per maxlength-Attribut auf zwei Ziffern begrenzt. Nun gab es aber tatsächlich Fälle, in denen jemand gleich einen ganzen Karton mit 100 Broschüren für eine Bildungseinrichtung bestellen wollte, was mit diesem Formular unmöglich war.
  • Mit welchem Element kann der Nutzer die wenigsten Fehler machen? Kann man sich einfach vertippen? Dann sollten Sie bei einer überschaubaren Anzahl von Optionen dem Nutzer die Arbeit abnehmen und diese als Auswahl präsentieren. Bei der Eingabe von freien Texten können Sie den Nutzer unterstützen, indem die Eingaben unmittelbar clientseitig validiert bzw. im Hintergrund an den Server geschickt werden, um die Plausibilität der Eingaben zu überprüfen.
  • Muss der Nutzer sämtliche Optionen lesen, um die Abfrage zu verstehen? Dann sollten Sie die beschreibenden Texte und Labels möglichst kurz und prägnant halten. Die Erfahrung hat gezeigt, dass Nutzer umso weniger Text lesen, je mehr in einem Formular steht. In Tests ist sogar oft zu beobachten, dass Nutzer noch während des Ladens der Seite anfangen, mit dem Formular zu interagieren, ohne sich vorher in Ruhe zu orientieren und eventuell bereitgestellte Hilfen zur Kenntnis zu nehmen.
  • Wie viele Optionen gibt es? Kann der Nutzer mehr als eine Option auswählen? Bei begrenzten Auswahlmöglichkeiten oder wenn immer nur eine Option zulässig ist (wie die Angabe der Kreditkarte in einem Bezahlvorgang) fällt schon fast zwangsläufig die Wahl auf Radiobuttons. Bei Mehrfachauswahlen wiederum bieten sich Checkboxen an.
  • Kann man die zur Wahl stehenden Optionen als bekannt voraussetzen oder geht es um die Auswahl aus einer Liste, die dem Nutzer unbekannt sein dürfte? Bei einfachen Fragen, die mit Ja oder Nein zu beantworten sind, fällt die Wahl natürlich auf Radiobuttons – hier hat der Nutzer alle Optionen im direkten Zugriff. Bei längeren Listen (z.B. eine Auswahl aus den 16 Bundesländern) macht es keinen Sinn, diese allesamt als eine Liste von Radiobuttons zu zeigen – diese Auswahl sollte als SELECT gezeigt werden. Weitere Gedanken zu diesem Thema finden Sie im Artikel »It's not about size, it's about context – radio buttons or drop-downs« von Donna Spencer.
  • Wollen Sie Ihren Benutzern wirklich die Navigation in einer Auswahlliste mit mehreren hundert Einträgen zumuten? Schlechte Beispiele hierfür finden sich im Netz zuhauf bei den Länderauswahlen: viele Anbieter hinterlegen hier sämtliche Staaten der Erde, auch wenn sie ihre Waren nur in Deutschland und dem benachbarten Ausland ausliefern. Auch die Strukturierung nach Kontinenten per OPTGROUP ist nur dann wirklich sinnvoll, wenn Sie tatsächlich Kunden auf allen Kontinenten bedienen wollen. Die Beschränkung auf eine Anzahl realistischer Optionen ist hier oftmals sinnvoller.
  • Was entspricht den (Seh-) Gewohnheiten der Nutzer? Bei der Auswahl eines Datums (nach der Art TT MM JJJJ) werden immer wieder unbeabsichtigte Barrieren aufgebaut. Bei der freien Eingabe in ein Textfeld kann es zu Problemen mit der Internationalisierbarkeit (I18N) kommen, wenn Nutzer aus unterschiedlichen Ländern unterschiedlichen Konventionen in der Sortierung folgen. Für einen Europäer ist 01/04/07 der 1. April 2007, für Amerikaner wäre dies jedoch der 4. Januar 2007; in Ländern mit umgedrehter Leserichtung (von rechts nach links) könnte dies auch als der 7. April 2001 gelesen werden. Auch die Hinterlegung als getrennte Auswahl in Form von getrennten Auswahllisten für Tag, Monat und Jahr ist suboptimal, da nur umständlich zu bedienen. Das natürlichste Element mit dem geringsten Verwechselungspotenzial wäre hier ein Kalender, den man mit ein wenig JavaScript und einer Datentabelle ins Formular integrieren kann. Wie dies barrierefrei zu realisieren ist zeigt das folgende Beispiel: »Unobtrusive JavaScript date-picker widgit«

Logische Blöcke: Fieldset & Legend

Wenn Sie die Komplexität auf das Notwendige reduziert haben, geht es nun an die Aufteilung der Oberfläche. Optische Gruppierungen sollten die strukturellen Gruppierungen unterstützen; mit Überschriften bzw. Legenden, Farben und Formen können Sie Bereiche des Formulars ordnen, die dann vom Besucher nacheinander abgearbeitet werden. So können Sie unerfahrenen Benutzern die einzelnen Schritte schrittweise oder seitenweise präsentieren und diese mit erklärenden Texten unterbrechen.

XHTML1 ist nicht nur HTML 4 mit ein paar zusätzlichen Schrägstrichen, es gibt auch tiefergehende Unterschiede. LEGEND ist ein Beispiel hierfür: In HTML ist das Element als direktes Kind-Element von FIELDSET zwingend vorgeschrieben, in XHTML1 ist LEGEND hingegen optional.

Aus der HTML 4.01 Strict-DTD:

<!ELEMENT FIELDSET – - (#PCDATA,LEGEND,(%flow;)*) -- form control group -->

und der korrespondierende Eintrag aus der XHTML-DTD:

<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>

Leider sind eine Reihe dieser Unterschiede in der offiziellen Dokumentation des W3C nicht beschrieben, was sicher auch einer der Gründe für die sinnfreie Fehlermeldung des W3C-Validators in diesem Punkt ist. Zum Vergleich: fieldset-ohne-legend.xhtml vs. fieldset-ohne-legend.html

Wenn Sie ein komplexes Formular anbieten, das aus mehreren logischen Einheiten besteht, sollten Sie über den Einsatz des FIELDSET-Elementes nachdenken. Mit einem Fieldset lassen sich Formulare in leichter überschaubare Blöcke unterteilen. Es werden genau die Bestandteile zusammengefasst, die eine logische Einheit ergeben. Diese können dann übersichtlicher gestaltet und vom Besucher nacheinander abgearbeitet werden. So können Sie unerfahrenen Benutzern die einzelnen Schritte häppchenweise präsentieren und diese mit erklärenden Texten (»Geben Sie bitte Ihre persönlichen Daten ein…«) unterbrechen.

Gerade bei Formularen, in denen die Eingabe einer Vielzahl unterschiedlicher Daten verlangt wird, trägt diese Technik zur Übersichtlichkeit für den Anwender bei. Für Nutzer, bei denen die Hürden weitestgehend im kognitiven Bereich bestehen, können Sie so die Zahl der Abbrecher reduzieren.

Durch den Einsatz von Legenden für die einzelnen Fieldsets können Sie Ihren Besuchern eine weitere Orientierungshilfe geben. Das Element LEGEND ist ein Kind-Element von FIELDSET, das von grafischen Browsern am Beginn des abgegrenzten Bereichs dargestellt wird. Per CSS und JavaScript lassen sich hier Strukturen schaffen, die zum Beispiel eine Präsentation in Form von Karteireitern und -karten ermöglichen:

Fieldsets können übrigens auch verschachtelt werden, d.h. innerhalb eines Fieldsets können weitere Fieldsets enthalten sein (Beispieldatei: fieldsets.html), um zum Beispiel zusammengehörige Gruppen von Kontrollelementen darzustellen:

<fieldset>
  <legend>Äussere Legende</legend>
    <label for="textinput1">Explizites Label:</label><br>
    <input type="text" name="textinput1" id="textinput1"><br>
    <label>Implizites Label:</label><br>
    <input type="text" name="textinput2" id="textinput2"></label><br>

    <fieldset>
      <legend>Innere Legende Eins</legend>
        <input type="radio" name="flavor1" id="toffee" value="toffee">
        <label for="toffee">Vanilla Toffee Crunch</label><br>
        <input type="radio" name="flavor1" id="chunky" value="chunky">
        <label for="chunky">Chunky Monkey</label><br>
        <input type="radio" name="flavor1" id="oatmeal" value="oatmeal">
        <label for="oatmeal">Oatmeal Cookie Chunk</label>
    </fieldset>

    <fieldset>
      <legend>Innere Legende Zwo</legend>
        <input type="checkbox" name="flavor2" id="brownie" value="chocolate">
        <label for="brownie">Chocolate Fudge Brownie</label><br>
        <input type="checkbox" name="flavor2" id="cookie" value="cookie">
        <label for="cookie">Chocolate Chip Cookie Dough</label><br>
        <input type="checkbox" name="flavor2" id="fudge" value="fudge">
        <label for="fudge">New York Super Fudge Chunk</label>
    </fieldset>

  <button type="submit">Haben Wollen!</button>

</fieldset>

In der grafischen Ausgabe sind diese Fieldsets deutlich voneinander getrennt; per CSS können Sie nun den inneren Fieldsets ein anderes Aussehen verpassen als dem Äußeren:

Diese Verschachtelungen können Sie sich beispielsweise zunutze machen und optionale Formularbereiche gruppieren, die vom Nutzer nicht zwingend ausgefüllt werden müssen. Der Nutzer kann diese so einfacher überspringen; per JavaScript können Sie den Nutzer diese optionalen Felder auch einfach ausblenden lassen. Mit FIELDSET haben Sie hier das semantisch naheliegendste Element gewählt statt eines bedeutungslosen generischen DIV.

Zu viel des Guten: Überlange oder unnötige Legenden

Verbreitete Screenreader lesen im Formularmodus den Inhalt einer Legende nicht zu Beginn des Fieldsets vor. Stattdessen wird der Text bei jedem einzelnem Kontrollelement bzw. dessen Label vorgelesen, das sich innerhalb des damit ausgezeichneten Fieldsets befindet. Dies kann, je nach Legendentext, sehr schnell dazu führen, dass Ihre Formulare im Screenreader kaum noch zu benutzen sind. Beim Nutzer werden ganz sicher Ermüdungserscheinungen hervorgerufen, wenn er gezwungen wird, sich den immer gleichen Zusatztext bei jeder einzelnen Checkbox und bei jedem einzelnem Radiobutton anzuhören.

Das Verhalten der Screenreader ist an sich nicht schlecht: so wird dem Nutzer jederzeit die Orientierung geboten, in welchem Bereich eines Formulars er sich befindet – was dem sehenden Nutzer durch optische Zusammenhänge klar wird, in der Sprachausgabe jedoch naturgemäß fehlt. Problematisch wird dieses Verhalten nur, wenn der Legendentext eine bestimmte Länge überschreitet oder im gesprochenen Zusammenhang mit dem Labeltext keinen Sinn mehr ergibt.

Wann Sie diese Grenze überschritten haben, ab der es zu viel wird, können Sie mit einem einfachen Test auch ganz ohne Screenreader feststellen: Lesen Sie den Textinhalt des Formulars laut vor und setzen die Legende erneut vor jedes Label. Wenn sich das dann so anhört:

»Ihre persönlichen Daten eingeben Ihr Vorname Ihre persönlichen Daten eingeben Ihr Nachname Ihre persönlichen Daten eingeben Ihre Adresse Ihre persönlichen Daten eingeben Ihre Postleitzahl Ihre persönlichen Daten eingeben Ihr Ort Ihre persönlichen Daten eingeben Abschicken«

dann haben Sie klaren Bedarf zur Nachbesserung. Unter Umständen kann es angebracht sein, auf LEGEND ganz zu verzichten, besonders wenn die Kontrollelemente durch die verwendeten Labels ausreichend beschrieben sind. Leider geben einige Accessibility-Checker einen Fehler aus, wenn kein LEGEND im Code vorgefunden wird. Unsere kritische Haltung gegenüber diesen Prüfprogrammen ist hinreichend bekannt – im Ernstfall sollte man sich hier für den Nutzer entscheiden.

Ein weiteres Problem entsteht, wenn verbreitete Screenreader wie JAWS die Zuordnung der LEGEND zu den Formularelementen kurzerhand selber übernehmen und anfangen zu raten. Im nächsten Codelisting sehen Sie eine durchaus zulässige Art der Verschachtelung, die aber bei Screenreader-Nutzern für einige herzhafte Lacher sorgen dürfte:

<fieldset>
  <legend>Persönliche Informationen</legend>
    <label for="vorname">Vorname</label>
    <input type="text" id="vorname" name="vorname">
    <label for="nachname">Nachname</label>
    <input type="text" id="nachname" name="nachname">

    <fieldset>
      <legend>Geschlecht</legend>
        <input type="radio" id="mann" name="geschlecht" value="mann">
        <label for="mann">Mann</label>
        <input type="radio" id="frau" name="geschlecht" value="frau">
        <label for="frau">Frau</label>
    </fieldset>

    <label for="telefon">Telefon</label>
    <input type="text" id="telefon" name="telefon">

</fieldset>

Hier wird JAWS die Legende »Persönliche Informationen« für die beiden Textfelder »Vorname« und »Nachname« übernehmen und als nächstes dann »Geschlecht Mann Geschlecht Frau Geschlecht Telefon" vorlesen, weil »Geschlecht« die von »Telefon« aus gesehen nächste Legende ist. Weitere interessante Hintergrundinfos über das Verhalten verbreiteter Screenreader finden sie in dem Artikel »Fieldsets, Legends and Screen Readers« von Steve Faulkner

Sind Überschriften nicht manchmal besser?

Wenn Ihr Formular in einer ansonsten mit Überschriften strukturierten (Text-) Seite steht, kann es durchaus sinnvoll sein, auf den Einsatz von Fieldset und Legend ganz zu verzichten und dem Formular stattdessen eine eigene Überschrift (H1-6) zu geben. Auch wenn Ihr Formular aus einem einzigen Kontrollelement besteht, ist das volle Programm aus FIELDSET, LEGEND usw. oftmals ein Code-Overkill, mit dem bestenfalls redundante Informationen mehrfach transportiert werden.

Strukturen im Kleinen: Optgroup

Ein Element fristet leider ein Schattendasein und wird im Code von Formularen viel zu wenig eingesetzt: OPTGROUP. So wie Sie mit Fieldsets größere logische Einheiten von Formularelementen gruppieren können, so geht dies per <optgroup>-Tags auch innerhalb von Auswahlfeldern vom Typ SELECT. Innerhalb einer Optgroup können zum Beispiel Länder der jeweiligen Kontinente zusammengefasst werden oder Geschmacksrichtungen bei der Auswahl von Eissorten, wie das folgende Markup-Beispiel zeigt:

<select name="Eissorte">

  <option disabled selected>Bitte auswählen:</option>

  <optgroup label="Schokoladig"> 
    <option>Chocolate Fudge Brownie</option>
    <option>New York Super Fudge Chunk</option>
    <option>Chocolate Therapy</option>
    <option>Chocolate Chip Cookie Dough</option>
  </optgroup>

  <optgroup label="Fruchtig">
    <option>Cherry Garcia</option>
    <option>Bohemian Raspberry</option>
    <option>Chunky Monkey</option>
    <option>Peace of Cake</option>
  </optgroup>

</select>

Durch das label-Attribut von OPTGROUP (nicht zu verwechseln mit dem LABEL-Element!) können nun den einzelnen Gruppen noch Kennzeichnungen vorangestellt werden, die selbst nicht auswählbar sind, sondern nur der Strukturierung dienen. Das Ergebnis sieht im Browser wie folgt aus:
Darstellung einer Optgroup in Safari unter Mac OS X Darstellung einer Optgroup im Internet Explorer unter Windows

Etikettierung mit Label

Neben der Navigation sind Formulare die Elemente einer Webseite, mit denen die Nutzer am häufigsten interagieren. Daher ist gerade bei Formularen nicht nur die Unabhängigkeit von den Ausgabemedien, sondern auch von den Eingabemedien wichtig. Eine wirkliche Barrierefreiheit erreichen Sie erst, wenn die bereitgestellten Funktionen mit einer Vielzahl von Eingabe- und Zeigegeräten bedient werden können. Zum Glück bietet HTML hierfür Elemente, die eine Bedienung unabhängig von der Umgebung ermöglichen.

Sie kennen diese Techniken aus Ihrem Betriebssystem und anderen Anwendungen: in Dialogen mit Checkboxen und Radiobuttons lassen sich nicht nur die Kontrollelemente selbst betätigen; es reicht auch, wenn man den daneben stehenden Text anklickt und schon ist das Häkchen gesetzt. Der Hintergrund dafür ist eine einfache Regel: je größer das Ziel, desto höher die Trefferwahrscheinlichkeit.

Mit dem dafür nötigen kleinen Kunstgriff kommen nicht nur erfahrene Nutzer schneller zum Ziel, die diese größere Klickfläche aus Anwendungen gewohnt sind. Gerade Menschen mit motorischen Behinderungen, die Probleme mit der exakten Positionierung der Maus haben oder alternative Zeigegeräte benutzen, können nun auf den dazugehörigen Text des Formularfeldes, das sogenannte Label, klicken. Blinde oder stark sehbehinderte Nutzer von Screenreadern sind ebenfalls auf die Bedienung per Tastatur angewiesen. Erst durch die Verknüpfung des Kontrollelementes mit seiner Beschriftung wird in der Sprachausgabe Sinn und Zweck des jeweiligen Kontrollelementes klar.

Label in HTML

HTML sieht hierfür seit der Version 4 das Element LABEL vor. Über dieses Label können Sie die Feldbeschriftung mit dem dazu gehörigen Kontrollelement verknüpfen, indem Sie letzterem eine eindeutige ID (id="textfeld1") zuweisen. Diese ID wird dann ebenso im for-Attribut des Start-Tags von LABEL benutzt und schon ist die Beschriftung mit dem jeweiligen Formularelement verknüpft und anklickbar:

<label for="textfeld1" class="left">Text:</label>
  <input id="textfeld1" type="text">
  […]
  <input id="checkbox1" type="checkbox" value="ja">
  <label for="checkbox1">Ja</label>

Diese Methode funktioniert bei allen Kontrollelementen, denen ein Label zugewiesen werden kann. Beachten Sie, dass einem Kontrollelement gemäß dem HTML-Standard zwar mehrere Label zugeordnet werden können, dies aber zu Problemen führt (Beispieldatei: multiple-label.html).

Folgenden Elementen können und sollten Label zugewiesen werden:

  • input type="text"
  • input type="checkbox"
  • input type="radio"
  • input type="file"
  • input type="password"
  • textarea
  • select

Label können nicht für folgende Elemente verwendet werden, da hier die Informationen über das value-Attribut (z.B. für submit-Buttons), das alt-Attribut (für grafische Buttons vom Typ input type="image") oder den Inhalt des Elementes selbst transportiert werden:

  • Submit und Reset-Buttons (input type="submit" bzw. input type="reset")
  • Grafische Buttons (input type="image")
  • Versteckte Eingabefelder (input type="hidden")
  • Script-Buttons (BUTTON-Element bzw. input type="button")

Warnhinweise: Probleme mit Screenreadern

Implizite Label

Nach den Spezifikationen ist es zulässig, das Label um das Kontrollelement herum zu legen, statt es ihm vor- oder nachzustellen. Hiermit könnte man sich als Webentwickler die Zuweisung über id="" und for="" sparen, da das Label nun durch diese Verschachtelung implizit zugeordnet ist:

<label>Text:<input type="text"></label>

Soweit die Theorie. Die Unterstützung für diese Variante ist jedoch selbst in aktuellen assistierenden Programmen eher lückenhaft und daher nicht zu empfehlen. Selbst aktuelle Versionen der verbreiteten Screenreader JAWS und Window Eyes haben bis dato Probleme mit impliziten Labels, obwohl diese bereits seit 1997 Bestandteil der HTML 4-Empfehlung sind. So werden implizite Labels für Checkboxen und Radiobuttons sogar im Formularmodus nicht vorgelesen, bei Textfeldern ist dies nach Aussage von Nutzern »Glückssache«. Um maximale Kompatibilität zu garantieren, sollten Sie auf die zuerst beschriebene Form der expliziten Verknüpfung zurückgreifen.

Falls Sie aus irgendwelchen Gründen gezwungen sein sollten, implizite statt explizite Labels zu benutzen, so können Sie den Label-Text in einem title-Attribut des jeweiligen Kontrollelementes wiederholen. In diesem Fall lesen JAWS, Window Eyes & Co. den Text des title-Attributs, sobald das Kontrollelement den Fokus erhält.

Mehrere Label zuweisen

Oft besteht die Notwendigkeit, einem Kontroll- oder Eingabeelement mehrere Label zuzuweisen. Dies ist zum Beispiel dann der Fall, wenn ein Fehler aufgetreten ist und man neben dem ursprünglichen Label auch noch die Fehlermeldung mit dem Ort des Fehlers verknüpfen will. Was liegt da näher als diese Fehlermeldung gleich als Label zu deklarieren – wie sich beim Blick in die HTML4-Spezifikation herausstellt eine durchaus zulässige Methode:

»Mehr als ein LABEL kann mit dem gleichen Steuerelement verknüpft werden, wenn mehrere Verweise über das for-Attribut erzeugt werden.«

In grafischen Browsern klappt das auch hervorragend: beide Labels lassen sich anklicken und die verknüpften Formularelemente werden fokussiert. Nur leider tanzen hier mal wieder einige Screenreader aus der Reihe:

  • VoiceOver von Apple erkennt nicht mehr als ein Label und liest immer das Label vor, das im Quelltext zuerst steht.
  • NVDA liest in der Kombination mit Firefox ebenfalls nur das erste Label vor.
  • JAWS und Window Eyes mit Internet Explorer machen genau das Gegenteil und lesen nur das letzte Label vor.

Mehrere Labels sollten also nur nach intensiver Abwägung und Tests eingesetzt werden, gegebenenfalls müssen auch die Labeltexte angepasst werden, um unter allen denkbaren Szenarien noch einen Sinn zu ergeben. Ein gelungenes Beispiel für zusätzliche Labels sehen Sie im folgenden Screenshot aus dem Spendenformular von sternstunden.de (Gewinner einer BIENE 2010). Die Labels sind hier durch ihre Betextung in allen der oben genannten Fälle noch so sinnbildend, dass dieses Problem nicht weiter auffällt:

Wie Sie trotzdem mehrere optisch von einander getrennte Elemente mittels eines gemeinsamen Labels verknüpfen können beschreibt der Artikel »Always read the <label>« von Richard Northover im Web Developer Blog der BBC. Falls Sie in Ihren Formularen WAI-ARIA einsetzen helfen unter Umständen auch die Attribute aria-labelledby und aria-describedby, mit denen man eine Verknüpfung auch ohne Label herstellen kann. Näheres dazu im Blog von Marco Zehe: »Easy ARIA tip #2: aria-labelledby and aria-describedby«

Label verstecken

Ein gern gesehener Fehler ist, dass ein wohlmeinender Frontend-Entwickler aus Accessibility-Gründen ein Label einbaut, wo vom Design her keines vorgesehen ist und dies dann per CSS mit display:none; versteckt. Leider kann man sich nicht darauf verlassen, dass Screenreader diese Label noch vorlesen, weil auch sie natürlich vom Browser mit dem fertig verarbeiteten Dokument versorgt werden. Und da heisst display:none; übersetzt: »Tu so als wäre dieses Element nicht im Dokumentenbaum vorhanden«. JAWS und NVDA lesen derart versteckte Label zwar vor, wenn das verknüpfte Eingabeelement fokussiert wird, allerdings nur im Virtuellen-Cursor-Modus in der Kombination zusammen mit Internet Explorer, nicht jedoch wenn die Screenreader zusammen mit Firefox eingesetzt werden.

Da man sich also nicht auf diese Form des Versteckens verlassen kann, bietet es sich an, die Labels mit der offleft-Methode aus dem Viewport zu schieben – diese wird von Screenreadern wie gewünscht vorgelesen:

label {
  height: 1px;
  left: -999em;
  overflow: hidden;
  position: absolute;
}

Weitere Informationen, wie Screenreader mit versteckten Elementen umgehen, finden Sie im Artikel »Invisible Form Prompts« von Gez Lemon.

Neu! Jetzt mit Knopf zum Selberdrücken!

Auch wenn Labels aus Sicht der Accessibility sicher ein wichtiges Element sind, ohne Abschicken- oder Speichern-Buttons geht gar nichts. Dafür kennt der HTML-Standard gleich zwei Methoden: die verbreitete per input type="submit" und das weithin unbeachtete, aber wesentlich flexiblere BUTTON-Element. Die Syntax für die Funktionen ist bei beiden Methoden gleich – mit button type="submit" wird ein Formular bzw. dessen Inhalt ebenfalls zum Server geschickt.

Werte für Buttons

Bei Elementen ohne Label wie z.B. »Abschicken«-Buttons müssen die Informationen zur ausgelösten Aktion über den jeweiligen Wert des Kontrollelementes (value="Formular abschicken") hinterlegt werden. Wenn Sie diesen Wert nicht setzen, überlassen Sie es damit dem jeweiligen Browser, welcher Text auf dem Button erscheint. Ein einfaches:

<input type="submit">

ohne Angabe des Attributs value ergibt:

Dieser vom Browser nach Gutdünken vergebene Text muss nicht unbedingt dem Ergebnis der ausgelösten Aktion entsprechen. Der Internet Explorer macht z.B. aus dem obigen Code »Anfrage senden«, in Firefox heißt der Text »Daten absenden« (bzw. in älteren Versionen »Anfrage abschicken«), bei Safari, Chrome und Opera ist das Ergebnis ein einfaches »Senden«. Bei den englischen Programmversionen wird vom jeweiligen Browser ein englischer Text eingefügt (»Submit …«), was in den meisten Fällen wenig wünschenswert ist.

Wenn Sie grafische Buttons nach der Art von <input type="image" src="button.gif"> beziehungsweise <button><img src="button.gif"></button> verwenden, sollten Sie grundsätzlich ein alt-Attribut setzen, ansonsten wird der grafische Button von einer Sprachausgabe nicht vorgelesen und das Formular ist damit für Screenreader-Nutzer nicht mehr verwendbar.

Im Interesse von Nutzern, die Ihre Formulare mit Spracherkennung bedienen, sollte das alt-Attribut den exakten Text des grafischen Buttons als Äquivalent enthalten. Die Spracherkennungs-Software orientiert sich am Quelltext und weiss nicht, was in Ihrem grafischen Button steht; der Nutzer wiederum liest den Text des grafischen Buttons . Wenn dieser nicht mit dem maschinenlesbaren Text übereinstimmt, wird die Aktion nicht ausgeführt.

Vermeiden Sie Sonderzeichen

Ein besonderes Problem für viele alternative Zugangsformen ist die gelegentlich zu sehende Verwendung von Sonderzeichen oder so genannten Dingbat-Fonts. Sie können nicht davon ausgehen, dass alle Nutzer die gleichen Zeichensätze wie Sie installiert haben, und insbesondere bei Exoten führt dies oftmals zu unvorhergesehen Ergebnissen. So zeigt das folgende Codefragment:

<button type="submit">Öffnen <span style="font-family:Wingdings">1</span></button>

unter Windows aller Wahrscheinlichkeit nach ein Symbol mit einem sich öffnenden Ordner an, auf anderen Plattformen wird jedoch eventuell die Ziffer »1« dargestellt und auch Screenreader lesen hier ganz konsequent eine Zahl vor.

Vermeiden Sie Hintergrundbilder

Statt der problematischen Sonderzeichen sieht man oftmals auch Icons in Buttons , die als CSS-Hintergrundbilder realisiert sind. Diese Methode der Umsetzungen bringt jedoch ihre eigenen Probleme in punkto Barrierefreiheit mit sich: so sind Hintergrundbilder grundsätzlich nicht mehr sichtbar, sobald der Benutzer eigene Farben z.B. über ein Windows-Kontrastschema eingestellt hat. Fatal sind die Auswirkungen dann, wenn das Hintergrund-Icon der einzige Inhalt z.B. eines Button-Elements ist, insbesondere weil man diesen keinen Alternativtext zuweisen kann

Die Auswirkungen dieser Technik und eine mögliche Lösung per CSS zeigt Steve Faulkner in seinem Artikel »High Contrast Proof CSS Sprites«.

Formulare mit und ohne Tabellen

Mangelnde Linearisierung: Warum Tabellen vollkommen ungeeignet für Formulare sind

Wie beim allgemeinen Layout von Seiten gilt auch für Formulare: Layout-Tabellen sind eine Technik aus dem vergangenen Jahrhundert. Mit Browsern der vierten und fünften Generation war eine durchgängige, also in allen damals vorhandenen Browsern vergleichbare Gestaltung und Funktionalität nur mit Layout-Tabellen erreichbar. Mittlerweile sind diese Browser aber den Gang alles Irdischen gegangen und tauchen in keiner Statistik mehr in Größenordnungen auf, die eine spezielle Berücksichtigung rechtfertigen würden.

Zudem sind die meisten im Netz zu findenden Formulare lediglich eine Abfolge von nacheinander abzuarbeitenden Funktionen, die aber meistens in keiner Beziehung zueinander stehen und somit auch keine tabellarischen Daten darstellen. Layout-Tabellen bringen eine Vielzahl von Problemen mit sich, insbesondere wenn sie nicht in einem der üblichen grafischen Browser ausgegeben werden. Das folgende Beispiel zeigt eine durchaus gängige Art für die Eingabe persönlicher Daten für den Benutzer in einer unsichtbaren Layout-Tabelle:

Zur Verdeutlichung hier nochmals die gleiche Tabelle, diesmal mit hervorgehobenen Rändern, um die Reihenfolge der Tabellenzellen zu verdeutlichen:

Werden die Inhalte dieser Tabelle nun in linearisierter Form dargestellt, also in der Reihenfolge, in der sie im Quelltext erscheinen, so ergibt sich in einem Screenreader folgender Output:

Vorname Name Textfeld Textfeld

Wenn in einem Formular viele Daten auf die gleiche Art abgefragt werden, verliert der Benutzer einer Sprachausgabe sehr schnell die Orientierung. Er kann die Beschriftungen zu den Formularelementen nicht mehr eindeutig zuordnen. Zwar können Sie die Beschriftungen per Label den jeweiligen Textfeldern zumindest programmatisch zuordnen, die Reihenfolge im Quelltext bleibt jedoch nach wie vor die Falsche und wird unter Umständen auch genau so falsch vorgelesen. Auch eine Zuordnung der Tabellenzellen über die für Datentabellen gedachten Elemente wie TH, scope, axis etc. ist nicht zu empfehlen, da solche Strukturelemente vom Screenreader im Formularmodus ignoriert werden.

Hier muss also eine Lösung gefunden werden, die in den gebräuchlichen grafischen Browsern ein adäquates Layout ermöglicht und trotzdem nicht die Bedienung der Formulare mit alternativen Zugangsmethoden verhindert.

Wenn Formulare mit tabellarischen Darstellungen vermischt werden, dann gelten auch hier die gleichen Regeln für den technischen Aufbau wie zu Beispiel die zwingende Verwendung von Labels. Im folgenden Screenshot aus der erweiterten Verkehrsmittelwahl bei bahn.de ist die Funktion der Checkboxen ohne die Zuordnung per Label nicht ersichtlich, da die Icons für ICE, IC, S-Bahn etc. nicht mit diesen verknüpft sind und die Checkboxen auch über keine sonstigen sprechenden Bezeichnungen (z.B. per title) verfügen:

Logische Verknüpfungen: Warum Tabellen wunderbar geeignet für Formulare sind

Anders gelagert ist der Fall unter Umständen bei web-basierten Anwendungen. Ein Beispiel: tabellarische Übersichten in Content Management-Systemen sind natürlich mit Tabellen zu strukturieren, da es sich um tabellarische Daten handelt – wenn auch als Mischform mit Formularen z.B. für die eigentlichen Editierfunktionen. Eine ganz einfache Regel: wenn man die Inhalte anhand der Kriterien in den Spalten- oder Zeilenköpfen sortieren kann, dann ist eine Datentabelle angebracht.

Auch browser-basierte Tabellenkalkulationen wie Google Spreadsheets oder jede andere Form der Eingabe und Manipulation komplexer Daten sind genau das: Tabellen. Hierfür sind die Tabellenelemente aus HTML nach wie vor hervorragend geeignet und somit die nahe liegende Technik zu ihrer Umsetzung. Allerdings gilt auch hier ganz besonders der Zwang zur Linearisierbarkeit, wenn diese Tabellen- und Formulargemische auch in nicht-visuellen Ausgabeformen nutzbar bleiben sollen. Wenn Sie die Inhalte von ihrem Codegerüst befreien, dann müssen sie in genau dieser Reihenfolge immer noch einen Sinn ergeben, denn genau so kommen sie aus dem Lautsprecher.

Allerdings helfen hier die Elemente und Attribute zur Strukturierung, die zwar in Layout-Tabellen unerwünscht sind, in komplexen oder mehrdimensionalen Datentabellen jedoch eine effektive Nutzung erst ermöglichen. Wie diese einzusetzen sind, können Sie in unserer BITV-Reloaded-Serie unter Anforderung 5 sowie im Artikel zu barrierefreien Datentabellen nachlesen.

Was Sie nicht tun sollten ist, die Optik einer Tabelle mit anderen Mitteln wie generischen DIV oder ähnlichem nachzuahmen. Dadurch würden gerade Nutzern nicht-visueller Zugangsformen wichtige Informationen und Anhaltspunkte zur Orientierung in den Datensätzen verloren gehen. Dem Entwickler des im Screenshot zu sehenden Bundesliga-Tabellenrechners hätte eigentlich spätestens beim Wort »Tabelle« auffallen müssen, dass es sich hier um tabellarische Daten handelt und folgerichtig eine HTML-Tabelle die richtigen Elemente zur Verfügung gestellt hätte. Schließlich heisst es ja Bundesliga-Tabelle und nicht Bundesliga-DIV:

Nur unter Aufsicht anwenden: Strittige Punkte

Es gibt einige Punkte, bei denen selbst unter Experten und Betroffenen keine Einigkeit herrscht, ob sie sinnvoll sind oder ob man diese Techniken auslassen kann und trotzdem noch ein barrierefreies Angebot hat. Ein übermäßiger Einsatz aller in HTML vorgesehenen Hilfen zur Orientierung und Navigation kann sogar bei manchen Nutzergruppen dazu führen, dass eine Seite weniger benutzbar wird. Das ist insbesondere dann der Fall, wenn die eingesetzte Technik einen übermäßigen Lernaufwand erfordert, der die Vorteile der Technik aufwiegt oder sogar übersteigt. Ein solcher Kandidat sind die von den Richtlinien und Verordnungen für Barrierefreie Internetauftritte verlangten Tastaturkürzel zur Navigation, die sogenannten Accesskeys.

Accesskeys – Ja oder Nein?

Die Idee hinter dem auch in HTML5 nach wie vor spezifizierten accesskey-Attribut ist eigentlich bestechend einfach: Wie in den gewohnten Desktop-Anwendungen kann man auch in HTML-Seiten Tastaturkürzel definieren, durch die bestimmte Aktionen ausgelöst werden. In HTML können diese Attribute einer Vielzahl von Elementen zugewiesen werden und somit unterschiedlichste Aktionen auslösen. Wie alle Attribute hat auch dieses einen Wert, der in Form von einzelnen Buchstaben oder Zahlen angegeben wird. Dieses Zeichen entspricht der Taste, die der Benutzer zusammen mit einer oder mehreren weiteren Tasten drücken muss, um die gewünschte Aktion auszulösen. Und genau da beginnt das Problem:

Unter den Browserherstellern herrscht keine Einigkeit, welche Tasten zusätzlich neben dem im Accesskey angegebenen Zeichen zu drücken sind.

  • Unter Windows sind dies im Internet Explorer die Alt-Taste + Accesskey + Enter
  • Im Mozilla Alt-Taste + Accesskey ohne Enter
  • Unter Opera sind es Shift + Esc + Accesskey ohne Enter
  • Auf anderen Plattformen wie dem Apple Macintosh sind es statt der Alt-Taste die Ctrl-Taste auch ohne Enter
  • Opera macht hier wieder die Ausnahme mit Shift + Esc und so weiter.

Sie sehen die Unmöglichkeit, einen erklärenden Hilfe-Text für eine Website zu verfassen. Zudem sind Accesskeys gerade für viele Menschen mit motorischen Behinderungen, für die sie auch gedacht waren, durch die Notwendigkeit zum gleichzeitigen Drücken mehrerer Tasten kaum zu gebrauchen.

Erschwerend kommt hinzu, dass die meisten Tasten, die man definieren kann, schon in anderen Programmen vergeben sind. Wenn man die gängigsten Browser untersucht und verbreitete assistierende Werkzeuge hinzunimmt, wird man sehr schnell feststellen, dass fast alle Zeichen der Tastatur schon von einem Programm benutzt werden.

Noch schwieriger wird die Situation bei mehrfach vergebenen Werten – dies ist zwar streng genommen ein Fehler, der aber von keinem Validator bemerkt wird und daher in der Praxis öfter vorkommt. Auch hier können sich die verschiedenen Browser nicht einigen, was zu tun ist, wenn ein Nutzer einen Accesskey auslöst, der mehrfach vorhanden ist:

  • Firefox geht alle Elemente, denen der gleiche accesskey zugewiesen wurde, in der Reihenfolge ihres Auftretens durch. Aktivierbare Elemente (wie Links und Buttons ) werden zwar fokussiert, aber nicht ausgelöst.
  • Internet Explorer geht, wie Firefox, alle Elemente, denen der gleiche accesskey zugewiesen wurde, in der Reihenfolge ihres Auftretens durch. Allerdings werden Buttons sofort ausgelöst, d.h. Daten unter Umständen übergeben, die der Nutzer noch gar nicht absenden wollte.
  • Webkit (Safari/Chrome) löst das letzte Element aus, dem einer dieser mehrfach vergebenen Accesskeys zugewiesen ist.
  • Opera löst das erste Element aus, dem einer dieser mehrfach vergebenen Accesskeys zugewiesen ist.

Weitere Hintergründe zu diesem Thema finden Sie im Artikel »If you use the accesskey attribute, specify unique values« von Roger Johansson.

Noch problematischer ist, dass jeder Webentwickler entscheiden kann, wie er diese Tasten vergibt. Für die Vergabe der Accesskeys gibt es keine einheitliche Richtlinie, so dass der Benutzer auf jeder Website, die er neu ansurft, zunächst einmal die Accesskeys erlernen müsste. Diese nicht kontrollierbaren Folgen sind einer der Gründe, warum z.B. die kanadische Bundesregierung die Verwendung von Accesskeys wieder aus ihrem Style Guide gestrichen hat.

Ausnahme: Wenn Sie eine web-basierte Anwendung mit vielen ähnlichen Formularen für ein Intranet entwickeln, können Sie natürlich genauere Vorhersagen darüber treffen, welche Accesskeys in Ihrer Umgebung funktionieren. In diesem Fall haben Sie ja die volle Kontrolle über die zu verwendende Zugangssoftware. Bei einem solchen System kann die Definition von Accesskeys für immer wiederkehrende Funktionen (also z.B. immer das erste Eingabefeld oder unterschiedliche logische Blöcke) sinnvoll und lohnenswert sein. In diesem Fall reden wir aber von Webinhalten, die keinen Dokumenten-Charakter haben, sondern eindeutig Anwendungs-Charakter. Bei Webseiten, die lediglich aus strukturierten Texten, der dazugehörigen Navigation und gelegentlichen simplen Formularen bestehen, lohnt sich der Einsatz generell nicht.

Tabindex – Ja oder Nein?

Ein enger Verwandter des accesskey-Attributes ist der tabindex. Mit diesem Attribut können Sie die Reihenfolge festlegen, in der sich ein Anwender per Tabulator-Taste durch eine Seite bewegen kann. Dies geschieht jedoch nicht in willkürlicher Form wie bei den Accesskeys, sondern in der Reihenfolge, die Sie bei der Erstellung des Formulars definieren:

<input type="text" id="suchfeld" size="20" tabindex="1">

Da die meisten Browser und assistierenden Programme von sich aus die Navigation per Tabulator-Taste unterstützen, brauchen Sie nicht jedes Element einer Seite mit einem Tabindex zu dekorieren. Dies wäre kontraproduktiv, da Sie nicht vorhersagen können, in welcher Reihenfolge der Benutzer durch die Seite navigieren möchte oder an welcher Stelle der Benutzer mit der Navigation beginnt. Zudem entspricht die Tabreihenfolge grundsätzlich dem Ablauf des Quellcodes – wenn sie hier für eine vernünftige und nachvollziehbare Abfolge sorgen, dann ist das tabindex-Attribut nicht mehr nötig.

Sinnvoll ist der Einsatz des tabindex-Attributes in Formularen, wenn die Reihenfolge, in der Kontrollelemente bedient oder Texteingaben gemacht werden sollten, nicht der Reihenfolge dieser Elemente im Quelltext entspricht. Dies kann zum Beispiel bei der Eingabe von Postleitzahl und Ort in zwei unterschiedliche Felder der Fall sein. Diese werden vom Benutzer in genau dieser Reihenfolge erwartet, müssen aber im Quelltext nicht unmittelbar aufeinander folgen und können unter Umständen nicht nacheinander von der Tabulator-Taste angesprungen werden.

Gerade bei mehrspaltigen Formularen muss die optische Anordnung nicht unbedingt den Erwartungen der Nutzer und der Abfolge im Quelltext entsprechen. Da Nutzer in Formularen ja bereits die Tastatur zur Eingabe benutzen müssen, steigt die Wahrscheinlichkeit, dass die Navigation innerhalb des Formulars ebenfalls per Tastatur (Tab-Taste, Pfeiltasten, Enter etc.) stattfindet – eine sinnvolle Tabreihenfolge wird dadurch umso wichtiger.

Wenn Sie in Ihren Formularen tabindex setzen wollen, dann sollten Sie diese für die LABEL-Elemente und nicht für die eigentlichen Kontrollelemente (Textfeld, Checkbox usw.) definieren. So stellen Sie sicher, dass diese Beschriftungen von einer Sprachausgabe zugeordnet und vorgelesen werden.

Tipp: Wenn Sie in mehreren Bereichen einer Seite Werte für tabindex vergeben, können Sie dies auch in 10er-Schritten machen. Mit diesem kleinen Kniff brauchen Sie bei Erweiterungen mitten in einer Seite nicht alle folgenden Elemente mit tabindex-Attribut neu zu numerieren. Uns ist bisher noch kein Browser begegnet, der dieses Attribut zwar versteht, aber nicht von tabindex="14" nach tabindex="20" springen kann, wenn die Werte dazwischen nicht vergeben sind.

Vorbelegung von Formularfeldern

Ein weiterer Punkt, an dem sich die Geister scheiden: die Vorbelegung von Formularelementen wie etwa Textfeldern durch einen Text, der im jeweiligen Feld angezeigt wird. Die Wurzeln der entsprechenden Vorgaben in den WCAG und damit auch der BITV-Bedingung 10.4 stammen noch aus einer Zeit, als angeblich manche Screenreader leere Textfelder nicht erkannten und darüber hinweg lasen. Uns ist jedoch kein einziges Hilfsmittel bekannt, das nach wie vor diesen Fehler aufweist, somit lässt sich diese Forderung der BITV nicht weiter aufrechterhalten. Weitere Informationen hierzu finden Sie in unserer BITV-Serie unter Bedingung 10.4, Testergebnisse verschiedener Methoden zum Vorbelegen und Löschen finden Sie im Artikel »Testing Accessibility of Pre-populated Input Fields« von Terrill Thompson.

Übermäßiger Einsatz von title-Attributen

Nicht nur in Navigationsleisten, auch in Formularen findet man häufig Inhalte und Funktionen, deren Sinn und Zweck sich erst erschließt, wenn man mit der Maus ein Tooltip auslöst. In diesen per title-Attribut realisierten kleinen Fähnchen stehen dann oftmals erläuternde Hinweise dazu, was sich hinter der jeweiligen Funktion verbirgt, da die Funktion selbst nicht verständlich beschriftet ist. Wenn Ihre Funktionen ohne diese Tooltips nicht verständlich sind – sollten Sie dann nicht lieber den Aufwand für die technische Umsetzung und Betextung dieser title-Attribute in verständlichere Icons, Buttons und Links stecken? Zumal diese title-Attribute nur bei Mausbedienung erscheinen, für Tastaturnutzer oder auf den Touchscreeens von Tablet-PCs oder Smartphones bleiben sie üblicherweise verborgen.

title-Attribute als Label-Ersatz

Berechtigte Ausnahmen von diesem Einwand gibt es aber dennoch: das title-Attribut kann als Ersatz für Label genommen werden, wenn diese aus irgendeinem Grund nicht einsetzbar sind (seien es Platzgründe oder aus technischen Gründen, die dagegen sprechen). Screenreader behandeln diese title dann wie LABEL und lesen sie entsprechend vor (selbst dann, wenn das Programm so eingestellt ist, dass eigentlich keine title vorgelesen werden sollen). Diese Vorgehensweise ist im Übrigen auch durch die Richtlinien der WCAG abgedeckt, näheres dazu in den Techniken unter »H65: Benutzung des title-Attributs, um Formular-Steuerelemente zu kennzeichnen, wenn das Label-Element nicht benutzt werden kann«.

Diese Eigenheit von Screenreadern können Sie ausnutzen, um ganz gezielt Informationen an die Nutzer solcher Hilfsmittel zu kommunizieren (Bildschirmlupen haben ebenfalls vergleichbare Funktionen, um die Inhalte von title-Attributen anzuzeigen, wenn ein Element den Fokus erhält). Ein Beispiel für den sinnvollen Einsatz wären Funktionen, die durch ihr Layout oder andere optische Eigenschaften verdeutlicht werden und man befürchten muss, dass diese Information in der Sprachausgabe, bei extremer Vergrößerung oder bei benutzerdefinierten Farben verloren gehen.

Weitere Gedanken zum Einsatz von title-Attributen finden Sie im Artikel »Using titles on form fields« von Mike Davies.

HTML5 jenseits des Hypes

Ein wenig Geschichte

Die konzeptionellen Vorarbeiten für HTML5 begannen irgendwann in den Jahren 2003/2004 bei Opera unter dem Namen Web Applications 1.0. Bald wurde die Sprache von einem Zusammenschluss verschiedener Browser-Hersteller jenseits der Standardisierungs-Gremien des W3C weiterentwickelt. Diese so genannte Web Hypertext Application Technology Working Group (WHATWG) wurde von Apple, Mozilla und Opera getragen und hatte zum Ziel, die mittlerweile seit über 10 Jahren bestehenden Lücken in HTML4/XHTML1 durch die Festlegung neuer Elemente zu schließen, die für zeitgemäße Web-basierte Applikationen dringend benötigt wurden.

Im Jahr 2007 installierte das W3C schließlich eine neue HTML-Arbeitsgruppe (die alte war de fakto aufgelöst und XHTML2 hatte sich als Sackgasse erwiesen) und übernahm somit die Weiterentwicklung der Spezifikation. Zurzeit wird mit der Veröffentlichung einer sog. Candidate Recommendation für das Jahr 2012 gerechnet.

Sagen was gemeint ist: präzisere Beschreibung durch neue Elemente

Dass der neue Standard noch nicht fertig ist, sollte aber niemanden vom Einsatz der neuen Elemente abhalten – im Gegenteil: die meisten modernen Browser bieten mittlerweile einen hohen Grad der Unterstützung, der zudem laufend verbessert wird, und in der Zwischenzeit ist sogar Microsoft mit an Bord.

HTML5 bringt neben einer ganzen Reihe neuer Elemente, der vereinfachten Syntax und den JavaScript-APIs nun endlich ein weitgehend standardisiertes Browserverhalten. Im Gegensatz zu den älteren Spezifikationen wird hier sehr detailliert beschrieben, was Browser mit den einzelnen Elementen einer HTML5-Seite machen sollen und selbst die möglichen Fehler und wie Browser sich von ihnen »erholen« ist im Detail festgelegt.

Der Nachteil dieser Genauigkeit: die gesamte Dokumentation ist dadurch wesentlich umfangreicher geworden. @thomasfuchs bemerkte bei Twitter, dass die gesamte HTML-Spezifikation im Jahre 1998 mit 9.967 Worten auskam – mittlerweile hat allein das einleitende HTML5-Overview-Dokument 311.000 Wörter!

Wie immer bei noch nicht endgültig verabschiedeten Standards kann und wird sich noch einiges ändern. Im Extremfall können auch Dinge wieder entfallen wenn sich herausstellt, dass sie in keinem Browser vernünftig umgesetzt werden. Daher sollte man, wenn man in seiner Applikation auf HTML5 setzt, die Fortentwicklung genau beobachten.
Übrigens: Nicht Teil von HTML5 ist CSS3, auch wenn sich manche Artikel im Netz so lesen – dies ist nach wie vor ein eigenständiger Standard.

Was geblieben ist: HTML legt nach wie vor lediglich die Struktur der Inhalte fest. Es tut dies aber auf eine Art und Weise, die eine viel präzisere Beschreibung der Inhalte und Funktionen einer Seite oder einer Applikation erlaubt. In Verbindung mit den neu definierten APIs werden komplexe Interaktionen ermöglicht, die bisher nur mit sehr viel JavaScript oder mit Fremdformaten wie Flash (auf Kosten der Zugänglichkeit) zu erreichen waren.

Dies gilt besonders für den Bereich der Formulare, auch wenn hier die Unterstützung in den verschiedenen Browsern noch sehr uneinheitlich und lückenhaft ist. Bei den neuen HTML5-Elementen zur Festlegung der Seitenstruktur ist der Einbau noch relativ einfach und ohne gravierende Nebenwirkungen zu erreichen. Selbst Browser wie Internet Explorer 6 bis 8 kann man mit einem kleinen Schubs per JavaScript dazu bringen, dass sie diese Elemente verstehen:

document.createElement('header');
  document.createElement('footer'); …

Andere Browser brauchen hingegen etwas Nachhilfe im CSS, um die neuen Elemente wie gewünscht darzustellen. Da unbekannte Elemente laut Spezifikation von HTML5-konformen Browsern zunächst einmal als inline-Elemente verarbeitet werden müssen, muss man hier noch explizit angeben, dass bestimmte Elemente als sog. block-level-Elemente gerendert werden sollen. Dies ist jedoch zum Glück mit einigen wenigen Zeilen Code erledigt:

header, footer, … {
  display: block;
}

Bei dem guten Dutzend neuer Formular-Elementen ist dies leider nicht ganz so einfach. Zwar haben die neuen Input-Elemente den nicht zu unterschätzenden Vorteil, dass in allen relevanten älteren Browsern an ihrer Stelle ein althergebrachtes Textfeld (<input type="text">) dargestellt wird, wenn die neuen Datentypen nicht erkannt werden. Allerdings braucht man für solche Fälle dann immer noch ein Fallback, um den Nutzern solcher Browser zum Beispiel die Auswahl eines Datums aus einem klassischen, JavaScript-basierten Kalender-Widget zu ermöglichen.

Auch in aktuellen Browsern kann man nicht davon ausgehen, dass diese z.B. ein natives Kalender-Widget (<input type="datetime">) auch anzeigen, wenn dies vom Autor des Formulars so gewünscht wird – auch hier sind unter Umständen Fallback-Lösungen nötig, zumal es in vielen Browsern auch mit der Barrierefreiheit dieser Widgets nicht so weit her ist. So sind zum Beispiel viele der Elemente selbst in manchen modernen Browsern schlichtweg nicht per Tastatur bedienbar.

Hinzu kommt das Problem, dass diese Widgets generell nicht per CSS formatierbar sind, weil sie nicht Teil des DOMs sind. Man übergibt also die volle Kontrolle über Darstellung und Bedienung an den Browser – mit teils ungeahnten Konsequenzen: der nebenstehende Screenshot bereitete uns einige Mühe, weil Opera bei jedem Versuch die Schrift zu skalieren, reproduzierbar abstürzte.

Was gibt's Neues?

Zunächst einmal eine ganze Reihe neuer Input-Typen und zusätzliche Attribute wie zum Beispiel:

  • <input type="email">
  • <input type="date">
  • <input type="time">
  • <input type="month">
  • <input type="week">
  • <input type="datetime" … >
  • <input type="range">
  • <input type="number">
  • <input type="color">
  • <input type="search">
  • <input type="file" multiple>
  • <input … autofocus>
  • <input … autocomplete>
  • <input … required>
  • <input … pattern="[a-z]{3}[0-9]{3}">

(Die althergebrachten Input-Typen wie z.B. button, file, hidden, image, password, reset, submit und text sind natürlich weiterhin Teil des HTML-Standards.)

Ein immenser Vorteil dieser Input-Typen ist, dass sie von sich aus nur bestimmte Eingaben oder Auswahlen ermöglichen, ohne dass man die dahinter liegende Logik skripten muss – dies erledigt ein geeigneter Browser von ganz allein. So werden Browser in die Lage versetzt, bei bestimmten Typen die Eingaben direkt zu validieren, ohne dass dafür JavaScript ausgeführt oder der Server konsultiert werden muss. Hier ein Beispiel für Input-Felder vom Typ "url" in Opera 11:

Bisher musste man solche Eingaben client- und serverseitig mit regulären Ausdrücken auf ihre Gültigkeit überprüfen. Nun lassen sich über einfache Attribute nicht nur Pflichtfelder festlegen (required-Attribut), sondern der Browser prüft auch gleich noch, ob es sich bei der Eingabe um einen der korrekten Syntax entsprechenden URL handelt.

<form action="foo.bar" method="get">
  <label for="url">URL:</label>
  <input type="url" id="url" name="url" required>
  …
</form>

Tipp: falls Sie die browserseitige Validierung verhindern wollen und sich lieber auf ihre eigenen Methoden verlassen möchten, können Sie die novalidate- und formnovalidate-Attribute setzen, die dies effektiv verhindern.

Mit Hilfe des pattern-Attributs lässt sich dann noch überprüfen, ob z.B. bestimmte Vorgaben an das Format (z.B. https:// für eine gesicherte Verbindung) eingehalten wurden.

Noch ein paar konkrete Beispiele

(Eine Übersicht der neuen Formularelemente finden Sie in der Beispieldatei html5forms.html)

<input type="color">
Feld für Farbauswahl.

Hier die Darstellung in Opera 11, andere Browser stellen unter Umständen ein anders strukturiertes Eingabefeld dar, in das hexadezimale RGB-Farbangaben (0-9,A-F) eingegeben werden können.
<input type="date">
Feld für Datumsangabe.
<input type="datetime-local">
Feld für Datum und Uhrzeit (ohne Zeitzone).
<input type="datetime">
Feld für Datum und Uhrzeit (mit Zeitzone).

(Darstellung in Opera 11).
<input type="month">
Feld für die Angabe von Monat und Jahr.
<input type="number">
Feld für eine Zahl, ggf. mit Pfeiltasten zur Veränderung der Werte (sog. numeric stepper).
.
<input type="range">
Feld für eine Zahl, die in einem bestimmten Wertebereich liegen muss.

(Wird üblicherweise als Schieberegler gerendert – hier die Darstellung in Safari 5)
Dieser Input-Typ akzeptiert weitere Attribute zur Festlegung des gewünschten Bereichs, aus dem der Nutzer etwas auswählen soll ("max" für den Maximalwert, "min" für den Minimalwert, "step" für die Anzahl der Schritte und "value" für den eingestellten Wert):
<form action="foo" method="post">
  <input type="range" id="range" min="0" max="10" step="1" value="">
</form>
Ohne weitere Angaben wird sich hier dem Benutzer jedoch nicht erschließen, was von ihm erwartet wird. Die aktuellen Browser sind hier auch keine große Hilfe, weil sie mögliche Werte und aktuelle Zustände nicht von sich aus ausgeben. Hier hilft ein wenig CSS, mit dem man die min- und max-Werte auslesen und jeweils vor bzw. hinter den Schieberegler schreibt:
input[type=range]:before { content: attr(min);}
input[type=range]:after { content: attr(max); }
Zum auslesen des aktuell eingestellten Wertes wiederum braucht man auch mit HTML5 noch etwas JavaScript. Zur Darstellung des ausgelesenen Wertes eignet sich hervorragend das neue Output-Element:
<output id="ergebnis"> </output>
.
<input type="search">
Feld für Suchbegriffe.

(Darstellung in Safari 5).
<input type="tel">
Feld für Telefonnummern.
Hier sieht man einen weiteren, nicht zu unterschätzenden Vorteil spezialisierter Elemente für bestimmte Datentypen: Browser können je nach Typ verschiedene Eingabearten präsentieren. So zeigt der mobile Safari auf dem iPhone bei einem Input vom Typ "tel" statt der Tastatur den wesentlich passenderen Ziffernblock zur Eingabe einer Telefonnummer an:

(Darstellung in Mobile Safari unter iOS).
<input type="time">
Feld für Uhrzeit.

(Darstellung in Opera 11).
<input type="url">
Feld für URLs.
Auch hier zeigt sich wieder die ganze Eleganz der neuen Elemente und Ihr Nutzen im Sinne der Anwender: Browser, die diese Elemente verstehen, können dann ein geändertes Interface zur Bedienung präsentieren und damit den Nutzer unterstützen. So zeigen die mobilen Versionen von Safari (iPad, iPhone, iPodTouch) ein leicht geändertes Keyboard beim Ausfüllen von input type="url", bei dem zum Beispiel die Leerschritt-Taste entfällt (da Leerschritte in URLs nicht zulässig sind); stattdessen werden für URLs benötigte Tasten wie "/" oder ".com" angezeigt:
.
<input type="week">
Feld für Angabe von Kalenderwoche und Jahr.
<input type="email">
Feld für E-Mail-Adressen.
<form action="foo.bar" method="get">
 <label for="email">E-Mail:</label>
 <input type="email" id="email">
 <button type="submit">Abschicken</button>
</form>
Wenn Sie ein Feld derart auszeichnen, weisen Sie damit den Browser an, nur bestimmte Eingaben zu akzeptieren, die in ihrer Syntax einer gültigen E-Mail-Adresse entsprechen, z.B. mindestens ein beliebiges Zeichen vor einem @, mindestens zwei Zeichen (inkl. Zahlen und Umlauten) nach dem @, gefolgt von einem Punkt, wiederum gefolgt von mindestens zwei beliebigen Buchstaben). Browser, die diesen und andere Input-Typen nicht verstehen, stellen eine herkömmliche Textbox dar – allerdings auch ohne die eingebaute Validierung, so dass Sie weiterhin eine client- und / oder serverseitige Überprüfung benötigen. Wie für alle neuen Input-Typen gilt also: Sie können sie ohne Nachteile verwenden, aber sie können sich nicht zu 100% darauf verlassen.
<input … autocomplete="on | off">
Beeinflusst die automatische Vervollständigung eines input-Feldes.
Manchmal kann es sinnvoll sein, das automatische Ausfüllen bzw. Komplettieren von Nutzereingaben zu verhindern, z.B. wenn Angaben nicht aus dem Adressbuch des Nutzers übernommen werden sollen, oder um das automatische Ausfüllen von Benutzernamen und Passwörtern, Kreditkartennummern etc. zu verhindern (autocomplete="off"). Beachten Sie dass Eingaben in solche Felder von HTML5-konformen Browsern gelöscht werden, wenn der Benutzer den »Back«-Button bedient: »… if the resulting autocompletion state is off, values are reset when traversing the history«.
<input pattern="…">
Attribut für Eingaben, auf die ein regulärer Ausdruck passen muss.
Durch das pattern-Attribut lassen sich solche regulären Ausdrücke direkt ins Markup des betreffenden Elementes schreiben:
<form action="" method="post"> 
 <label for="username">Create a Username: </label> 
 <input type="text" 
 id="username"
 placeholder="8 <> 20"
 pattern="[A-Za-z]{4,10}"
 required
 autofocus> 
 <button type="submit">OK</button> 
</form>
[a-zA-Z] bedeutet, dass das Feld nur Klein- und Großbuchstaben akzeptiert, {8,20} bedeutet, dass es mindestens 8 und höchstens 20 Buchstaben sein dürfen. Empfehlenswert ist dies zum Beispiel auch bei Telefonnummern – die Angabe von pattern="\+[0-9\-]" ermöglicht die Eingabe von Telefonnummern nach der Art +492282092-0.
<input placeholder="…">
Attribut für Felder mit Platzhalter-Texten, die Hinweise auf die einzugebenden Daten geben sollen.
Vor HTML5 musste man JavaScript einsetzen, um in einem Textfeld eine Vorbelegung mit mehr oder minder sinnvollem Hinweistext zu erreichen, dann prüfen ob der Nutzer das Feld fokussiert hat und den Platzhaltertext entfernen, dann erneut testen ob der Benutzer etwas eingegeben hat wenn er das Feld wieder verlässt, und gegebenenfalls den Platzhaltertext wieder einfügen (ohne aber bereits gemachte Eingaben wieder zu überschreiben).
Diesen ganzen Aufwand können Sie sich sparen, wenn Sie das placeholder-Attribut aus HTML5 einsetzen – dann macht der Browser diese Arbeit nämlich von ganz alleine:
<input type="email" id="email" placeholder="name@domain.de">

Die Unterstützung hierfür ist nach unseren Tests allerdings noch lückenhaft. Erst die neuesten Versionen von Firefox 4, Opera 11 und Safari 5 unterstützen dieses Attribut – wenn Sie einen hohen Prozentsatz von Nutzern mit älteren Browsern haben und essentielle Hinweise in diesem Platzhalter stehen haben sollten, dann brauchen Sie auch hier einen Fallback.
Zum Glück gibt es eine ganze Reihe Skripte wie zum Beispiel Modernizr, um die Unterstützung von placeholder und anderen Attributen zu testen und entsprechend zu reagieren.
Was Sie nicht machen sollten ist, das placeholder-Attribut als LABEL-Ersatz zu missbrauchen – diese werden nach wie vor benötigt, weswegen dies in der HTML5-Spezifikation auch ausdrücklich verboten ist. Längere Hinweistexte sind nach wie vor besser in einem title-Attribut oder noch besser im sichtbaren Anleitungstext des Formulars aufgehoben. Tests zur barrierefreien Umsetzung dieses Attributs finden Sie unter html5accessibility.com: »HTML5 placeholder attribute tests«.
<input … required>
Attribut zur Kennzeichnung von Pflichtfeldern.
Wie der Name impliziert können Sie hiermit Pflichtfelder auszeichnen. Dies geht entweder, indem Sie das Attribut ohne Wert einfügen:
<input type="text" id="foo" required>,
oder wenn Sie die Schreibweise von XHTML bevorzugen auch als Attribut-Wert-Paar:
<input type="text" id="foo" required="required" />
Funktional sind diese beiden Schreibweisen identisch: mit diesem Attribut kann ein Formular nicht abgesendet werden, wenn das Input-Feld leer ist. Falls der Nutzer hier nichts eingetippt hat wird das Textfeld vom Browser entsprechend markiert.

(Darstellung in Firefox 4)
Das befreit Sie allerdings nicht von der Notwendigkeit, Nutzer auch schon vor dem Ausfüllen und Absenden auf das Vorhandensein von Pflichtfeldern hinzuweisen. Für halbwegs moderne Browser könnten Sie dies theoretisch per CSS erledigen:
input[required]:after {
  content:" * ";
}
Vom Standpunkt der Barrierefreiheit ist diese Variante aber eher ungeeignet, weil z.B. im Screenreader diese essentielle Information fehlt, wenn sie ausschließlich via CSS (und damit über die visuelle Präsentationsschicht) vermittelt wird. Zudem werden solche Attribut-Selektoren erst von der neuesten Browser-Generation unterstützt. Auch hier sollte man weiterhin auf die klassische Kennzeichnung mit Symbolen vertrauen, ggf. ergänzt durch ARIA-Attribute wie aria-required.
<input … autofocus>
Attribut zur automatischen Fokussierung des Kontrollelements.
Auch hier wird durch Neuerungen in HTML5 die Notwendigkeit zum Einsatz von JavaScript reduziert; aber auch hier kann es bei unbedachtem Einsatz zu Problemen in der Zugänglichkeit der Anwendung führen. Das Problem entsteht hier nicht durch HTML5, sondern generell durch das Konzept, ein Formularfeld automatisch zu fokussieren (vergleichbares ließ sich bisher ja auch durch JavaScript erreichen):
<input type="text" id="foo" autofocus>
Wie Bruce Lawson in seinem Artikel »The accessibility of HTML 5 autofocus« zu Recht bemerkt gibt es nur sehr wenige legitime Einsatzzwecke für diese Technik. Nur wenn sie mit absoluter Sicherheit davon ausgehen können, dass der Zweck des Besuchs der Seite ausschließlich das Erreichen des entsprechenden Formularelementes ist, sollten Sie dieses auch automatisch fokussieren.
Dieses Szenario mag auf Seiten wie die Google-Suchseite zutreffen – diese erfüllt nur den einen Zweck, nämlich dass Nutzer einen Suchbegriff in das Suchfeld eintippen. Hier lässt sich ein autofocus also durchaus rechtfertigen: Sie können davon ausgehen, dass der Nutzer genau deswegen auf die Seite gekommen ist und Sie helfen ihm damit, seine Aufgabe schneller zu erledigen.
Eher hinderlich ist dieses Verhalten auf Seiten deren primärer Zweck eben nicht die Bedienung eines Formulars ist, sondern zum Beispiel das Lesen eines Artikels – ein Fehler den viele Templates des verbreiteten Blog-Systems Wordpress machen. Nutzer von Screenreadern finden sich dort mitten in einem Formular wieder, das Programm schaltet in den Formularmodus und dem Nutzer fehlen jegliche Informationen zum Kontext des Formulars oder zum eigentlichen Inhalt der Seite.

Formulare ohne Form

Eine der spannendsten Neuerungen in HTML5 ist, dass Formularelemente nun auch ausserhalb des <form>…</form>-Tags stehen dürfen. Input muss nun also nicht mehr zwingend ein Kind-Element von FORM sein. Damit entfällt der Zwang, den ganzen BODY einer Seite in ein <form>…</form>-Tag zu packen, wenn Formular-Elemente an verschiedenen, weit auseinander liegenden Stellen der Seite vorkommen (z.B. eine einfache und eine erweiterte Suche, die beide auf die gleiche form action="…" auf dem Server zurückgreifen). Alles was Sie benötigen ist ein eindeutige ID am Start-Tag von <form>:

<form id="suche" action="suche.pl" method="post">
 <fieldset>
 <legend>Erweiterte Suchoptionen</legend>
 <input type="search">
 …
 </fieldset>
</form>

Ein weiterer Suchschlitz kann nun irgendwo auf der Seite ausserhalb von <form>…</form> platziert werden; die Verbindung zum Suchskript wird über den Verweis auf die ID des <form>-Tags hergestellt. Dieses verhält sich durch das zusätzliche form-Attribut nun als wäre es Teil des Formulars, auf das der Wert des Attributs verweist:

<input type="search" name="suchfeld" form="suche">

In der Zwischenzeit: WAI-ARIA

Die grossen Betriebssysteme mit ihren grafischen Benutzeroberflächen verfügen alle über sogenannte Accessibility-APIs (Application Programming Interfaces). Über diese Schnittstellen werden Hilfsmittel wie Braillezeilen, Lupenprogramme und Screenreader, aber auch alternative Eingabegeräte mit den nötigen Informationen darüber versorgt, was gerade auf dem Bildschirm geschieht und wie Funktionen zu bedienen sind.

Für Windows ist dies die mittlerweile recht betagte »Microsoft Active Accessibility«-Schnittstelle (MSAA) bzw. für aktuelle Windows-Versionen UI Automation; unter Linux gibt es das »Gnome Accessibility Toolkit« (ATK); bei Apple ist es das »Accessibility-API for Cocoa«; auch Sun bzw. Oracle hat mit dem »Java Accessibility-API« eine entsprechende Schnittstelle. Um über diese Schnittstellen kommunizieren zu können und dem Nutzer den Zugriff zu gewährleisten brauchen Elemente einer Webseite bzw. eines Web-Formulars klar festgelegte Rollen und Zustände (Roles = Was ist dieses Element und was kann ich damit machen? States = In welchem Zustand befindet sich das Element?)

Im Falle statischer HTML-Dokumente mit den üblichen Strukturelementen wie Überschriften, Absätze und Listen, Links und einfachen Formularelementen sind die Rollenverteilungen und Zustände klar verteilt und sollten somit kein Problem für die Hilfsmittel darstellen. Der Browser teilt die Informationen über die jeweiligen Elemente und ihre Zustände (fokussiert, gedrückt, angekreuzt, besucht) über das Accessibility-API mit.

Wenn nun jedoch per HTML, CSS & JavaScript Bedienelemente nachgebildet werden, die über den begrenzten Satz von HTML4 bzw. XHTML1 hinausgehen (gemeinhin also sinnfreie DIVs oder Bilder sind), eröffnet sich das Problem, dass diese »Nachbauten« von der Accessibility-Schnittstelle nicht verstanden werden und somit auch nicht an ein Hilfsmittel weitergereicht werden können. Screenreader können also gar nicht umhin, solche eigentlich interaktiven Elemente wie statischen Text zu behandeln.

Falls Ihre Anwendung diese Elemente bzw. deren Funktionalität benötigt, so können Sie für moderne Browser die neuen Elemente aus HTML5 auch heute schon verwenden. Allerdings sollten Sie sich dann im Klaren sein, dass nicht ganz so moderne Browser und ältere Hilfsmittel zusätzliche Unterstützung in Form von Fallback-Lösungen und/oder JavaScript benötigen, um die gewünschten Funktionen zur Verfügung zu stellen.

ARIA – Was ist das?

Dieser Spagat wird nun durch den Einsatz der noch in der Entwicklung befindlichen Spezifikation WAI-ARIA erleichtert, die als eine Art Brücken-Technik die Kluft zwischen der begrenzten Welt von HTML4 und den erweiterten Möglichkeiten von HTML5 zu überbrücken sucht. WAI-ARIA ist genau dafür gedacht: Hilfsmittel wie Screenreader und Lupenprogramme mit Informationen über Rollenverteilungen und Zustände von Objekten zu versorgen, an die diese aus eigener Kraft nicht kommen könnten.

Dazu werden HTML-Elemente mit zusätzlichen semantischen Informationen über ihre Funktion, über mögliche Werte und Zustände (an/aus, auf/zu, Prozentwerte bei Schiebereglern etc.) und über ihr Verhalten ausgestattet. Dies geschieht über Attribute, die zum Start-Tag des jeweiligen Elementes hinzugefügt werden.

Ein einfaches Beispiel hierfür sind die ARIA-Landmark-Roles: hiermit können die heutzutage üblichen, aus einer (Un-)Menge DIVs aufgebauten Layouts mit weiteren Informationen über ihren Zweck und ihre Inhalte ergänzt werden. Die ARIA-Rolle role="navigation" sagt dem Hilfsmittel, dass sich innerhalb des derart ausgezeichneten Bereichs die Navigation der Seite befindet, role="main" kennzeichnet den wesentlichen Inhalt einer Seite, role="complementary" kennzeichnet ergänzende Informationen zu diesem Inhalt und role="search" ist ein Such-Widget – gemeinhin Dinge, für die es (noch) keine passenden HTML-Elemente gibt.

Für ein Beispiel der praktischen Anwendung von Landmark-Roles genügt ein Blick in den Quelltext dieser Seiten – wir setzen diese hier bei »Einfach für Alle« schon seit geraumer Zeit ein.
Screenshot der Juicy Studio Accessibility Toolbar mit der Funktion »Highlight document landmark regions«

Weitere ARIA-Attribute kümmern sich um Zustände und Eigenschaften: aria-required="true" sagt z.B. bei einem Eingabefeld, dass dies ein Pflichtfeld ist, aria-invalid="true" weist auf eine Fehleingabe hin:

<input type="text" aria-required="true" aria-invalid="true">

ARIA-Rollen können auch verschachtelt sein, teilweise haben Sie auch zwingend vorgeschriebene Eltern- oder Kind-Rollen. Eine detaillierte Auflistung würde den Rahmen dieses Artikels sprengen, für eine aktuelle Übersicht sollten Sie die »WAI-ARIA 1.0 Authoring Practices« sowie die »ARIA-Techniken für WCAG 2.0« zu Rate ziehen.

Das Hinzufügen von ARIA-Attributen im Quelltext einer Seite ändert zunächst einmal nichts an deren Oberfläche. Wenn man einem sinnfreien DIV via ARIA die Rolle "checkbox" zuweist, so erkennt ein Screenreader zwar die Intention, das Verhalten einer Checkbox fehlt aber nach wie vor und muss per JavaScript nachgebildet werden. Auch in der grafischen Darstellung wird dieses Element weiterhin als leeres Element und nicht, wie man vielleicht meinen könnte, als Checkbox dargestellt. An diesem Beispiel sehen Sie schon, dass es oftmals besser wäre, die eventuell bereits vorhandenen passenden HTML-Elemente zu verwenden und nicht das Rad neu zu erfinden.

Das Elegante an dieser Lösung ist, dass erweiterte Bedienelemente in Widgets wie zum Beispiel Schieberegler den Nutzern genau so präsentiert werden, wie Schieberegler in Desktop-Anwendungen schon seit Jahren: es wird angesagt, dass es sich um einen Schieberegler handelt, der aktuell eingestellte Wert wird vorgelesen und die möglichen Werte, die der Nutzer (z.B. per Pfeiltaste) einstellen kann – der Lernaufwand zur Bedienung solcher Widgets in Webseiten geht für den Nutzer also gegen Null, dafür steigt die Zugänglichkeit um ein Vielfaches.

Die einzige negative Auswirkung auf Ihre Seiten ist, dass diese durch den Einsatz von WAI-ARIA nicht mehr validieren werden. Das ist aber in diesem Fall eher ein Problem des Validators, nicht Ihrer Nutzer oder der Browser, die diese verwenden.

Weitere Hintergründe dazu, was das W3C zur Entwicklung dieses Standards veranlasst hat und wie die weitere Planung verläuft finden Sie in der »Roadmap for Accessible Rich Internet Applications (WAI-ARIA Roadmap)«.

ARIA – Wer unterstützt das?

WAI-ARIA wird bereits seit einigen Versionsnummern von Screenreadern wie NVDA, VoiceOver, Window Eyes und JAWS sowie von Browsern wie Safari ab der Version 4, Internet Explorer ab Version 7 und Firefox ab v.1.5 unterstützt; weitere Hilfsmittel und Browser werden in Zukunft sicher folgen. Allerdings gibt es teils erhebliche Unterschiede in der Umsetzung, und selbst auf einer einzigen Plattform mit ein und demselben Screenreader kann es zu Unterschieden in der Nutzbarkeit kommen, je nachdem welchen Browser (z.B. Firefox oder IE) man benutzt. Hier kommen Sie also um einen praktischen Test mit echten Anwendern kaum herum.

Aktuelle Informationen über den Stand der Unterstützung in den diversen Hilfsmitteln finden Sie (mit viel Glück) auf den Seiten der jeweiligen Hersteller, z.B. »JAWS Support for ARIA« (Word-Datei). Sehenswert ist auch das Youtube-Video von Cannon Access, das zeigt, wie Screenreader-Nutzer mit ARIA-angereicherten Seiten interagieren: »ARIA Live Regions Screen Reader Demo«.

ARIA – Wie geht das?

Die einfachste Methode, um ARIA-Attribute in vorhandene HTML-Seiten hinein zu bekommen, ist per Skript. Wenn Sie bereits JavaScript-Bibliotheken wie z.B. jQuery einsetzen, dann ist dies mit einigen Zeilen Code erledigt – alles was Sie machen müssen ist, eindeutig identifizierbare IDs oder Klassen, die ausschließlich für bestimmte Inhalte verwendet werden, mit den entsprechenden Rollen-Attributen zu versehen:

/* Skript zum Anhaengen von WAI-ARIA-Rollen-Attributen mit jQuery: */
$(document).ready(function() {
  $("#kopf").attr("role","banner");
  $("#nav").attr("role","navigation");
  $("#skiplinks").attr("role","navigation");
  $("#inhalt").attr("role","main");
  $("#marginalie").attr("role","complementary");
  $("#legende").attr("role","note");
  $(".fehlerbox").attr("role","alert");
});

Das Elegante an diesem Ansatz ist, dass der Validator nichts von den neuen, formal ungültigen Attributen mitbekommt und Ihre Seiten weiterhin validieren. Allerdings stellt sich bei uns ein gewisses Unbehagen ein, wenn man strukturelle Informationen wie ARIA-Landmarks an die Verhaltens-Schicht (und damit an das Vorhandensein von JavaScript) bindet – eigentlich gehören diese ins HTML.

Weiterhin problematisch an diesem Ansatz ist, dass diese Zuweisungen nicht zwangsläufig immer an den vorgesehenen Stellen greifen, weil nicht überall alleine anhand der ID entschieden werden kann, welche Rolle passt, oder ob das Element tatsächlich mit Inhalt befüllt ist. Im Zweifelsfall sollten Sie sich gegen die Verwendung solcher Skripte entscheiden und die benötigten ARIA-Attribute direkt ins HTML einfügen.

Eine Ausnahme von dieser Regel: wenn Widgets für ihre Funktionalität zwingend JavaScript voraussetzen, dann spricht selbstverständlich nichts dagegen, die ergänzenden ARIA-Informationen innerhalb dieser Widgets per JavaScript zu setzen. ARIA wurde ja gerade für den Einsatz in dynamischen Applikationen ersonnen (wir erinnern uns: ARIA steht für »Accessible Rich Internet Applications«) und Werte müssen teilweise per JavaScript geändert werden (z.B. wenn ein Element auf- oder zugeklappt wird), um weiterhin sinnvoll zu sein.

<fieldset aria-expanded="true" class="klappe-auf">
  <legend>Dieses Fieldset wird angezeigt</legend>
  …
</fieldset>

<fieldset aria-expanded="false" class="klappe-zu">
  <legend>Dieses Fieldset wird nicht angezeigt</legend>
  …
</fieldset>

Hier nun eine Auswahl von verschiedenen ARIA-Attributen, die Sie auch heute schon ohne Nebenwirkungen in Ihren Seiten einsetzen können. Sie sollten auf jeden Fall vor dem unkritischen Einsatz abwägen, ob es nicht vielleicht doch bereits passendere HTML-Elemente und -Attribute gibt, die den Einsatz von ARIA überflüssig machen, weil sie vergleichbare semantische Information bereits in sich tragen:

Landmark-Roles

role="application"
Für Inhalte vom Typ Anwendung: »A region declared as a web application, as opposed to a web document.« . Diese Rolle sollte nur mit äusserster Vorsicht eingesetzt werden. Zum einen müssen dann sämtliche Inhalte (also auch statische Texte) mit Bedien-Elementen einer Anwendung verknüpft sein (z.B. über aria-labelledby oder aria-describedby), ansonsten werden sie von Screenreadern ignoriert. Zum anderen ändern Screenreader wie JAWS ihr Verhalten, wenn man dieses Attribut für das BODY-Element setzt: der Screenreader verhält sich dann wie bei einer Desktop-Anwendung und nicht wie bei Web-Inhalten.
role="banner"
Für den Kopfbereich einer Seite, der z.B. das Logo oder andere Objekte enthält, die sich auf die gesamte Site beziehen. Dieses Attribut sollte nur 1× je role="document" oder role="application" vergeben werden (diese können allerdings mehrfach pro Dokument vorkommen).
role="complementary"
Für ergänzende Zusatzinfos zum wesentlichen Inhalt der Seite.
role="contentinfo"
Für eine Kopf- bzw. Fußzeile, Sidebar o.ä. mit Metadaten, Impressum, Disclaimer, Hinweisen zum Datenschutz etc.
role="document"
Für Inhalte vom Typ Dokument: »A region containing related information that is declared as document content, as opposed to a web application.« In der Regel unnötig, weil der default-Zustand.
role="form"
Für Formulare: kann mehr enthalten als nur ein reines FORM-Element, sondern auch Hyperlinks oder Texte etc., die zum Formular gehören, aber ausserhalb von FORM stehen und hierüber zugeordnet werden.
role="main"
Für den wesentlichen Inhalt der Seite.
role="navigation"
Für jegliche eindeutig abgrenzbare Bereiche mit mehreren Navigations-Elementen.
role="search"
Für ein Such-Widget: Die Rolle sollte dem FORM-Tag zugewiesen werden, nicht den enthaltenen INPUT-Feldern.

Document-Structure-Roles

role="alert"
Für Warnhinweise: »A message with important, and usually time-sensitive, information.«
role="article"
Für Artikel im Sinne eines eigenständigen Teils der Seite oder der Anwendung, der für sich genommen eine abgeschlossene Sinneinheit bildet. Vorsicht: "article" ist nicht im Sinne eines redaktionellen Artikels zu verstehen (das wäre "story", diese Rolle gibt es jedoch nicht), sondern eher vergleichbar mit einem Artikel in einem Regal.
role="columnheader"
Für Spaltenköpfe bei Inhalten, die tabellarische Eigenschaften haben.
role="definition"
Für Definitionen: »A definition of a term or concept.« Unnötig, wenn DFN oder DL verwendet wird.
role="directory"
Für ein Verzeichnis im Sinne eines Inhalts- oder Dateiverzeichnisses: »A list of references to members of a group, such as a static table of contents.«
role="group"
Für generische Gruppen: »A set of user interface objects which are not intended to be included in a page summary or table of contents by assistive technologies. Contrast with region which is a grouping of user interface objects that will be included in a page summary or table of contents.«
role="img"
Für Abbildungen: »An img can contain captions and descriptive text, as well as multiple image files that when viewed together give the impression of a single image.«
role="list"
Für Elemente, deren enthaltene Elemente den Charakter einer Auflistung haben: »A group of non-interactive list items. Also see listbox. Lists contain children whose role is listitem, or elements whose role is group which in turn contains children whose role is listitem.«
role="listitem"
Für Listenelement einer solchen Liste: »A single item in a list or directory. Authors MUST ensure elements with role listitem are contained in, or owned by, an element with the role list.«
role="math"
Für mathematische Formeln: »Content that represents a mathematical expression.«
role="note"
Für Einschübe und Ergänzungen: »A section whose content is parenthetic or ancillary to the main content of the resource.«
role="presentation"
Für rein dekorative Elemente, die z.B. in der Sprachausgabe keine semantische Bedeutung haben sollen: »An element whose implicit native role semantics will not be mapped to the accessibility API. The intended use is when an element is used to change the look of the page but does not have all the functional, interactive, or structural relevance implied by the element type, or may be used to provide for an accessible fallback in older browsers that do not support WAI-ARIA Dies heisst jedoch nicht, dass die Inhalte eines Elements mit der Rolle "presentation" im Screenreader nicht vorgelesen werden – im Gegenteil. Lediglich das derart ausgezeichnete Element (z.B. eine Überschrift) taucht nicht im Dokumentenbaum auf, enthaltene Texte jedoch weiterhin.
role="radiogroup"
Für eine Gruppe von Radiobuttons: wird benötigt um z.B. am umschließenden Element aria-required="true" setzen zu können und muss role="radio" enthalten.
role="region"
Für eine Region einer Seite als Fallback, falls andere Landmark Roles nicht passen. »A large perceivable section of a web page or document, that the author feels is important enough to be included in a page summary or table of contents, […] Authors SHOULD ensure that a region has a heading referenced by aria-labelledby. […] When defining regions of a web page, authors are advised to consider using standard document landmark roles. If the definitions of these regions are inadequate, authors can use the region role and provide the appropriate accessible name.«
role="row"
Für Tabellenzeilen bei Inhalten, die tabellarische Eigenschaften haben.: »A row of cells in a grid.«
role="rowheader"
Für Zeilenköpfe bei Inhalten, die tabellarische Eigenschaften haben.: »A cell containing header information for a row in a grid.«
role="separator"
Für Trennelemente, z.B. verschiebbare Stege zwischen Bereichen eines Widgets oder einer Anwendung: »This is a visual separator between sections of content. For example, separators are found between groups of menu items in a menu or as the moveable separator between two regions in a split pane.«
role="toolbar"
Für Werkzeugleisten (z.B. die Button-Leiste eines Texteditors): »A collection of commonly used function buttons represented in compact visual form.«
role="tree"
Für Baum-Strukturen: »A type of list that may contain sub-level nested groups that can be collapsed and expanded.«
role="treeitem"
Für Baumelemente: »An option item of a tree. This is an element within a tree that may be expanded or collapsed if it contains a sub-level group of treeitems.«

Zustände & Eigenschaften (States & Properties)

aria-autocomplete="list"
Element hat eine ihm zugeordnete Liste von Vorschlägen, mit denen der eingegebene Text komplettiert werden kann. »A list of choices appears from which the user can choose, but the edit box retains focus.«
aria-describedby="#ID"
Verknüpft ein Element mit anderen (vorzugsweise textlichen) Elementen, die das Objekt beschreiben. Beispiel: <img src="icon.gif" width="40" height="40" aria-describedby="#bildlegende" />
aria-expanded="false" / aria-expanded="true"
Universal-Attribut zur Kennzeichnung auf- bzw. zugeklappter Elemente: »Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.«
aria-haspopup="true"
Zur Kennzeichnung, dass dem Element ein Pop-Up zugeordnet ist: »Indicates that the element has a popup context menu or sub-level menu.«
aria-labelledby="ID_der_Beschreibung"
Für die Zuordnung einer Beschriftung zu einem Element: »Identifies the element (or elements) that labels the current element«) Beispiel: <div id="datepicker" role="grid" aria-labelledby="abflugdatum">
aria-live="assertive" / aria-live="polite"
Ergänzende Rolle zu role="alert" (eine Live-Region, die Aktualisierungen innerhalb einer Seite anzeigt: »Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region.«
aria-owns="ID"
Zur Zuordnung von weiteren Elementen auf einer Seite, die ansonsten nicht über das DOM hergestellt werden kann: »Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship between DOM elements where the DOM hierarchy cannot be used to represent the relationship.«
aria-required="true"
Kennzeichnet Pflichtfelder: »Indicates that user input is required on the element before a form may be submitted.« Beispiel: <textarea id="foo" name="bar" class="baz" cols="15" rows="5" aria-required="true">

CSS zum Debugging

Zum Abschluss noch ein kleiner CSS-Kniff, um die Struktur einer mit WAI-ARIA angereicherten Seite zu visualisieren und eventuelle Fehler zu finden. Zunächst wird allen Elementen (*) mit dem Attribut role ([role]) eine kleine Box nach Art eines Tooltips vorangestellt (:before). In dieses Tooltip wird der Inhalt des Rollen-Attributs per Generated Content geschrieben (content: "[role=" attr(role) "];), der Rest sind optische Formatierungen:

/* Rollen anzeigen ------------------------------------------------- */

*[role]:before {
  content: "[role=" attr(role) "]";
  color: #333;
  background: #fdffdc;
  outline: 1px solid #999;
  padding: .2em;
  -webkit-box-shadow: 2px 2px 2px #ccc;
  -moz-box-shadow: 2px 2px 2px #ccc;
  box-shadow: 2px 2px 2px #ccc;
}

Dann werden verschiedene Rollen mit einer farbigen Outline versehen, die den gesamten Bereich umfasst:

/* unterschiedliche Rahmenfarben je nach Rollen-Typ ---------------- */

*[role] {
  outline: 1px solid gray;
}

*[role=banner] {
  outline: 1px solid red;
}

*[role=navigation] {
  outline: 1px solid green;
}

*[role=main] {
  outline: 1px solid blue;
}

Als letztes werden die unterschiedlichen Eigenschaften per Outline hervorgehoben. Leider gibt es in CSS keinen Wildcard-Character (also etwas wie *[aria-*]), um sämtliche Attribute abzufangen, die mit aria- beginnen, daher müssen diese leider einzeln aufgelistet werden:

/* States & Properties anzeigen ------------------------------------ */

/* geht leider nicht:
*[aria-*] {
outline: 1px dashed red
} */

*[aria-autocomplete],
*[aria-describedby],
*[aria-expanded],
*[aria-haspopup],
*[aria-labelledby],
*[aria-live],
*[aria-owns],
*[aria-readonly],
*[aria-required] {
  outline: 1px dashed red
}

Sollte man HTML5 & ARIA zusammen verwenden?

Es gibt eine ganze Reihe guter Beispiele, in denen die erweiterte Semantik von HTML5 und die hilfsmittel-spezifischen Eigenschaften von WAI-ARIA erfolgreich kombiniert werden, inklusive Testcases zur Überprüfung der Machbarkeit und den passenden Workarounds. Allerdings stellt sich für uns schon die Frage nach der Sinnhaftigkeit dieser Kombination: HTML5 wird entwickelt, um die Lücken endgültig zu schließen, welche die für den heutigen Stand der Technik unzureichende HTML4-Spezifikation hinterlassen hat; WAI-ARIA hingegen ist als Übergangslösung gedacht, um Hilfsmitteln den Zugriff auf interaktive Elemente zu ermöglichen, die ohne zusätzliche Informationen unzugänglich blieben. Wenn nun HTML5 zusammen mit ARIA eingesetzt wird, dann kann dies im Umkehrschluss eigentlich nur bedeuten, dass es auch in HTML5 noch Lücken gibt, wo z.B. Screenreader nicht mit den für sie nötigen Informationen versorgt werden – ein Zustand, der eigentlich durch HTML5 behoben sein sollte.

Eine durchaus nachvollziehbare Begründung für den kombinierten Einsatz ist die Unterstützung älterer Browser und/oder älterer Hilfsmittel, die eventuell noch nicht den vollen Satz der Möglichkeiten verstehen und korrekt umsetzen. Derek Featherstone beschreibt dies im Artikel »ARIA and Progressive Enhancement« bei A List Apart anhand des NAV-Elements aus HTML5 in Kombination mit der Rolle "navigation" aus WAI-ARIA:

<nav role="navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/archives/">Archives</a></li>
    <li><a href="/about/">About</a></li>
    <li><a href="/contact/">Contact</a></li>
  </ul>
</nav>

Was zunächst aussieht wie ein unnötiger Doppler ergibt bei näherer Betrachtung durchaus Sinn: weder HTML5 noch WAI-ARIA werden, global betrachtet, von sämtlichen Browsern und allen Hilfsmitteln vollständig und korrekt unterstützt. Browser/Screenreader-Kombinationen, in denen NAV bereits verstanden wird, können diese Informationen zur Verfügung stellen; andere Kombinationen, in denen zumindest ARIA unterstützt wird, erhalten diese Informationen über die ARIA-Rolle. Wenn keines von beiden verstanden wird (NAV also wie ein generisches DIV ohne weitere Attribute behandelt wird), dann bekommt der Nutzer trotzdem die gleichen Informationen wie bei klassischen HTML4/XHTML1-Seiten über die Auszeichnung der Navigationspunkte als Liste.

Problematisch wird dieser Ansatz nur, wenn durch solche Doppler Informationen tatsächlich mehrfach vorgelesen werden. Leider kann man weder server- noch client-seitig abfragen, ob und wenn ja welcher Screenreader an der Accessibility-Schnittstelle hängt, geschweige denn welchen Grad der Unterstützung dieser für diverse technische Möglichkeiten hat. Also scheitern an dieser Stelle auch alle Ansätze des »Progressive Enhancement«, da man nicht testen kann, ob ein User Agent ein Objekt in der gewünschten Form versteht, um dann im Code darauf zu reagieren – Tests hierzu und mögliche Workarounds finden Sie im oben genannten »A List Apart«-Artikel.

Hinzu kommt, dass Screenreader vergangener und auch aktueller Baureihen teilweise erhebliche Bugs in der Umsetzung von HTML5 & WAI-ARIA haben. Ob das nun am Screenreader, an der Accessibility-Schnittstelle des Betriebssystems oder am verwendeten Browser liegt, ist aus Sicht eines Webentwicklers eigentlich egal: ändern kann man alle drei nicht.

Nun könnte man zum Umschiffen von Bugs in Screenreadern zusätzliche Elemente einfügen, wenn z.B. Screenreader wie Window Eyes mit dem obigen Code nicht zurechtkommen. Der folgende Code hilft auch diesem auf die Sprünge:

<div role="navigation">
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      […]

Allerdings haben wir hier nun das Problem, dass der Navigationsbereich in anderen Hilfsmittel-/Browser-Kombinationen zweifach vorgelesen wird (im konkreten Fall passiert dies in der Tat bei NVDA 2010.2 & Firefox 4); User Agents, die sich ihrerseits an die Standards halten, werden dadurch also effektiv abgestraft – das kann auch nicht das Ziel sein.

Hier kann man also nur auf die Nutzer fehlerhafter Hilfsmittel hoffen, dass diese Upgrades möglichst zeitnah vollziehen, um die erweiterten Möglichkeiten nutzen zu können. Trotzdem: nicht jeder Screenreader-Nutzer hat die Möglichkeit, auf moderne Programme wie NVDA und Firefox umzusteigen, die moderne Webstandards hervorragend unterstützen. Gerade im beruflichen Umfeld ist die Kombination aus JAWS 6 und Internet Explorer 6 noch gelegentlich anzutreffen, allerdings kann man nicht erwarten, damit moderne Webapplikationen auch nur im Ansatz nutzen zu können. Anbieter können nur das größtmögliche an Zugänglichkeit einbauen; wenn dies dann nicht unterstützt wird und auch Fallback-Lösungen scheitern (oder prinzipienbedingt nicht möglich sind), dann gibt es nicht mehr viel, was man als Anbieter machen kann – der Ball liegt also hier bei den Anwendern. Bruce Lawson, Accessibility Evangelist bei Opera, formuliert dies wie folgt:

»… if you correctly use a W3C specification, like this one, and obey WCAG, then I believe that your responsibility as a web author is done. I won't delay using a technique because a user agent can't deal with it (although I will try to give extra help where I can).«

Alles im Fluss – Formularlayout mit CSS

Viele große Websites, die ohne Layout-Tabellen gestaltet wurden, bedienen sich der float-Eigenschaften des CSS-Box-Modells. Bekannte CSS-Frameworks wie YAML bauen ebenfalls auf diesen Methoden auf und erreichen damit höchst flexible Layouts. Das Box-Modell beschreibt die Eigenschaften von CSS 2, beliebige Inhalts-»Behälter« (Boxen) einer HTML-Seite zu formatieren. Hiermit können Sie Inhaltsblöcke, die im rohen HTML nacheinander stehen würden, in der grafischen Darstellung nebeneinander positionieren. Wenn Sie nun eine solche Box per float: positionieren, so wird diese aus dem »Fluss« des Dokumentes herausgenommen und kann nun durch die Angabe float: right; oder float: left; beliebig rechts oder links neben einer darauf folgenden Box positioniert werden. Die Nachbar-Boxen umfließen nun diese Box. So lassen sich mit nur wenigen Zeilen Code komplexe mehrspaltige Layouts umsetzen, wie Sie hier an den »Einfach für Alle«-Seiten sehen können.

Eine detailliertere, dafür aber auch sehr technische Beschreibung der box- und float-Modelle finden Sie in den CSS 2-Spezifikationen des W3C; wem die Lektüre der W3C-Spezifikation zu trocken ist: die wohl beste Einführung in dieses Thema ist der Artikel »Float: the theory« von Holly Bergevin und John Gallant, hier in der deutschen Übersetzung »Float: Die Theorie«

Genau diese Eigenschaften können Sie auch ausnutzen, um in Formularen die Labels vollkommen tabellenfrei neben den dazu gehörigen Kontrollelementen zu positionieren. Die einzige Schwierigkeit besteht darin, dass die Labels einiger Kontrollelemente wie Textfelder oder Auswahlmenüs üblicherweise vor dem Element (also links daneben oder darüber) stehen; bei anderen Kontrollelementen wie Radiobuttons und Checkboxen stehen diese nach dem Element (d.h. rechts daneben). Sie sollten sich in Ihren Formularen unbedingt an diese Konvention halten, weil dies den Erwartungen des Nutzers im allen Betriebssystemen entspricht.

Ein Beispielformular

Erst mal das HTML

Das folgende Formular enthält die gängigen Elemente zur Eingabe von Text und zur Auswahl von Optionen. Als Vorbereitung auf die Formatierung per CSS wurden bereits einige Klassenangaben eingefügt. Alle Elemente, bei denen das Label links vom Kontrollelement steht, haben die Klasse "left", alle Elemente, bei denen das Label rechts daneben steht, haben die Klasse "right":

<form action="foo">
  <fieldset>
    <legend>Beispielformular</legend>

      <label for="textfeld" class="left">Text:</label>
      <input type="text" id="textfeld" name="textfeld" size="12"><br>

      <label for="auswahl" class="left">Auswahl:</label>
      <select id="auswahl">
        <option value="auswahl1">Auswahl 1</option>
        <option value="auswahl2">Auswahl 2</option>
      </select><br>

      <input type="radio" id="radio1" name="radio" value="entweder" class="right">
      <label for="radio1">Entweder</label><br>

      <input type="radio" id="radio2" name="radio" value="oder" class="right">
      <label for="radio2">Oder</label><br>

      <input type="checkbox" id="check1" value="sowohl" class="right">
      <label for="check1">Sowohl</label><br>

      <input type="checkbox" id="check2" value="alsauch" class="right">
      <label for="check2">Als auch</label><br>

    <button type="submit" class="right">Bestellen</button>

  </fieldset>
</form>

Das gerenderte Ergebnis zeigt ein Formular ohne jegliche Formatierung, aber in einer für nicht-grafische Darstellungsformen optimal verarbeitbaren Form:

Dann das CSS

Im nächsten Schritt wird das Style Sheet erstellt, um die Labels und Kontrollelemente zu positionieren. Zunächst werden die Labels mit der Klasse "left" mit einer Breite versehen und rechtsbündig an eine imaginäre Mittelachse gebracht. Über margin-right wird der Abstand der Labels zu den daneben stehenden Kontrollelementen definiert:

.left {
  float: left;
  text-align: right;
  width: 40%;
  margin-right: 2%;
}

Dann kommen die Radiobuttons und Checkboxen an die Reihe, die im HTML bereits mit der Klasse "right" versehen wurden. Der Abstand ergibt sich hier aus der Breite der Textlabels für die vorhergehenden Textfelder (40%) plus des Abstands dieser Labels zu ihren Kontrollelementen (2%). Hieraus ergibt sich für die folgenden Kontrollelemente inklusive des »Absenden«-Buttons ein linker Abstand von 40% + 2% = 42%, um sich an besagter Mittelachse auszurichten:

.right, button {
  margin-left: 42%;
}

Das war's auch schon – mit ein paar Zeilen Code (Beispieldatei: beispielformular.html) haben sie nun eine Basis-Formatierung für sämtliche Formulare Ihrer Website. Das Ergebnis sehen Sie in den folgenden Screenshots:

Darstellung unter Mac OS X Darstellung unter Windows

Luxuriöse Buttons

In den vorherigen Beispielen haben wir zum Absenden des Formulars <button>-Tags benutzt. In der unformatierten Variante sind diese eher hässlich und erinnern auch in modernen Browsern stark an die Zeiten von Windows 3.11. Vielleicht verwenden Frontend-Entwickler deshalb oft Buttons vom Typ <input type="submit">, ärgern sich dann über dessen mangelhafte Anpassbarkeit und greifen am Ende doch wieder auf <input type="image"> zurück.

Wesentlich flexibler ist man mit dem BUTTON-Element, da dieses nicht nur sehr individuell gestaltbar ist, sondern auch noch so gut wie alle anderen HTML-Elemente enthalten darf. Die Buttons selbst können zum Beispiel in einer Auflistung stehen, und selbst auch Block-Level-Elemente wie H1-H6 oder P und selbstverständlich auch Inline-Elemente oder Grafiken mit Alternativtext enthalten:

<fieldset>
  <legend>Bitte wählen Sie:</legend>
  <ol>
    <li>
      <button type="submit" name="karte" value="sued">
        <h3>Südkurve</h3>
        <p><strong>10 &euro;</strong></p>
        <p>(Stehplatz)</p>
      </button>
    </li>
    <li>
      <button type="submit" name="karte" value="nord">
        <h3>Nordkurve</h3>
        <p><strong>20 &euro;</strong></p>
        <p>(Sitzplatz)</p>
      </button>
    </li>
    <li>
      <button type="submit" name="karte" value="ost">
        <h3>Osttribüne</h3>
        <p><strong>30 &euro;</strong></p>
        <p>(Sitzplatz)</p>
      </button>
    </li>
    <li>
      <button type="submit" name="karte" value="west">
        <h3>Westtribüne</h3>
        <p><strong>50 &euro;</strong></p>
        <p>(VIP-Loge)</p>
      </button>
    </li>
  </ol>
</fieldset>

Mit ein wenig CSS können Sie aus diesen gänzlich unattraktiven Buttons nun das folgende zaubern:

Eine gute Anleitung zum Erstellen von reinen HTML- & CSS-Buttons finden Sie im Artikel »CSS3 Gradient Buttons «; auch für den umgekehrten Fall, nämlich wenn Buttons in der Optik von Links präsentiert werden sollen (z.B. um eine sekundäre Aktion weniger prominent zu zeigen), gibt es ein passendes Tutorial: »Styling buttons to look like links«

Das elegante an dieser Lösung ist, dass sie gänzlich ohne Hintergrundbilder auskommt. Die Unter-Elemente der Buttons können wie im Beispiel einzeln per CSS mit Verläufen, Schlagschatten, runden Ecken etc. versehen werden, ohne die Geschwindigkeit der Seiten durch zusätzliche Requests für Grafikdateien zu verringern. Den kompletten Code finden Sie in der Besipieldatei button.html.

Wenn Sie schon dabei sind Ihre Buttons direkt im CSS statt in Photoshop zu stylen, sollten Sie im Sinne der Zugänglichkeit auch an die möglichen Zustände von Buttons hover, focus & active denken und für diese Zustände das Aussehen festlegen. Gerade der aktive Zustand wird gerne vergessen, dabei ist dieser recht einfach zu erreichen, indem man z.B. den enthaltenen Verlauf einfach um 180° dreht, oder indem man den Button in gedrücktem Zustand um 1 Pixel nach unten oder nach unten rechts versetzt:

button:active {
  position: relative;
  top: 1px;
  left: 1px;
}

Browserbugs und andere Unterschiede im Rendering

Styling von Kontrollelementen

Im Gegensatz zu Buttons und Texteingabefeldern, die sich hervorragend stylen lassen, sollten Sie bei anderen Elementen eines Formulars lieber die Finger davon lassen, weil das Styling z.B. von Radiobuttons und Checkboxen in der Regel schief geht. Auch aus Sicht der Barrierefreiheit stellt sich für uns die Frage, ob es sinnvoll ist, Webseiten und ihre Elemente in allen Browsern gleich aussehen zu lassen.

Wenn die optische Darstellung von Formularelementen zu sehr von der für den Nutzer gewohnten Darstellung in seinem jeweiligen Betriebssystem abweicht, dann leidet darunter naturgemäß auch die Wiedererkennbarkeit und die Erlernbarkeit.

Falls Sie es doch wagen wollen, hier ein paar Links zu Artikeln, in denen die negativen Folgen illustriert werden:

Legendäre Browser-Bugs

Auch wenn wir zu Anfang die Verwendung von FIELDSET und LEGEND empfohlen haben – der Ehrlichkeit halber muss gesagt werden, dass insbesondere die Verwendung des LEGEND-Elements nur etwas für ganz hartgesottene Frontend-Entwickler ist. Leider gibt es hier eine ganze Reihe Inkonsistenzen und Bugs in verschiedenen Browsern, die einen sinnvollen Einsatz manchmal fast unmöglich machen. Besonders ärgerlich hierbei ist, dass diese Bugs teilweise seit mehreren Jahren bekannt und dokumentiert sind, es aber anscheinend niemand für nötig befindet, diese zu beheben.

So ist es bis heute kaum möglich, dass lange Legenden umbrechen und bei Bedarf mehrzeilig dargestellt werden, ohne dass es in dem einen oder anderen Browser zu Problemen kommt (Beispieldatei: firefox-legend-bug.html). Firefox erlaubt erst ab Version 3.6 die Deklaration einer Breite für <legend>…</legend>, bis einschließlich Firefox 3.5.7 ist die Breite der Legende immer gleich der Breite des enthaltenen Textes.
Eine lange Legende – oben in Safari 4, unten in Firefox 3.5

Eine Empfehlung, möglichst kurze Legenden zu verwenden ist sicher sinnvoll, aber spätestens bei Formularen in schmalen Spalten braucht man eine robustere Lösung. Diese wird jedoch dadurch erschwert, dass LEGEND in eigentlich allen Browsern nicht wie ein normales Element auf CSS-Anweisungen reagiert. Oft hilft nur, ein zusätzliches Element (z.B. SPAN) in <legend> zu schachteln und dann die Formatierung über das innere Element vorzunehmen.

<fieldset>
  <legend><span>Legende</span></legend>
  …
</fieldset>

Im CSS wird dem inneren <span> nun ein display:block; zugewiesen, wodurch sich die Hintergrundfarben immer auf die volle Breite des Fieldsets erstrecken.

Weitere Tipps & Tricks zum Thema Legenden:

Gestalterische Hilfen für Nutzer mit Behinderung

Deutlicher Fokus-Indikator bei Maus- und Tastaturnavigation

In Formularen wird generell, also auch von Nutzern ohne motorische Behinderung oder Sehbehinderung, öfter per Tastatur navigiert, weil der Nutzer in der Regel schon beide Hände auf der Tastatur hat und der Griff zur Maus eine Unterbrechung darstellen würde. Daher ist hier die geräteunabhängige Wahrnehmbarkeit und Bedienbarkeit noch wichtiger als bei reinen Textdokumenten ohne Formulare. Problematisch ist dies besonders bei mehrspaltigen Formularen: hier sollten Sie unbedingt auf eine Abfolge der Felder und Fieldsets im Quelltext achten, die dem optischen Ablauf des Formulars entspricht. Gleichzeitig muss dem Tastaturnutzer ein sehr deutlich erkennbarer optischer Indikator gegeben werden, wo sich der aktuelle Fokus befindet, da man die aktuelle und die nächste Position nicht zwangsläufig vom Aufbau des Formulars herleiten kann.

Mit modernem CSS lässt sich die Gestaltung der Formularelemente auch ohne den Einsatz von JavaScript verändern. So können Sie zum Beispiel die Hintergrund- oder Rahmenfarbe von Textfeldern ändern, sobald diese aktiviert sind. Damit teilen Sie dem Benutzer deutlich mit, in welchem Abschnitt des Formulars er sich zurzeit befindet und welche Eingabe als nächstes erwartet wird. Hierzu müssen Sie zunächst einmal die Hintergrund- und ggf. Rahmenfarbe der Textfelder definieren:

input[type="text"], textarea {
  background: #ddd;
  border: 1px solid #ccc;
}

Als nächstes werden die Textfelder beim Erreichen des Fokus (d.h. durch das Setzen der Einfügemarke per Tabulator oder Maus oder durch Anklicken des verknüpften Labels) farblich hervorgehoben:

input[type="text"]:focus, textarea:focus {
  color: #000;
  background: #fff;
  border: 1px solid #000;
  outline: 1px solid blue;
}

Ein Beispiel für diese Technik ist der per CSS-Outline erreichte Halo-Effekt beim Fokussieren eines Eingabeelements im Suchwidget von www.wien.at:

Wie Sie einen vergleichbaren Effekt erreichen können, beschreibt der Artikel »Mit CSS3 aktive Formularfelder auf Websites deutlicher kennzeichnen« von Michael van Laar. Ein fertiges Programmierbeispiel finden Sie im Codelisting input-halo.html.

Zeig mir deine Label

Gerade bei umfangreichen Formularen mit einer Vielzahl von Kontrollelementen kann es sinnvoll sein, das aktive Label bei der Interaktion durch den Nutzer hervorzuheben, wie im nebenstehenden Screenshot zu sehen ist:

Auch dies ist mit einigen Zeilen Code zu bewerkstelligen:

label:hover, label:focus {
  background-color: #ccc;
  outline: 1px solid #999;
}

Bitte nicht nachmachen!

Sie sollten auf keinen Fall den Fokus-Indikator wegnehmen. Diese Maßgabe betrifft sowohl das in bestimmten Redaktionssystemen verbreitete onfocus="this.blur()", das per Tastatur fokussierte Elemente sofort per Skript wieder de-fokussiert, als auch die sogenannten Reset-Styles, die oft unkritisch eingesetzt werden. Sie führen dazu, dass Wahrnehmbarkeit und Orientierung auf den Seiten massiv leiden.

Zwar steht in einem der verbreitetsten Reset-Bausteine extra noch ein Kommentar, welcher Anwender darauf hinweist, dass sie die Regeln für :focus noch ergänzen müssen. Wie die praktische Erfahrung gezeigt hat, wird dies dann aber gerne mal vergessen. Und so findet, wie Dirk Jesse in seinem Artikel »Löschen ist keine Lösung« zutreffend bemerkt, das folgende »Reset CSS«-Codeschnipsel seinen Weg in verbreitete CSS-Frameworks:

/* remember to define focus styles! */
:focus { outline: 0; }

Der Erfinder dieses Reset-Bausteins, Eric Meyer, hatte mittlerweile ein Einsehen und hat den Code so geändert, dass die Fokus-Indikatoren nicht mehr automatisch unterdrückt werden. Mehr dazu bei »Reset Revisited« – bleibt zu hoffen, dass der geänderte Code ebenso schnell Verbreitung finden wird wie der Ursprüngliche.

Optische Unterstützung bei geänderten Farbeinstellungen

Viele sehbehinderte Nutzer sind mit individuellen Einstellungen ihres Rechners und des Browsers im Netz unterwegs. Dazu gehören stark vergrößerte, aber auch verkleinerte Schriften und individuelle Farbeinstellungen, um die bei einigen Formen der Sehbehinderung auftretenden Blendeffekte zu mildern.

Hierfür bieten sämtliche Betriebssysteme eigene Einstellungsmöglichkeiten. Bei Linux-Desktops und unter Windows werden eine ganze Reihe so genannter Kontrastschemata mitgeliefert, die radikal den gesamten Bildschirminhalt verändern. Verbreitet ist die invertierte Darstellung z.B. mit gelbem Text auf schwarzem Hintergrund (unter Windows zu finden in den Systemeinstellungen als »Kontrast #1«). Unter Mac OS X hingegen kann entweder der gesamte Bildschirm in Graustufen oder invertiert (vergleichbar einem Foto-Negativ) dargestellt werden; der Bildschirm-Kontrast kann zudem systemweit mit einem Schieberegler sehr genau an die jeweiligen Bedürfnisse angepasst werden.

Problematisch werden solche Einstellungen für den Nutzer, wenn wie im Falle der Windows-Kontrastschemata sämtliche optischen Hilfen verschwinden, die der Designer eingebaut hat. Das System bzw. der Browser ignoriert in diesem Fall sämtliche Hintergrundfarben und stellt stattdessen überall die vom Nutzer eingestellte Hintergrundfarbe dar. Im konkreten Anwendungsfall wären also die Hilfen in Fieldsets oder die in unseren Designbeispielen zu sehenden gestreiften Hintergründe unsichtbar.

Aber es gibt einen Ausweg: Windows entfernt zwar alle Hintergrund-Farben (in CSS: background-color), nicht jedoch die Ränder (wie z.B. border: 2px solid #000;). Diese Tatsache kann man nutzen und seinen Farbflächen einen kleinen Rand in der gleichen Farbe geben – diese Ränder können dann für sehbehinderte Nutzer eine wertvolle Orientierungshilfe geben und fallen dem normalsichtigen Nutzer nicht weiter auf.

Weitere Informationen zu diesem Thema finden Sie im Artikel »Image Replacement-Techniken nicht zugänglich für Sehbehinderte« und in der BITV-Reloaded-Serie bei Anforderung 2 »Verständlichkeit ohne Farbe«.

Klick mich, ich bin ein Label

Mit ein wenig CSS können und sollten Sie Ihre Besucher informieren, dass man die Labels auch tatsächlich anklicken kann. Dies kann durch eine grafische Hervorhebung und durch eine Veränderung des Cursors beim Überfahren mit der Maus geschehen. Durch das folgende Beispiel verwandelt sich der Mauszeiger beim Überfahren des Labels in eine Hand mit Zeigefinger:

label, select, 
input[type=checkbox], 
input[type=radio],
input[type=button], 
input[type=submit] {
  cursor: pointer;
}

Falls Sie ein IE-spezifisches Style Sheet benutzen, sollten Sie an dieser Stelle noch die Angabe cursor:hand; deklarieren, da ältere Versionen des Internet Explorer die W3C-konforme Variante nicht verstehen.

Eingabefelder vom Typ Text (<input type="text"> bzw. <textarea>) benötigen hingegen keine Sonderbehandlung im CSS, obwohl dies mit dem Selektor input[type=text] möglich wäre – sämtliche uns bekannten Browser stellen hier von ganz allein eine Einfügemarke als Cursor dar.

Tipp: Wenn sie in Ihren Formularen Buttons vom Typ input type="submit" benutzen, dann sollten Sie im CSS nie das INPUT-Element stylen, sonst sehen Ihre Absenden-Buttons nachher aus wie Textfelder. Stattdessen sollten Sie Selektoren wie input[type=text] verwenden (die allerdings ältere Internet Explorer nicht verstehen) oder den Eingabeelementen Klassen zuweisen und diese per CSS formatieren. Die eleganteste Lösung ist jedoch, das BUTTON-Element zu benutzen.

Die Labels und die Kontroll- bzw. Eingabefelder werden in den gängigen Browsern durch eine Outline hervorgehoben, sobald sie mit der Tabulatortaste erreicht werden. Begehen Sie jedoch nicht den Fehler und nehmen diesen Fokus per JavaScript wieder weg, wie es viele Standard-Installationen des Open-Source-CMS Typo3 tun. Solche Formulare sind leider per Tastatur oder mit anderen alternativen Zeige- und Eingabegeräten nicht mehr zu bearbeiten.

Kennzeichnung inaktver Felder (Disabled & Readonly)

Ein, wenn auch geringfügiges, Problem aus Sicht der Barrierefreiheit stellen inaktive Formularfelder dar, wenn die »ausgegrauten« Informationen so kontrastarm sind, dass sie nicht mehr von allen Nutzern wahrgenommen werden können. Zwar nehmen die WCAG 2.0 solche Felder ausdrücklich von den Vorgaben für Mindestkontraste aus (»Für Text oder Bilder eines Textes, die Teil eines inaktiven Bestandteils der Benutzerschnittstelle […] sind […] gibt es keine Kontrastanforderung.«), trotzdem möchten viele Nutzer wissen, welche Funktionen zurzeit nicht zur Verfügung stehen – sie können diese aber nicht entziffern. Eine zusätzliche Kennzeichnung inaktiver Elemente, z.B. per Icon, würde das Interface unnötig verkomplizieren, daher bleibt hier nur die Variante, per CSS die generell etwas zu schwachen Kontraste solcher Felder und Kontrollelemente zu erhöhen – allerdings nur bis zu dem Punkt an dem sie noch von normalen, aktiven Feldern unterscheidbar sind.

Auf weitere Probleme in der Unterstützung solcher Felder durch verbreitete Screenreader weist der Artikel »Screen Reader Support For Disabled & Read Only Form Fields« hin.

Formulare zum Ausdrucken

Ein leider viel zu wenig beachtetes Anwendungsszenario von web-basierten Formularen ist der Ausdruck. Nutzer wollen vielleicht ihre gemachten Eingaben ausdrucken und archivieren, oder das leere Formular von Hand ausfüllen. Mit ein wenig CSS können Sie Ihr Formular so aufbereiten, dass es auch im Ausdruck eine gute Figur macht, ohne dass Sie dafür den HTML-Code verändern müssen.

Dazu müssen Sie nur Ihr Print-Style-Sheet (Sie haben doch ein Print-Style-Sheet, oder?) um ein paar Eigenschaften erweitern. Hier sollten Sie den Kontrollelementen ein Aussehen mitgeben, das für den Ausdruck geeigneter ist als die gewohnten Kontroll-, Eingabe- und Auswahlelemente im Webbrowser. Bei Textfeldern ist dies ausgesprochen simpel: statt der üblichen Pseudo-3D-Border definiert man im CSS kurzerhand:

textarea, input[type=text] {
  border: none;
  border-bottom: 2px #000 solid;
}

Im Ausdruck ergibt dies:

Label: __________________

Bei anderen Formularelementen wie Radiobuttons oder Checkboxen ist dies nicht ganz so einfach, allein schon weil man in CSS nicht für alle Browser runde Formen definieren kann, die für Radiobuttons nötig wären. Sie können diese allerdings simulieren, indem Sie die Kontrollelemente per Image Replacement durch eine entsprechende Grafik ersetzen. Ein weiterer Ansatz wäre, die Elemente mit CSS auszublenden und mit Generated Content durch Sonderzeichen wie zum Beispiel das Ballot Box-Zeichen aus Zapf Dingbats (Beispiele: ⊗ ⊠ ❏ ☐ ☒) zu ersetzen. Diese werden zwar, wie viele Unicode-Zeichen auch, im Screenreader nicht vorgelesen – allerdings ist es auch ausgesprochen unwahrscheinlich, dass sich ein vollblinder Screenreader-Nutzer ein für den Ausdruck vorgesehenes Formular vorlesen lässt.