- HTML-Listen sollten nicht nach ihrem visuellen Aussehen, sondern nach Bedeutung und Interaktionsweise ausgewählt werden; sie lassen sich in Steuer-, geordnete, beschreibende, Menü- und ungeordnete Listen unterteilen
- Für feste Auswahlmöglichkeiten sind
<select>/<option> korrekt, für Eingaben mit Vorschlägen <datalist>; dabei muss man das Verhalten von multiple, optgroup, size und value unterscheiden
<ol> wird für Abläufe, Ereignisse und Kontinua verwendet, bei denen sich die Bedeutung ändert, wenn man die Reihenfolge ändert; reversed kehrt nur die Nummerierung um, nicht die tatsächliche Reihenfolge der Einträge
<dl> wurde in HTML5 über die Definitionsliste hinaus zur Beschreibungsliste erweitert und eignet sich für Begriff-Wert-, Metadaten- und andere Schlüssel-Wert-Paare wie beim JSON-Debugging
<menu> dient für Befehlslisten wie Werkzeugschaltflächen und unterscheidet sich in Bedeutung und erlaubtem Inhalt von nav; alle übrigen allgemeinen Listen gehören in <ul>
Steuerlisten: <select>/<option> und <datalist>
- Auch in Formularen lassen sich Listen erstellen, mit denen Nutzer interagieren
-
Feste Auswahlmöglichkeiten mit <select> und <option>
- Wenn Nutzer nur Elemente aus einer Liste auswählen dürfen, verwendet man
<select> und <option>
- Im Beispiel einer Sprachliste werden
<option>-Einträge wie Select a Language, English, French, Spanish, Portuguese innerhalb von <select name="languages"> platziert
- Ein normales
<select> erlaubt standardmäßig genau eine Auswahl
- Sollen mehrere Elemente auswählbar sein, fügt man das Attribut
multiple hinzu
- Mit
multiple ändert sich die Darstellung der Liste, alle Optionen werden sichtbar, und Nutzer können mit Shift oder Cmd + Klick mehrere Einträge auswählen
- Verwendet man echtes
select und option, übernimmt die browserseitige Standardsémantik dies, sodass man an ein Listenelement mit role="listbox" nicht selbst aria-multiselectable anbringen muss
-
Verwandte Optionen mit <optgroup> gruppieren
- Wenn Sprachen nach Sprachfamilien gruppiert werden sollen, gruppiert man die Optionsliste mit
<optgroup>
- Im Beispiel werden
<optgroup>-Elemente mit den label-Werten Germanic, Romance, Celtic erstellt und die Einträge English, French, Spanish, Portuguese, Irish, Welsh darin platziert
- Soll eine bestimmte Untergruppe nicht auswählbar sein, fügt man dem betreffenden
<optgroup> das Attribut disabled hinzu
- Im Beispiel wird die Gruppe
Celtic mit disabled versehen und damit die Gruppe mit Irish und Welsh deaktiviert
-
Mit HTML-Bordmitteln verbessern
- Wenn eine visuelle Trennung zwischen Gruppen nötig ist, kann man das in
<select> erlaubte <hr> verwenden
- Das Attribut
size steuert, wie viele Einträge gleichzeitig angezeigt werden, und ist daher für lange Listen nützlich
- Verwendet man
size zusammen mit optgroup, belegen auch die Gruppenbeschriftungen Platz in der Anzeige
- Im Beispiel enthält
<select name="languages" size="4" multiple> die Gruppen Germanic, Romance, Celtic, Afroasiatic sowie <hr /> dazwischen und zusätzlich Hebrew und Arabic
Vorschlagslisten: <datalist>
- Wenn Nutzer nicht ausschließlich aus der Liste wählen müssen, sondern die Liste nur Vorschläge machen soll, verwendet man
<datalist>
<datalist> wird in zwei Schritten verbunden
- Man erstellt ein
<datalist> und weist ihm eine id zu
- In das
list-Attribut des zugehörigen <input> trägt man diesen id-Wert ein
- Im Beispiel für Sprachvorschläge stehen in
<datalist id="languages"> die Optionen English, French, Spanish, Portuguese, Irish, Welsh, Hebrew, Arabic, und über <input name="language" list="languages"> wird das Eingabefeld damit verknüpft
-
Das Verhalten von <option value>
- Der Standardwert von
<option> ist der umschlossene Text; wenn ein value-Attribut vorhanden ist, überschreibt dessen Wert den Standardwert, während der Text wie ein Label fungiert
- Bei
<select> ist das meist unproblematisch, weil Nutzer nur den Text sehen; bei <datalist> kann es jedoch verwirrend sein, weil Nutzer das Label sehen und auswählen, im Eingabefeld danach aber value landet
- Im Beispiel sehen Nutzer bei
<option value="cy">Welsh</option> zwar Welsh, im Eingabefeld steht danach jedoch cy
- Wer
<datalist> verwendet, muss also davon ausgehen, dass der eingefügte Wert nicht das Label, sondern value ist
-
Mit mehreren Eingabetypen kombinieren
<datalist> ist nicht nur für Textoptionen gedacht, sondern kann auch mit anderen input-Typen kombiniert werden
- Im Beispiel zur Wochenauswahl wird
<datalist id="preferred-weeks"> mit <input type="week" name="week" id="camp-week" min="2026-W2" max="2026-W51" list="preferred-weeks" /> verbunden
- Vorgeschlagene Wochen sind
2026-W22, 2026-W23, 2026-W24, 2026-W25
-
Kombination mit <input type="range">
<datalist> ist nicht auf Zeichenketten beschränkt, sondern funktioniert auch mit Zahlen; dadurch lässt es sich mit Range-Eingaben kombinieren, um markierte Punkte mit Labels über einem Wertebereich zu erzeugen
- Im Beispiel für die Trinkgeldquote wird
<datalist id="recommended-tips"> an <input type="range" name="tips" id="tips" min="0" max="50" step="1" list="recommended-tips" /> gebunden und mit Labels 10%, 18%, 30%, 45% versehen
- In Chrome-basierten Browsern wird per
@supports (x: attr(x type(percentage))) der label-Wert über attr() gelesen, der Wert mit type() als Prozent deklariert und die Optionen per position: absolute platziert
- Für Firefox wird
@supports not (x: attr(x type(percentage))) verwendet; der Wert wird dort über ::before angezeigt
- Dieses Verfahren garantiert nicht, dass alle Browser gleich funktionieren oder auf dem Bildschirm identisch darstellen
Geordnete Listen: <ol>
- Für eine Sammlung von Einträgen, die in einer bestimmten Reihenfolge gelesen werden müssen, verwendet man
<ol>
- Entscheidend ist nicht, ob neben den Einträgen Zahlen angezeigt werden, sondern ob sich die Bedeutung der Liste ändert, wenn man die Reihenfolge der Einträge verändert
- Geeignete Sammlungen für
<ol> sind Algorithmen, Folgen von Ereignissen, Elemente auf einem ansteigenden oder absteigenden Kontinuum, Rezepte und alphabetische Listen
- Im Beispiel für ein Bananenbrot-Rezept wird die Reihenfolge aus Ofen vorheizen und Form einfetten, Zutaten mischen, Teig eingießen, 60 Minuten backen oder bis ein Zahnstocher sauber herauskommt, und auf einem Kuchengitter abkühlen als
<ol> dargestellt
- Auch eine alphabetische Zutatenliste gehört zu
<ol>, weil sie einem alphabetischen Kontinuum folgt; die Reihenfolge ist baking soda, bananas, brown sugar, butter, eggs, flour, salt
-
Verschachtelung geordneter und ungeordneter Listen
- Eine gut strukturierte geordnete Liste sollte sich so lesen lassen, dass man auch ohne Browser-Rendering versteht, was in welcher Reihenfolge geschehen muss
- Im Rezeptbeispiel wird für die übergeordneten Schritte ein
<ol> verwendet; innerhalb eines Schritts kommen bei nicht relevanter Reihenfolge <ul> zum Einsatz und für wiederum geordnete Teilschritte erneut <ol>
- Die Struktur bewahrt die übergeordnete Reihenfolge
Prepare, Mix, Pour, Bake, Cool, während parallele Elemente innerhalb von Prepare und Bake mit <ul> und Abläufe innerhalb von Mix und Cool mit <ol> dargestellt werden
-
reversed
- Das Attribut
reversed ändert die Nummerierungsrichtung von aufsteigend zu absteigend
- Die tatsächliche Reihenfolge der Listeneinträge bleibt unverändert
- Es kann für Zutaten- und Mengenlisten verwendet werden, die etwa
most to least von viel nach wenig darstellen
- Im Beispiel enthält
<ol reversed> die Einträge eggs (2), flour (2 cups), bananas (2) (mashed), brown sugar (¾ cup), butter (½ cup), baking soda (1 teaspoon), salt (¼ teaspoon)
-
Die tatsächliche Reihenfolge per JavaScript umkehren
- Soll die Liste wirklich umgedreht werden, kann man mit JavaScript die
li-Kinder in umgekehrter Reihenfolge neu anordnen und das Attribut reversed umschalten
- Die Beispielfunktion wandelt das Ergebnis von
list.querySelectorAll('li') in ein Array um, ruft .reverse() auf, leert mit list.innerHTML = '' und hängt mit list.append(...children) erneut an
- Anschließend wird
list.toggleAttribute('reversed') aufgerufen
- Im Beispielereignis wird das Umdrehen per Doppelklick mit
orderedList.addEventListener('dblclick', (evt) => { reverseList(orderedList) }) ausgelöst
-
start
- Das Attribut
start dient dazu, die Nummernfolge beizubehalten, wenn man statt einer einzigen großen Liste mehrere geordnete Listen verwendet
- Im Beispiel zum Bananenbrot-Rezept bleibt
Prepare ein ul, während Mix mit <ol start=2>, Pour mit <ol start=5> und Cool mit <ol start=7> fortlaufende Schrittnummern erhalten
- Selbst wenn zwischendurch ein Abschnitt wie
6: Bake als ungeordnete Liste dargestellt wird, kann die spätere ol für Cool mit start=7 beginnen und so den Nummernfluss des Gesamtprozesses bewahren
Beschreibungslisten: <dl>, <dt>, <dd>
- Die Beschreibungsliste (description list) ist ein Listentyp, der verhindert, dass man alles zwanghaft in
ol oder ul pressen muss
-
Definitionslisten in HTML 4
- In HTML 4 hieß dies nicht
description list, sondern Definitionsliste (definition list) und war auf den engeren Zweck des Definierens ausgerichtet
- Die Struktur bestand aus dem zu definierenden Begriff
<dt> und dem Definitionstext <dd>; für semantisch exakte Verwendung wurde der definierte Begriff zusätzlich in <dfn> eingeschlossen
- Im Beispiel werden
throw und yeet mit derselben Definition verbunden, während no cap und bet jeweils eigene Definitionen erhalten
<dl>
<dt><dfn>throw</dfn></dt>
<dt><dfn>yeet</dfn></dt>
<dd>Verb. To discard at a high velocity</dd>
<dt><dfn>no cap</dfn></dt>
<dd>Interjection. Expresses authenticity and truthfulness, sometimes surprise.</dd>
<dt><dfn>bet</dfn></dt>
<dd>Interjection. Expresses agreement and affirmation.</dd>
</dl>
-
Erweiterte Bedeutung in HTML5
- In HTML5 wurde daraus eine Beschreibungsliste, die nicht mehr nur auf Definitionen beschränkt ist und verwendet werden kann, wenn es eine „Menge von Begriffen und Werten“ gibt
- In HTML5 ist ein nichtsemantischer Wrapper
<div> erlaubt, um zusammengehörige <dt>- und <dd>-Elemente zu gruppieren
- Im Beispiel zu Browser-Engines werden
Chrome, Opera, Brave, Edge unter Blink-based browsers gruppiert und Firefox, Tor, Librewolf unter Gecko-based browsers
<dl>
<div class="dl-item">
<dt>Chrome</dt>
<dt>Opera</dt>
<dt>Brave</dt>
<dt>Edge</dt>
<dd>Blink-based browsers</dd>
</div>
<div class="dl-item">
<dt>Firefox</dt>
<dt>Tor</dt>
<dt>Librewolf</dt>
<dd>Gecko-based browsers</dd>
</div>
</dl>
-
Metadaten und JSON-Debugging
- Wenn Inhalte eine Abfolge aus Fakten und Beschriftungen bilden, eignet sich eine Beschreibungsliste gut zur Darstellung von Metadaten
- Auch Benutzerprofile lassen sich in
<dl> ausdrücken; im Beispiel werden First Frank, Last Taylor, Age 44, Job Writer, Handle Paceaux als <dt>-/<dd>-Paare dargestellt
- Beschreibungsliste können in Single-Page-Applications auch zum JSON-Debugging verwendet werden
- Das Beispiel
DebugJson iteriert über die einzelnen key, value-Paare eines Objekts via Object.entries(obj) und rendert Schlüssel als <dt><var>...</var></dt> sowie Werte als <dd><code>...</code></dd>
- Wenn ein Wert ein Objekt und kein Array ist, wird
DebugJson.createDl(value) erneut aufgerufen, um ein verschachteltes <dl> zu erzeugen; andernfalls wird value.toString() in <code> eingesetzt
const debugJson = new DebugJson({foo: 'bar', arr: ['a', 'b'], car: 1}, '.container')
debugJson.render();
- Beschreibungsliste sind breit für Anforderungen mit Schlüssel-Wert-Paaren geeignet
Menüs: <menu>
- Das Element
menu steht für eine Liste von Befehlen und ist stärker auf interaktive Webanwendungen ausgerichtet als auf die Darstellung von Inhalten
menu eignet sich für Listen von Schaltflächen, die als „Werkzeuge“ dienen, etwa Textbearbeitungs-Steuerelemente in einem Rich-Text-Editor
- Im Beispiel für einen Rich-Text-Editor werden die Schaltflächen
Strong, Emphasize, Strike als li innerhalb eines menu platziert
<menu>
<li><button onclick="strong()">Strong</button></li>
<li><button onclick="emphasize()">Emphasize</button></li>
<li><button onclick="strike()">Strike</button></li>
</menu>
- Laut HTML-Spezifikation entspricht dies dem Zweck einer Toolbar, und überall dort, wo es auf interaktiven Seiten Werkzeugschaltflächen gibt, kommt häufig
menu in Frage
- Auch das Beispiel für Videosteuerung gehört in ein
menu; die button-Elemente tragen commandfor="vid-123" und command="--play", --mute, --fullscreen
<div class="player player--video">
<video source="whatever.mp4" id="vid-123"></video>
<menu>
<li><button commandfor="vid-123" command="--play">Play</button></li>
<li><button commandfor="vid-123" command="--mute">Mute</button></li>
<li><button commandfor="vid-123" command="--fullscreen">Fullscreen</button></li>
</menu>
</div>
Ungeordnete Listen: <ul>
ul ist die Auffangliste für alle übrigen Listenanforderungen, die nicht durch andere Listentypen oder nav abgedeckt sind
- In früherem HTML lag der Unterschied zwischen geordneten und ungeordneten Listen näher an einem visuellen Unterschied wie Zahlen versus Aufzählungszeichen
- Heute muss man Zugänglichkeit, Screenreader und Suchmaschinenoptimierung berücksichtigen; deshalb sollte man sich stärker darauf konzentrieren, ob Reihenfolge Bedeutung trägt, statt auf die visuelle Darstellung
- Die Liste der Bandmitglieder gehört in
ul, weil die Reihenfolge nicht wichtig ist
<h3>Beatles</h3>
<ul>
<li>John Lennon</li>
<li>Paul McCartney</li>
<li>Ringo Star</li>
<li>George Harrison</li>
</ul>
- Auch eine Liste von Bandnamen kann als ungeordnete Liste dargestellt werden
<ul>
<li>Beatles</li>
<li>Rolling Stones</li>
<li>Van Halen</li>
<li>Foo Fighters</li>
</ul>
1 Kommentare
Hacker-News-Kommentare
Schon beim Testen der Beispiele scheint datalist in Mobile Safari nicht ordentlich zu funktionieren
Wenn es in einem so großen Markt Kompatibilitätsprobleme gibt, könnte man fast sagen, dass es praktisch kaum sinnvolle Einsatzszenarien dafür gibt
Eine Info, die ich zwar nicht hören wollte, aber als kalte Dusche der Realität unbedingt gebraucht habe
Vor mehr als zehn Jahren habe ich an einem Projekt gearbeitet, das ein ziemlich aggressives Eingabevorschlags-Widget im UI nutzte, und damals haben wir dafür ein jQuery-Plugin verwendet
Das war der komplexeste Teil im Frontend und praktisch der Hauptgrund, warum wir in diesem Projekt jQuery überhaupt benutzt haben
Beim Lesen des Artikels dachte ich, es wäre kinderleicht, dieses Frontend als leichtgewichtige, minimierte JS-Version neu umzusetzen, aber in der Realität ist es eben nicht so, solange man nicht seine eigene Umgebung direkt auf das Gerät des Nutzers ausliefert
Trotzdem sind die Funktionen, die heute Teil der HTML-Spezifikation sind, ziemlich beeindruckend
Seit ich in der Schule mal XHTML gelesen habe, habe ich Änderungen an der Spezifikation kaum noch verfolgt, vielleicht sollte ich gelegentlich mal nachsehen, was sich verändert hat
Nur die Browser-Kompatibilität ist damals wie heute ein ständiger Schmerzpunkt
Das datalist-Beispiel funktioniert auf meinem iPhone definitiv
Es ist in den Bereich für Autovervollständigungsvorschläge über der nativen iOS-Tastatur integriert
Allerdings gibt es keine Möglichkeit, alle Vorschläge durchzublättern, und vermutlich ist das auch nicht die beabsichtigte Nutzung von datalist
Aber das Attribut
disabledvongroupfunktioniert definitiv nichtFunktioniert auch nicht in Firefox auf Android
Vor langer Zeit in meinem ersten Job funktionierte datalist in Firefox nicht, und deshalb wurde Firefox aus der Liste der unterstützten Browser gestrichen
Wenn man Browser jenseits von Chrome unterstützen will, ist das schon sehr lange ein problematisches Feature
Zusammen mit GBoard auf iOS funktioniert es nicht richtig
Das Beispiel, bei dem
disabledzuoptgrouphinzugefügt wird, damit einige Optionen nicht auswählbar sind, scheint in Mobile Safari kaputt zu seinIn der Praxis wird es nicht deaktiviert, und auch deaktivierte Einträge lassen sich weiterhin auswählen
In aktuellem Safari sollte es funktionieren, also ist es wohl nicht wirklich kaputt, sondern eher in einem seltsamen Zustand
https://caniuse.com/mdn-html_elements_optgroup_disabled
Sieht nach einem möglichen Safari-Bug aus
Genau deshalb ist es schwer, natives HTML für mehr als nur die einfachsten Dinge zu verwenden
Selbst wenn man genug liest und genug Vertrauen hat, um so einen Artikel zu schreiben, tauchen in den Kommentaren am Ende doch wieder die merkwürdigen Verhaltensweisen, Einschränkungen und fehlenden Unterstützungen je nach Browser- und Gerätekombination auf
Eine
div-Wüste ist vielleicht zu weit in die andere Richtung, aber wenigstens sind die Eigenheiten und Grenzen dort recht konsistent und sichtbarWeil es besser zu dem passt, was ich selbst geschrieben habe oder was das Framework erzeugt hat
Interessanter und umfassender Artikel
Leider gibt es heute viele Entwickler, die HTML nie lernen und direkt mit React einsteigen, und mit LLMs ist es noch wahrscheinlicher, dass HTML gar nicht erst gelernt wird
Deshalb sucht man selbst dort zuerst nach einer React-Komponente, wo simples HTML völlig ausreichen würde
Ich finde das trotzdem okay
Als ich zum ersten Mal XML verwenden musste, musste man noch die XML-Spezifikation lernen und alles selbst ausgeben
Serialisierungsbibliotheken gab es praktisch nicht
Später habe ich gesehen, wie jüngere Generationen XML und später JSON als Austauschformat nutzten, ohne es vollständig zu lernen, und das war auch kein Problem
AJAX ist ebenfalls vom heißen neuen Trend zu etwas geworden, bei dem viele nicht einmal mehr wissen, wofür die Abkürzung steht, und heute erkennen die meisten den Begriff selbst kaum noch
AJAX ist nicht gestorben, sondern einfach so alltäglich geworden, dass man kein eigenes Wort mehr dafür braucht
Mein Problem ist, dass ich HTML vor 20 Jahren sehr gründlich gelernt habe und seitdem nur zufällig in kleinen Dosen mitbekommen habe, wie es sich verändert und verbessert hat
Bei CSS gilt das noch mehr
Ehrlich gesagt ist HTML umständlich
Zum Beispiel ist der HTML-artige Ansatz, Teile eines Controls zu stylen, die Verwendung von Pseudoklassen, und je nach Browser unterscheiden sich die Selektoren sogar
Dann muss man browserweise testen, weil man sonst gar nicht weiß, ob es wirklich richtig funktioniert
React ist nicht nur einfacher, sondern auch verlässlicher
Wenn man es mit React und
div-Elementen baut, kann man erwarten, dass es in allen Browsern gleich funktioniertGuter Inhalt, aber man sollte von
datalistnicht zu viel erwartenFür wirklich nützliche Anwendungen fehlen Anknüpfungspunkte, daher taugt es kaum für mehr als kleine Prototypen
Ich frage mich, ob ein HTML-Linter wirklich hilft, solche Unterschiede zu erkennen
Mich würde auch interessieren, ob es einen Linter gibt, der diese Art von Auswahl semantischer Tags erzwingen kann
Dass semantische Tags erzwungen werden, leuchtet mir nicht wirklich ein
HTML ist vor allem dafür gedacht, dass Autoren es kreativ einsetzen, und es ergibt für mich keinen Sinn, bestimmte Tags gegenüber anderen zu erzwingen
Barrierefreiheit ist wichtig, aber Einschränkungen gibt es ohnehin schon mehr als genug
Das Nächste, das ich kenne, ist https://github.com/kristoff-it/superhtml#diagnostics
SuperHTML validiert nicht nur die Syntax, sondern auch die Verschachtelung von Elementen und Attributwerte
Es gibt keinen anderen Language Server, der die gesamte HTML-Spezifikation als Validierungscode implementiert
Heute neu gelernt
Ich frage mich, warum nicht mehr Frameworks das nutzen
Aus Sicht der User Experience ist es dasselbe wie eine normale Liste
Wenn es hilft, den Code zu verstehen, kann man es verwenden, aber im Accessibility Tree des Browsers und in jeder anderen Hinsicht ist es einfach nur eine ungeordnete Liste
Wenn man vermitteln will, dass es sich um eine Liste von Aktionen handelt, muss man ARIA-Attribute hinzufügen
Im Artikel wird
role=menuerwähnt, aber das allein reicht nicht aus, auch die einzelnen Einträge brauchen die RollemenuitemDer WAI Authoring Practices Guide erklärt Rollen und Erwartungen an die Interaktion, aber man sollte die Codebeispiele nicht einfach kopieren und diese Rollen insbesondere nicht für Navigationsmenüs verwenden
https://www.w3.org/WAI/ARIA/apg/patterns/menubar/
Clevere Leute lernen kein kompliziertes HTML, sondern lösen es einfach mit mehreren
div-ElementenHeutiges HTML hat viele interessante Funktionen
Ich frage Leute gern, was sie glauben, was bestimmte Elemente machen
Ich lag am Anfang auch komplett daneben
Ich habe mehrere Jahre als Frontend-Lead gearbeitet und trotzdem vieles davon nicht gewusst
Das werden wir im Unternehmen jetzt vermutlich definitiv ausprobieren
Es wäre schön, wenn Designer die Standard-Optik von datalist mögen würden
Der Blogpost ist wirklich gut, aber ich finde keine Möglichkeit, die komplette Liste aller Blogbeiträge auf einmal zu sehen
https://blog.frankmtaylor.com/archive funktioniert nicht
https://blog.frankmtaylor.com/archives auch nicht
https://blog.frankmtaylor.com/posts ebenfalls nicht
https://blog.frankmtaylor.com/all gibt es auch nicht
https://blog.frankmtaylor.com/blog ist es auch nicht
Da es viele Leute mit mehr als 10.000 Lesezeichen gibt, wäre eine einzelne Übersichtsseite, die einfach alle bisher geschriebenen Beiträge ohne Beschreibung oder vollständigen Text auflistet, wirklich praktisch
Meinst du nicht einfach eine Sitemap?
Die meisten Blogs haben ein
sitemap.xml, in dem alle Beiträge aufgelistet sindUnd ich frage mich auch, warum man überhaupt alle 235 Beiträge durchsehen möchte