Formularfelder richtig beschriften
Formulare sind neben Links wohl diejenigen Konstrukte, mit denen wir es beim täglichen Surfen und Arbeiten im Web am häufigsten zu tun aben. Und doch passieren hier bei der Entwicklung viele Fehler. Marco Zehe zeigt in seinem Artikel häufige Fehler und wie diese richtig vermieden werden können.
Diese Fehler führen dann zu einer eingeschränkten Barrierefreiheit oder anderen Problemen bei der Validierung oder Projektübergabe. Dieser Artikel soll helfen, häufige Fehler zu vermeiden und bietet als Bonus am Ende noch ein bisschen moderne Würze.
Das label-Element
Die meisten Formularfelder wie Textfelder, Aufklapplisten oder Kontrollkästchen benötigen eine Beschriftung, damit der Anwender weiß, was er in das jeweilige Feld eintragen oder auswählen muss oder was das Ankreuzen oder Abhaken des Kontrollkästchens bewirkt. In HTML gibt es viele Möglichkeiten, Texte visuell Formularfeldern zuzuordnen. Aber nur eine ist syntaktisch korrekt und führt zu einem positiven Abhaken bei einer Barrierefreiheits-Checkliste. Dies ist das label-Element. Dieses fasst den Text ein, der ein bestimmtes Eingabeelement (input, textarea, select usw.) beschreibt.
Weiterhin muss dieses label-Element das Attribut for enthalten, welches als Wert die ID des Eingabeelements bekommt, welches beschrieben wird. Ein häufiger Fehler hierbei ist, dass dem input-Element statt des id-Attributs das name-Attribut gegeben und dieses dann als Wert für das for-Attribut des label-Elements angegeben wird. Dies ist syntaktisch nicht korrekt.
Ein korrekt codiertes einfaches Adressformular hat diesen Quelltext:
- <form action="post.php" method="post">
- <fieldset><legend>Adressangaben</legend><br />
- <label for="vollerName">Vor- und Zuname:</label><input id="vollerName" /><br />
- <label for="strasse">Straße</label> <label for="hausnummer">und Hausnummer:</label><input id="strasse" /> <input id="hausnummer" /><br />
- <label for="plz">PLZ:</label><input id="plz" maxlength="10" /> <label for="ort">Ort:</label><input id="ort" />
- </fieldset>
- </form>
Und so sieht’s aus (noch ohne besonderes Styling).
- Die erste Zeile innerhalb des Fieldsets ist einfach: Es gibt ein Textfeld für den vollständigen Namen.
- In der zweiten Zeile wird die vollständige Bezeichnung der Zeile an den Anfang geschrieben, es wird jedoch explizit auf zwei Textfelder verwiesen, um genau zu definieren, dass in das erste die Straße und in das zweite nur die Hausnummer einzutragen sind.
- In der dritten zeile schließlich wird jedes label-Element wieder einem input-Element zugeordnet, und die Elemente wechseln sich ab, stehen lediglich nebeneinander.
Dieses Hörbeispiel (MP3-Datei) zeigt , wie das Formular von NVDA, Window-Eyes (beide Windows) und VoiceOver (Mac OS X) vorgelesen wird, wenn man mit Tab von Element zu Element springt.
Ein häufiger Fehler ist, dass die Beschreibungen für Straße und Hausnummer in einem Label stehen, welches dann nur dem ersten input-Element zugeordnet wird. Das zweite steht daneben, hat aber keine Bezeichnung. Benutzer von Bildschirmleseprogrammen hören dann für das erste Eingabefeld eine vollständige Bezeichnung und tragen fälschlicherweise sowohl Straße als auch Hausnummer in dieses erste Feld ein, nur um dann festzustellen, dass die Hausnummer eigentlich ins zweite Feld sollte. Im schlimmsten Fall wird ihnen das Fehlen der Hausnummer erst nach dem Abschicken des Formulars mitgeteilt.
Die obigen Richtlinien gelten analog für select- oder textarea-Elemente (z. B. bei durch Aufklapplisten realisierte Geburtstagsangaben).
Kennzeichnung erforderlicher Felder
Häufig kommt es vor, dass nicht alle Felder eines Formulares ausgefüllt werden müssen. Entweder kennzeichnet ihr also nun diejenigen Felder, die absolut erforderlich sind, indem ihr ein Wort wie »erforderlich«, ein Sternchen »*« o. ä. der Beschriftung hinzufügt, oder ihr kennzeichnet diejenigen Felder, die nicht absolut erforderlich sind, mit dem Wort »optional«. Gern wird auch für erforderliche Felder ein anderer Stil (z. B. eine andere Hintergrundfarbe) verwendet, dies funktioniert jedoch nicht für alle Benutzergruppen und sollte daher nur zusätzlich, nicht ausschließlich, verwendet werden.
In neueren Projekten findet man auch häufiger die Verwendung des WAI-ARIA-Attributes aria-required, das zusätzlich verwendet werden kann, um erforderliche Felder zu kennzeichnen. Es wird dem jeweiligen input-Element hinzugefügt, und sein Wert wird auf »true« gesetzt. Beispiel: <input id="vollerName" aria-required="true" />
. Aktuelle Versionen von Bildschirmleseprogrammen, wie NVDA 2009.1 oder JAWS 10 und höher, werten dies aus, um von sich aus spezielle Hinweise auf die Erforderlichkeit eines solchen Eingabefeldes zu signalisieren.
Weiterführende Beschreibungen
Manchmal kommt es vor, dass eine Erklärung oder Ergänzung nicht in ein label-Element passt, sondern getrennt von diesem z. B. unterhalb des Eingabefeldes angegeben wird. Ausschließlich durch WAI-ARIA kann auch dieser Text dem input-Element zugewiesen werden und dann von Bildschirmleseprogrammen als zusätzliche Information automatisch gesprochen werden. Ihr geht dazu folgendermaßen vor:
- Fasst den Text mit der weiterführenden Erklärung in ein Element ein, dem ihr eine ID über das id-Attribut gebt.
- Dem eigentlichen input-Element fügt ihr das Attribut aria-describedby hinzu, welches als Wert die im obigen Schritt vergebene ID bekommt.
Hinweis: input-Element steht hier synonym auch für alle weiteren Formularfeldelemente.
Kommentare
Chris
am 20.12.2009 - 10:24
Sehr schöner aufklärender Text. Vielen Dank. Allerdings ist in der Beispielseite ein Mini-Fehler passiert. das title-tag hat zweimal ein > bekommen. :-)
Gruß und schönen 4. Weihnachtstag
Chris
domingos
am 20.12.2009 - 10:49
Sehr schöner Beitrag. Formulare sind oft die Achillesferse von Webseiten. Bei Amazon z. B. wenn man die Bankverbindung bei der Erstanmeldung oder bei Änderungen eintragen muss. Die Screenreader liest zuerst die Beschriftung der Formularfelder hintereinander vor und zeigt dann die vier zugehörigen Eingabefelder hintereinander an. Als Blinder darf man also entweder raten, welche Angabe wohin gehört oder spekulieren, dass die Reihenfolge der Feldnamen der Reihenfolge der Eingabefelder entspricht, was stimmen kann, aber nicht muss. Der Blinde kann also Hilfe nicht bei Amazon bestellen. Wie so oft hat hier weder jemand richtig nachgedacht noch die Funktionen testen lassen.
Maik Wagner
am 20.12.2009 - 13:05
Screenreader live im Feldversuch, fein!
Offensichtlich ist der Bug, den "die Screenreader" machen, nämlich bei jedem Feld die des erneut vorzulesen, noch nicht behoben. Kannst Du nochmal sagen, welcher von denen das wie macht?
Marco Zehe (Autor)
am 20.12.2009 - 13:52
Bis auf den NVDA wiederholen alle mir bekannten Screen Reader den Titel/die Legend des Fieldsets bei jedem der Elemente. Der NVDA hat hier ganz deutlich die Nase vorn, weil die intelligenteste Behandlung von verschachtelten Focusübergängen (also rein in eine Gruppe, rein in ein Element, raus aus Element, raus aus Gruppe usw).
Gabriel
am 20.12.2009 - 14:19
Noch als Ergänzung zu diesem Artikel: schön bündige Formulare lassen sich mit einer ungeordneten Liste erstellen, in denen die Labels floaten. Dann werden auch keine s benötigt.
Hier das ganze Tutorial: http://www.alistapart.com/articles/prettyaccessibleforms
Maik Wagner
am 20.12.2009 - 14:35
Huch, die Elemente nicht maskiert, sie verschwinden und du weißt trotzdem, was ich meine...
Gemeint war die <legend> des <fieldset>, die bei jedem Element immer wieder vorgelesen wird. Danke!
Markus
am 20.12.2009 - 14:53
Also ich hab sehr gute Erfahrungen damit gemacht, statt Straße die Bezeichnung Straßenname zu benutzen. Der User sucht dann in der Regel von selbst nach einem Eingabefeld für seine Hausnummer.
Fritz Weisshart
am 20.12.2009 - 15:22
Hallo Marco,
schöne Zusammenfassung. Danke dafür.
Noch 'n Tipper:
Und so sieht's aus (noch besonderes Styling).
sollte wohl heißen:
Und so sieht's aus (noch ohne besonderes Styling).
nik
am 20.12.2009 - 15:31
Schade, dass gerade das Thema Check/Radioboxes ausgespart wurde. Denn in einem (auch optisch) standardkonformen Formular, sollte ja sowohl links beschreibend ein Text stehen, der den Sinn der Elementliste angibt, als auch bspw. rechts neben jeder Box ein Labeltext. Ob man jetzt auf das erste Element ein zweites Label setzt, was ja genau genommen auch nicht auf die Elementgruppe zeigt und damit ähnlichen Kritikpunkten wie die Straße/Hausnummer unterliegen, wäre mal wirklich interessant gewesen.
nik
am 20.12.2009 - 15:33
PS: Im Übrigen, liebe Webkrauts, muss ich mal deutlich diese Kommentarbox kritisieren. Sie besitzt keinen Vorschaubutton, noch der entstehende Beitrag eine Editierfunktion. Ob mein Beitrag korrekt angezeigt wird bleibt also auf reines Raten beschränkt. In Beitrag 3/5 kann man gut sehen, dass dies nicht immer klappt.
alexander farkas
am 20.12.2009 - 15:38
Zu den unterstützen Screenreenreadern beim Aria-Part:
Die aria-required/aria-invalid-Attribute funktionieren definitiv auch in Jaws 9/NVDA 0.6p2 und mit hoher Wahrscheinlichkeit bereits in Jaws 8, Windows Eyes 5.5 etc. (nicht getestet).
Zu Gruppierungen im allgemeinen und Fieldset im besonderen:
Jaws liest Gruppierungen normalerweise ähnlich vor wie NVDA. Das heißt wird eine Gruppierung betreten wird der Name und die allgemeine bzw. besondere Rolle der Gruppierung erwähnt. Wird dann innerhalb der Gruppierung weiter navigiert/fokusiert wird die Gruppierung nicht nochmals erwähnt. Dies ist ein ziemlich cooles Vorleseverhalten und wird bei Aria konzeptionell immer wiederkehrend benutzt. So sind beispielsweise die Menus - Menu ist eine Gruppierung von Menuitems - beim Aria-YUI Menu durch labeldby mit dem übergeordneten Menuitem verbunden. Todd Kloots (einer der Aria-Meister bei Yahoo) beschreibt diese labelledby-Technik bei gruppierten Elementen kurz.
Ich nutze diese Technik bei zweien meiner Aria-Tutorials.
a) Bei Bereichen, deren Sichtbarkeit durch einen Button gesteuert werden kann, sind diese Bereiche gruppiert (Rolle: group) und mit aria-labelledby mit dem Button verbunden. Das hört sich in Firefox 3.x zusammen mit dem aria-expanded-Attribut richtig gut an. (Aufklappende Bereiche).
b) Bei einfachen Ausklapplisten/nicht schreibbaren Comboboxen.
Hier wird nicht nur die Combobox mit dem label-Element verbunden, sondern zusätzlich auch die Liste, welche nichts anderes ist als eine Gruppierung von Optionen (Demo Aufklappliste mit Aria.
Nur bei Gruppierungen innerhalb von Formularen verhält sich Jaws dagegen so nervig. (Aus Aria-Sicht ist ein fieldset technisch eigentlich nichts anderes als die Rolle group, welches mit dem legend-Element "gelabelt" wurde.) Dies hat - soweit ich mich richtig erinnern kann - den besonderen Grund, daß die UAAG-Spezifikation ein solch blödes Verhalten nahe legt. Weiteres zu legend/fieldset könnte bei der Paciello Group zu finden sein. Im Ergebnis könnte sich Jaws eigentlich auch intelligenter verhalten, aber die Spezifikations-Treue hat dem ganzen einen Riegel vorgeschoben.
Marco Zehe (Autor)
am 20.12.2009 - 15:52
Hallo an alle, herzlichen Dank für das zahlreiche Feedback! Werde den Fehler im Beispielformular noch korrigieren, das tut aber dem Lesebeispiel keinen Abbruch. ;)
An Alexander: Ja, JAWS 9 kann aria-required und aria-invalid, JAWS 8 nicht. Erst ab JAWS 10 funktionieren aber so Dinge wie aria-labelledby usw. richtig. Live Regions sowieso, aber die waren hier ja nicht Thema. :)
Jens Grochtdreis (Webkraut)
am 21.12.2009 - 09:01
@Gabriel: Ich finde die Nutzung von Listen zur Organisation von Formularelemente sehr zweifelhaft. Im seltensten Fall kann man doch ein Formular als Aufzählung interpretieren. Wir sollten uns immer fragen, welchen Charakter die auszuzeichnende Information hat. Ein Kontaktformular ist genauso wenig eine Aufzählung, wie eine Webseite selber. Es genügt vollkommen, alle Formularblöcke (Zeilen?) in DIV-Container zu packen. Die kann man dann auch gut stapeln. Und wenn man nur Label und Inputfelder organisiert hilft auch meist ein beherztes display: block weiter. Wobei ich dabei dann leider nicht weiss, ob es nicht für Screenreadernutzer besser wär, echte Blockelemente zur Abtrennung zu nutzen.
Listen würde ich jedenfalls zur Organisation eines Formulars nie nutzen.
Chris
am 22.12.2009 - 08:07
@Marco
Das sollte auch kein Kritisieren sein. Der Teufel liegt eben im Detail. grinzt.
Was ich bei den vielen Beispielen unverständlich finde ist, dass immer solche Libary's wie jquery genutzt werden. Ist es die Faulheit der Entwickler und die darauß hoffentliche Zeitersparnis? Kann man es rechtfertigen, für ein einfachen "Tabbing" 120kb jquery einzubinden und dann 20 Zeilen Code zu schreiben? Meines Erachtes nach ist das unnötige Zusatzballast.
Wo soll das nur enden? YAML, jquery, als nächtes noch ein (x)HTML mega-Template (wurde ja schon an dem div-suppen-beispiel von OOCSS gut gezeigt) und schon haben wir eine 200 KB Seite, ohen das überhaupt Inhalt drin steht.
Schade irgendwie.
Gruß und dennoch schönen guten Morgen
Chris
Chris
am 22.12.2009 - 08:09
Edit: Editierfunktion!! :-)
*ohne
Ulf
am 22.12.2009 - 08:47
@Jens
Ich empfinde Formulare schon meist als Listen. Ich muss meine Eingaben chronologisch eingebn. Formulare in Deutschland vom Bürgeramt sind doch auch meist nummeriert. Formulare sind doch eigentlich eine Abfrage von Fakten in einer gewissen sinnvollen Reihenfolge - was eben auch Listen sind.
@Chris
jQuery minified und compresses sind 19KB über Google. Und ich weiß nicht ob diese 19KB nicht doch die erhöhte Usability und Benutzbarkeit der Seite wert sind (kann natürlich auch ein anderes JS-Framework sein). Im übrigen nutzt man JS-Libraries nicht aus Faulheit sondern eben aus Zeitersparnis und da man nicht schon gelöste Probleme immer wieder neu lösen muss (do not reinvent the wheel).
Jens Grochtdreis (Webkraut)
am 22.12.2009 - 09:03
@Ulf: Mit dieser Argumentation ist so ziemlich alles eine Liste. Ein Text ist eine Abfolge von Absätzen (erster, zweiter, dritter ..) oder wir haben eine "Liste von Seitenelmenten". Ich bevorzuge, die Semantik enger zu fassen, es ist so schon manchmal kompliziert genug, einen Unterschied zwischen Listen und Tabellen oder Listenarten zu erkennen.
Chris
am 22.12.2009 - 10:00
@Jens
letzenendes ist es dennoch die eigene Auffassung, wie man etwas auszeichnet. Die Spezifikation betrachtet das nicht so eng und lässt da eigentlich recht viele Freiheiten. Man könnte ja eigentlich auch ein Menu in einer ol oder dl darstellen. Wenn es Sinn ergibt.
@Ulf
Über 19KB lässt sich schon reden. Allerdings, soweit ich weiß, sind das nur 19KB, wenn du es über dem Server als gzip laufen lässt. Ansonsten sinds in die 40KB.
Bislang hatte ich keine guten Erfahrungen damit gemacht und wenn ich so einige Seiten betrachte die jquery nutzen, dann sind das meist ziemliche Klotze. Gerade in der CEHTML-Branche (Webseiten für Mobile geräte über z.B. Fernbedienung steuerbar) findet man oft welche, die jquery gar missbrauchen um irgendwelche tollen "Effekte" einzubinden. Letzenendes leider dann dennoch die Benutzbarkeit darunter. Keiner wartet gerne länger als 5 Sekunden auf Inhalte, lässt sich aber durch den supertollen Einblendeffekt beschlichten.
Gruß
Chris
Ulf
am 22.12.2009 - 14:58
@Jens
Durchaus ist ein Text auch eine Abfolge von Paragraphen. Da die HTML-Syntax aber -Tags besitzt, sind diese natürlich sinnvoller als Listenelemente an dieser Stelle (ohne Frage). Die Divs innerhalb von Formularen sind doch aber meist verkappte Listen. Es wird eine chronologische Abfrage von gewissen Fakten abgefragt. Des weiteren dienen ja auch fieldset / legend der Gruppierung von Elementen. Eine Gruppierung ohne Sortierung macht semantisch wenig Sinn. Sicherlich ist ein Formular nicht ein 1a-Listenelement, welches zu 100% in das Profil passt, aber solange es keine bessere HTML-Elemente gibt, ist dies für mich noch das Sinnvollste. Inhaltsleere Containerelemente steigern auf jeden Fall nicht die Semantik der Seite. Trotzdem finde ich Divs ok im Kontext eines Fomrulars, die Ablehnung von Listenelementen aufgrund der Semantik halte ich aber für höchst diskussionswürdig.
@Chris
Da Google auch gzip anbietet, gibt es keinen grund es nicht zu nutzen. Dazu wird jQuery nicht dadurch schlecht nur weil es missbraucht wird. JS-Libraries sind großartige Tools, die die Usability und Benutzerfreundlichkeit einer Webseite beträchtlich steigern - wenn man es richtig verwendet. Frauen sind ja auch nicht per se böse. ;)
Chris
am 22.12.2009 - 20:07
Hallo Ulf. Ich danke dir für die Antwort. Allerdings bin ich immernochnicht überzeugt. Nehmen wir mal ein einfaches Tabbing. Mit jquery habe ich 19KB, wenns komprimiert ist. Dann das Tabbing.js welches nochmal 60KB groß ist. Sind schon 79KB für ein einfaches Tabbing. Also wenn ich eins "schnell" OOP fummel, dann ist es 12KB groß und auch jederzeit verwendbar.
Wo ist da der Gewinn? Ich denke der Gewinn von jquery liegt in Zeit- und somit Kostenersparnis. Desweiteren ist hier der Vorteil, dass schon eine Vielzahl von "fertigen" Scripten mit kleinen Anpassungen vorhanden sind. Wenn es dann noch sinnvoll eingesetzt ist, bringt es wohlmöglich auch tolle Effekte und mehr Benutzerfreundlichkeit, soweit man JS angeschalten hat (davon gehen wir mal aus..sonst lahmt das Beispiel).
Gegenüber kann man aber ein selbsterstelltes (OOP) JS-Script nehmen, welches perfomanter und wohlmöglich auch einfacher zu Ändern ist (meiner Meinung nach, ist ja selbst geschrieben).
Hat alles Vor- und Nachteile und in der heutigen Gesellschaft, wo es zählt wer schneller ist (leider) - und wohlmöglich auch qualitativ schlechter -, ist wohlmöglich vorne.
Gruß und schönen Abend
Chris :-)
P.S.: ich hoffe die Diskussionen stoßen nicht negative auf.
Ulf
am 23.12.2009 - 10:22
Ich weiß nicht welche Tabbing.js du meinst, welche 60KB groß ist, aber ich nehme stark an dass diese weder compressed ist noch gzipped. Jedes JS-Plugin sollte eigentlich kleiner werden als das jQuery-Monstrum.
Das große Problem welches ich sehe ist, dass du eben nicht so schnell ein OOP-Script bastelt, welche alle Browser-Inkompatilitäten kapselt (nightmare IE6) und trotzdem sehr smooth funktioniert. jQuery und Mootools (die einzigen JS-Libraries die ich kenne) haben ein sehr gut durchdachten OO-Konzept sowie Callback-Prinzip. Dazu erleichert es mir die Arbeit enorm, da ich eben mich nicht noch zu 100% mit JS und deren Syntax beschäftigen muss. Es extrahiert eben auch für mich viel. Ein Frontendler (der ich sicher nicht bin) sollte aber durchaus auch die Vor- und Nachteile von jQuery kennen wenn er es intensiv einsetzt.
Ich gebe dir aber durchaus Recht (und weiß auch), dass viele Marketing-Leute ihre Seite gerne überladden ("Toller Effekt", "Hab ich doch neulich bei xyz gesehen) und dann endet man schnell mit jQuery + vielen Plugins ab. Dem muss man eben auch einfach Einhalt als Entwickler geben und auf die Nachteile hinweisen (Ladezeit, Wartbarkeit etc. pp.).
Kaiuwe
am 23.12.2009 - 14:36
@Ulf
Ein deutsches Amt als Beispiel oder gar als Begründung aufzuführen, halte ich mehr als fraglich. Mit den Formularen vom Finanzamt könnte man sogar Layouttabellen begründen. Aber ein Finanzamt ist nun überhaupt nicht barrierearm, in keiner Weise.
Die Kommentare sind geschlossen.