HTML-Listen sind langweilig. Sie tun nicht viel, deshalb denken wir nicht wirklich über sie nach, obwohl sie so weit verbreitet sind. Und wir können immer noch die gleichen Dinge tun, die wir schon immer getan haben, um sie anzupassen, wie z. B. Marker entfernen, die Reihenfolge umkehren und benutzerdefinierte Zähler erstellen.
Es gibt jedoch ein paar „neuere“ Dinge – einschließlich Gefahren –, die man bei der Verwendung von Listen wissen sollte. Die Gefahren sind meist geringfügig, aber weitaus häufiger, als Sie vielleicht denken. Wir werden uns damit befassen, sowie mit einigen neuen Dingen, die wir mit Listen tun können, und sogar mit neuen Wegen, alte Lösungen anzugehen.
Zur Klarstellung, dies sind die HTML-Elemente, über die wir sprechen
- Geordnete Listen
<ol> - Ungeordnete Listen
<ul> - Beschreibungslisten
<dl> - Interaktive Listen
<menu>
Geordnete Listen, ungeordnete Listen und interaktive Listen enthalten Listenelemente (<li>), die je nach Art der Liste angezeigt werden. Eine geordnete Liste (<ol>) zeigt Zahlen neben den Listenelementen an. Ungeordnete Listen (<ul>) und Menüelemente (<menu>) zeigen Aufzählungspunkte neben den Listenelementen an. Wir nennen diese „Listenmarker“ und sie können sogar mit der ::marker-Pseudoklasse gestylt werden. Beschreibungslisten verwenden Beschreibungsterme (<dt>) und Beschreibungsdetails (<dd>) anstelle von <li> und haben keine Listenmarker. Sie sollen Metadaten und Glossare anzeigen, aber ich habe sie noch nie in der Praxis gesehen.
Beginnen wir mit den einfachen Dingen – wie man Listenelemente korrekt (zumindest meiner Meinung nach) zurücksetzt. Danach werfen wir einen Blick auf ein paar Barrierefreiheitsprobleme, bevor wir das schwer fassbare <menu>-Element beleuchten, das Sie vielleicht überraschen wird… es ist tatsächlich auch eine Art Liste!
Listenelemente zurücksetzen
Browser wenden automatisch ihre eigenen User-Agent-Stile an, um die visuelle Struktur von Listen sofort zu unterstützen. Das kann großartig sein! Aber wenn wir mit einer leeren Leinwand beginnen wollen, die frei von Styling-Vorgaben ist, müssen wir diese Stile zuerst zurücksetzen.
Zum Beispiel können wir die Marker neben den Listenelementen ziemlich einfach entfernen. Nichts Neues hier
/* Zap all list markers! */
ol, ul, menu {
list-style: none;
}
Aber modernes CSS bietet neue Möglichkeiten, um spezifische Listeninstanzen zu isolieren. Nehmen wir an, wir möchten Marker von allen Listen entfernen, es sei denn, diese Listen erscheinen in langformigen Inhalten, wie z. B. einem Artikel. Wenn wir die Leistung der neueren CSS-Pseudoklassenfunktionen :where() und :not() kombinieren, können wir diese Fälle isolieren und die Marker in diesen Fällen zulassen.
/* Where there are lists that are not articles where there are lists... */
:where(ol, ul, menu):not(article :where(ol, ul, menu)) {
list-style: none;
}
Warum :where() anstelle von :is() verwenden? Die Spezifität von :where() ist immer null, während :is() die Spezifität des spezifischsten Elements in seiner Selektorliste übernimmt. Daher ist die Verwendung von :where() eine weniger aufdringliche Methode, Dinge zu überschreiben, und kann selbst leicht überschrieben werden.
UA-Stile wenden auch einen Innenabstand an, um den Inhalt eines Listenelements vom Marker zu trennen. Auch das ist in einigen Fällen eine ziemlich gute Anpassung ab Werk, aber wenn wir die Listenmarker bereits entfernen, wie wir es oben getan haben, können wir auch diesen Innenabstand entfernen. Dies ist ein weiterer Fall für :where().
:where(ol, ul, menu) {
padding-left: 0; /* or padding-inline-start */
}
OK, das verhindert, dass markerlose Listenelemente im leeren Raum schweben. Aber wir haben irgendwie das Kind mit dem Bade ausgeschüttet und den Innenabstand in allen Fällen entfernt, auch in denen, die wir zuvor in einem <article> isoliert hatten. Jetzt hängen diese Listen mit Markern irgendwie am Rand der Inhaltsbox.
Beachten Sie, dass UA-Stile dem <menu>-Element zusätzliche 40px zuweisen.
Was wir also tun wollen, ist zu verhindern, dass die Listenmarker aus dem Container „herausragen“. Wir können dies mit der Eigenschaft list-style-position beheben.
Oder auch nicht… vielleicht kommt es auf die stilistische Vorliebe an?
Neuere Barrierefreiheitsprobleme mit Listen
Leider gibt es ein paar Barrierefreiheitsprobleme bei Listen – auch in diesen moderneren Zeiten. Ein Problem ist das Ergebnis der Anwendung von list-style: none;, wie wir es beim Zurücksetzen von UA-Stilen getan haben.
Kurz gesagt, Safari liest geordnete und ungeordnete Listen, die mit list-style: none gestylt sind, nicht als tatsächliche Listen vor, wenn man mit einem Screenreader durch Inhalte navigiert. Mit anderen Worten, das Entfernen der Marker entfernt auch die semantische Bedeutung der Liste. Die Behebung dieses Problems besteht darin, der Liste eine ARIA-list-Rolle und den Listenelementen eine listitem-Rolle zuzuweisen, damit Screenreader sie erkennen.
<ol style="list-style: none;" role="list">
<li role="listItem">...</li>
<li role="listItem">...</li>
<li role="listItem">...</li>
</ol>
<ul style="list-style: none;" role="list">
<li role="listItem">...</li>
<li role="listItem">...</li>
<li role="listItem">...</li>
</ul>
Seltsamerweise betrachtet Safari dies als ein Feature und nicht als einen Fehler. Im Grunde meldeten Benutzer, dass Screenreader zu viele Listen ansagten (da Entwickler dazu neigen, sie zu überstrapazieren), sodass jetzt nur noch die mit role="list" von Screenreadern angesagt werden, was eigentlich gar nicht so seltsam ist. Scott O’Hara hat eine detaillierte Zusammenfassung, wie alles ablief.
Ein zweites Barrierefreiheitsproblem ist nicht unser eigenes Verschulden (hurra!). Sie wissen also, wie man einem <section>-Element ohne Überschrift eine aria-label hinzufügt. Nun, es ist manchmal sinnvoll, dasselbe mit einer Liste zu tun, die kein Überschriftenelement enthält, das die Liste beschreibt.
<!-- This list is somewhat described by the heading -->
<section>
<h2>Grocery list</h2>
<ol role="list">
<!-- ... -->
</ol>
</section>
<!-- This list is described by the aria-label -->
<ol role="list" aria-label="Grocery list">
<!-- ... -->
</ol>
Sie müssen keine der beiden Methoden verwenden. Die Verwendung einer Überschrift oder eines ARIA-Labels ist nur ein zusätzlicher Kontext, keine Anforderung – testen Sie Ihre Websites mit Screenreadern und tun Sie, was die beste Benutzererfahrung für die Situation bietet.
In einem etwas verwandten Zusammenhang hat Eric Bailey einen ausgezeichneten Artikel darüber verfasst, warum und wie er aria-label als Code-Smell betrachtet.
Moment, <menu> ist auch eine Liste?
Okay, Sie fragen sich wahrscheinlich, was es mit all den <menu>-Elementen auf sich hat, die ich in die Codebeispiele eingeschleust habe. Es ist eigentlich ganz einfach; Menüs sind ungeordnete Listen, außer dass sie für interaktive Elemente gedacht sind. Sie werden sogar als ungeordnete Listen im Barrierefreiheitsbaum dargestellt.
In den Anfängen des semantischen Webs glaubte ich fälschlicherweise, dass Menüs wie <nav> seien, bevor ich glaubte, dass sie für Kontextmenüs (oder „Werkzeugleisten“, wie es in der Spezifikation heißt) seien, da dies die frühen Versionen der HTML-Spezifikation sagten. (MDN hat einen interessanten Beitrag zu all den veralteten Dingen im Zusammenhang mit <menu>, wenn Sie daran interessiert sind.)
Heute ist das die semantische Art, Menüs zu verwenden.
<menu aria-label="Share article">
<li><button>Email</button></li>
<li><button>Twitter</button></li>
<li><button>Facebook</button></li>
</menu>
Persönlich denke ich, dass es einige gute Anwendungsfälle für <menu> gibt. Das letzte Beispiel zeigt eine Liste von Social-Sharing-Buttons, die in ein beschriftetes <menu>-Element eingeschlossen sind. Das Bemerkenswerte ist, dass die Beschriftung „Artikel teilen“ einen erheblichen Kontextbeitrag leistet, der beschreibt, was die Buttons tun.
Sind Menüs unbedingt notwendig? Nein. Sind sie HTML-Landmarken? Definitiv nicht. Aber sie sind da, wenn Sie weniger <div>s mögen und das Gefühl haben, dass die Komponente eine aria-label für zusätzlichen Kontext benötigt.
Sonst noch was?
Ja, es gibt auch das bereits erwähnte <dl> (Beschreibungsliste)-Element, aber MDN scheint es nicht auf die gleiche Weise als Liste zu betrachten – es ist eine Liste von Gruppen, die Begriffe enthalten –, und ich muss sagen, dass ich sie noch nie wirklich benutzt gesehen habe. Laut MDN sollen sie für Metadaten, Glossare und andere Arten von Schlüssel-Wert-Paaren verwendet werden. Ich würde sie einfach meiden, da alle Screenreader sie unterschiedlich ansagen.
Aber lassen Sie uns die Dinge nicht mit einer negativen Note beenden. Hier ist eine Liste von supercoolen Dingen, die Sie mit Listen tun können.
- Erstellen Sie ein Inhaltsverzeichnis
- Visualisieren Sie eine Zeitleiste von Ereignissen
- Konvertieren Sie eine Liste in eine horizontale, durch Kommas getrennte Liste
- Gestalten Sie den Marker (Ich persönlich mag das nicht, aber es ist trotzdem irgendwie cool)
Ich benutze schon seit 20 Jahren
<dl>-Listen. Es ist üblich, dass professionelle Entwickler den vollständigen Katalog von HTML-Tags nutzen und sich nicht an 4-5 bekannte Tags halten und nicht bereit sind, ihren Geist für die riesige, wunderschöne Bandbreite semantischer Möglichkeiten zu erweitern.<dl>-Listen sind praktisch für Listen mit Titeln pro Element, wie z. B. FAQ-Bereiche.Ich habe
<dl>auch verwendet, um Tabs zu markieren. Ich bin mir nicht sicher, wie a11y-konform das war, aber es fühlte sich ziemlich semantisch an.Für FAQs habe ich sie verwendet, und da einige Antworten auf Fragen zu lang sind, um sie alle im Browser geöffnet zu lassen, wenn die Seite angezeigt wird.
Moment, was ist also der Unterschied zwischen diesen beiden Beispielen in der Praxis? Ich vermute, ich bin wie viele Leute, die nicht wussten, dass
<menu>existiert, und ich versuche immer noch, es zu verstehen.Vielen Dank für das Schreiben dieses Artikels!
Nur ein Gedanke...
Alles kann eine Liste sein.
Wenn wir sowieso die eingebauten Stile von
ul,olundlirückgängig machen, warum nicht benutzerdefinierte Elemente verwenden?Pragmatisch gesehen, was würde mehr Styling erfordern? Was wäre DRYer für wiederverwendbare Komponenten?
Fühlt sich an wie das Abhängigkeitsargument bei Microservices. In dem Moment, in dem wir eine Abhängigkeit nutzen, begrenzen wir uns auf ihre Grenzen und verbringen (eventuell, wenn nicht sofort) mehr Zeit damit, sie zu umgehen.
Praktisch gesehen nicht viel.
<menu>ist semantischer, wenn man Buttons verwendet (im Gegensatz zu Links), da es eine Liste interaktiver Elemente anzeigen soll. In einer idealen Welt würden Suchmaschinen sie ignorieren (oder vielleicht tun sie das bereits) und Screenreader würden sie anders und konsistent ansagen. Meiner Meinung nach schadet es nicht, sie zu verwenden.Ja Daniel, es „fühlt“ sich in einigen Fällen definitiv semantischer an, aber ich war ein wenig irritiert von der Aussage im Artikel „Sie werden sogar als ungeordnete Listen im Barrierefreiheitsbaum dargestellt“. Ich dachte: „Unterscheidet der Browser überhaupt zwischen diesen Dingen?“.
Entschuldige Glenn, ich hätte klarer sein sollen.
<menu>s sind ungeordnet, aber nicht dasselbe wie<ul>s, wenn das Sinn macht? Screenreader lesen sie als Menüs vor, im Gegensatz zu<dl>s, die bei Screenreadern eher inkonsistent sind.Ich verstehe. Danke für die Klarstellung Daniel.
Ich habe darüber nachgedacht, ob dl nicht sinnvoll für Metadaten mit 1 Schlüssel zu vielen Werten sein könnte, wie z. B. Tags: foo bar, Kategorie: Baz, Autor: gaz.
Aber ich bin mir nicht sicher.
Ich glaube, dass Menü vielleicht nur in einer Nicht-App-Website für Formulare nützlich ist.
Ich glaube, dass 90% der Zeit
aria-labelledbyaria-labelvorzuziehen ist.Hier sind ein oder zwei
<dl>in Aktion für Sie.https://atomicarchive.com/resources/documents/effects/glasstone-dolan/glossary.html
https://meyerweb.com/eric/css/
Beide großartige Beispiele!
Wirklich schönes Tutorial.
Danke
Die meisten Websites, die ich besuche, um neue Dinge über Webentwicklung zu lernen, stehen <dl> für Definition List und für Definition Term. Was ich wissen möchte, ist, ob sie synonym mit Description List und Term sind?
Offiziell heißen sie Beschreibungslisten.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
Ich denke, Definition List ist nur ein verbreiteter Irrtum.
Die Spezifikation für
<dl>wurde geändert. Früher hieß siedefinition list, als sie für Glossare gedacht war. Nachdem die Anwendungsfälle erweitert wurden, wurde sie indescription listgeändert.Ein paar Anmerkungen (dies ist eine Liste mit 4 Elementen, aber CSS-Tricks frisst die Aufzählungszeichen, ironischerweise für diesen Beitrag).
Wahrscheinlich keine ARIA-Listenrollen für Safari/VO-Benutzer hinzufügen, es sei denn, die Benutzer selbst geben an, dass sie diese wünschen.
Wahrscheinlich keine
aria-labelzu<section>-Elementen hinzufügen, es sei denn, Sie möchten, dass ein<section>eine Region ist, in diesem Fallaria-labelledbyverwenden, um auf die Überschrift zu verweisen (die Sie hätten hinzufügen sollen).Das
<menu>-Element wird als ungeordnete Liste dargestellt; keine unterschiedlichen Barrierefreiheits-APIs, keine unterschiedlichen Plattform-APIs, nichts Unterschiedliches im Browser. Sie können<menu>sicher ignorieren, es sei denn, Sie bevorzugen es als Entwickler.Beschreibungslisten werden tatsächlich unterschiedlich über Browser- und Screenreader-Kombinationen angesagt, aber die Unterstützung für
<dl>ist generell gut (mit Safari als Ausreißer), auch wenn Ihnen vielleicht nicht gefällt, *wie* sie unterstützt wird.„Wir können das mit der Eigenschaft list-style-position beheben“ .. Wenn Sie
list-style-position: inside;verwenden, dehnt sich der Inhalt der Listenelemente bei mehreren Zeilen bis ganz nach links aus. Meiner Meinung nach wäre es viel besser, einfach den Innenabstand dafür anzuwenden und die Position auf Standard zu lassen.https://codepen.io/Azragh/pen/abKgNez