CSS-Lesefluss für eine logische sequenzielle Fokusnavigation verwenden

Veröffentlicht: 1. Mai 2025

Die CSS-Attribute reading-flow und reading-order sind seit Chrome 137 verfügbar. In diesem Beitrag werden die Gründe für die Gestaltung dieser Properties erläutert und einige kurze Details zur Einführung gegeben.

Layoutmethoden wie „grid“ und „flex“ haben die Frontend-Entwicklung revolutioniert. Ihre Flexibilität kann jedoch für einige Nutzer ein Problem darstellen. Es ist sehr einfach, eine Situation zu schaffen, in der die visuelle Reihenfolge nicht mit der Quellreihenfolge im DOM-Baum übereinstimmt. Da der Browser dieser Quellreihenfolge folgt, wenn Sie die Website mit einer Tastatur bedienen, kann es bei einigen Nutzern zu unerwarteten Sprüngen kommen, wenn sie sich auf einer Seite bewegen.

Die Eigenschaften reading-flow und reading-order wurden entwickelt und der CSS-Displayspezifikation hinzugefügt, um dieses seit langem bestehende Problem zu lösen.

reading-flow

Mit der CSS-Property reading-flow wird die Reihenfolge gesteuert, in der Elemente in einem Flex-, Grid- oder Blocklayout für Tools zur Barrierefreiheit sichtbar sind und wie sie mithilfe linearer sequenzieller Navigationsmethoden fokussiert werden.

Es wird ein Keyword-Wert mit dem Standardwert normal verwendet, wodurch die Elemente in der DOM-Reihenfolge sortiert werden. Wenn Sie es in einem Flex-Container verwenden möchten, legen Sie den Wert auf flex-visual oder flex-flow fest. Wenn Sie es in einem Rastercontainer verwenden möchten, legen Sie den Wert auf grid-rows, grid-columns oder grid-order fest.

reading-order

Mit der CSS-Property reading-order kannst du die Reihenfolge der Elemente in einem Container für den Lesefluss manuell überschreiben. Wenn Sie diese Eigenschaft in einem Raster-, Flex- oder Blockcontainer verwenden möchten, legen Sie den Wert „reading-flow“ für den Container auf „source-order“ und den Wert „reading-order“ für das einzelne Element auf einen Ganzzahlwert fest.

Beispiel in Flexbox

Angenommen, Sie haben einen Flex-Layout-Container mit drei Elementen in umgekehrter Zeilenreihenfolge und möchten die Reihenfolge mithilfe der Eigenschaft „order“ neu anordnen.

<div class="box">
 <a href="#">One</a>
 <a href="#">Two</a>
 <a href="#">Three</a>
</div>
.box {
  display: flex;
  flex-direction: row-reverse;
}

.box :nth-child(1) {
  order: 2;
}

Sie können versuchen, mit der TAB-Taste zum nächsten und mit TAB + UMSCHALT zum vorherigen Element zu wechseln. Dabei werden die Elemente in der Quellreihenfolge aufgeführt: Eins, Zwei, Drei.

Aus Sicht der Endnutzer macht das keinen Sinn und kann sehr verwirrend sein. Dasselbe passiert, wenn wir ein Tool zur Raumnavigation für Barrierefreiheit verwenden, um uns auf der Seite zu bewegen.

So beheben Sie das Problem:reading-flow

.box {
  reading-flow: flex-visual;
}

Die Fokusreihenfolge ist jetzt: Eins, Drei, Zwei. Das entspricht der visuellen Reihenfolge, die Sie erhalten würden, wenn Sie Englisch von links nach rechts lesen.

Wenn Sie die Fokusreihenfolge stattdessen in umgekehrter Reihenfolge beibehalten möchten, können Sie Folgendes festlegen:

.box {
  reading-flow: flex-flow;
}

Die Reihenfolge des Fokus ist jetzt die umgekehrte Flex-Reihenfolge: Zwei, Drei, Eins. In beiden Fällen wird die CSS-Property order berücksichtigt.

Beispiel mit Rasterlayout

Um zu sehen, wie das in einem Raster funktioniert, stellen Sie sich vor, Sie erstellen ein Layout mit automatisch platzierten Elementen im CSS-Raster mit zwölf fokussierbaren Bereichen.

<div class="wrapper">
 <a href="#">One</a>
 <a href="#">Two</a>
 <a href="#">Three</a>
 <a href="#">Four</a>
 <a href="#">Five</a>
 <a href="#">Six</a>
 <a href="#">Seven</a>
 <a href="#">Eight</a>
 <a href="#">Nine</a>
 <a href="#">Ten</a>
 <a href="#">Eleven</a>
 <a href="#">Twelve</a>
</div>

Das fünfte Kind soll den größten Bereich ganz oben einnehmen, gefolgt vom zweiten Kind in der Mitte des Rasters. Alle anderen untergeordneten Elemente können automatisch im Raster gemäß einer Spaltenvorlage platziert werden.

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
}
.wrapper a:nth-child(2) {
  grid-column: 3;
  grid-row: 2 / 4;
}
.wrapper a:nth-child(5) {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}

Versuchen Sie, mit der Tabulatortaste zum nächsten und mit Tabulatortaste + Umschalttaste zum vorherigen Element zu wechseln. Die Elemente werden in der Quellreihenfolge aufgeführt: Eins bis Zwölf.

So beheben Sie das Problem:reading-flow

.wrapper {
  reading-flow: grid-rows;
}

Die Fokusreihenfolge lautet jetzt: Fünf, Eins, Drei, Zwei, Vier, Sechs, Sieben, Acht, Neun, Zehn, Elf, Zwölf. Die Reihenfolge folgt der visuellen Reihenfolge, Zeile für Zeile.

Wenn der Lesefluss stattdessen der Spaltenreihenfolge folgen soll, können Sie stattdessen das Keyword grid-columns verwenden. Die Fokusreihenfolge lautet dann Fünf, Sechs, Neun, Sieben, Zehn, Eins, Zwei, Elf, Drei, Vier, Acht, Zwölf.

.wrapper {
  reading-flow: grid-columns;
}

Du kannst es aber auch mit grid-order versuchen. Die Reihenfolge der Fokuspunkte bleibt unverändert (1 bis 12). Das liegt daran, dass für keinen Artikel eine Preisvergleichsportal-Bestellung festgelegt wurde.

Blockcontainer mit reading-order

Mit der Property reading-order können Sie angeben, wann ein Element im Lesefluss besucht werden soll. Dadurch wird die Reihenfolge überschrieben, die mit der Property reading-flow festgelegt wurde. Sie wird nur auf einen gültigen Container für den Lesefluss angewendet, wenn das reading-flow-Attribut nicht normal ist.

.wrapper {
  display: block;
  reading-flow: source-order;
}

.top {
  reading-order: -1;
  inset-inline-start: 50px;
  inset-block-start: 50px;
}

Der folgende Blockcontainer enthält fünf Elemente. Es gibt keine Layoutregeln, die die Elemente aus ihrer Quellreihenfolge neu anordnen. Es gibt jedoch ein Element außerhalb des Fluss, das zuerst besucht werden sollte.

<div class="wrapper">
  <a href="#">Item 1</a>
  <a href="#">Item 2</a>
  <a href="#">Item 3</a>
  <a href="#">Item 4</a>
  <a class="top" href="#">Item 5</a>
</div>

Wenn Sie die reading-order dieses Elements auf -1 festlegen, wird es zuerst in der Fokusreihenfolge besucht, bevor für die restlichen Elemente des Leseflusses auf die Quellreihenfolge zurückgegriffen wird.

Weitere Beispiele finden Sie auf der chrome.dev-Website.

Interaktion mit tabindex

Bisher haben Entwickler das globale HTML-Attribut tabindex verwendet, um HTML-Elemente fokussierbar zu machen und die relative Reihenfolge für die sequenzielle Fokusnavigation zu bestimmen. Dieses Attribut hat jedoch viele Nachteile und Probleme in Bezug auf die Barrierefreiheit. Das Hauptproblem besteht darin, dass die Fokusnavigation, die durch die Verwendung eines positiven Tabindex-Attributs erstellt wurde, vom Baum für Barrierefreiheit nicht erkannt wird. Bei falscher Verwendung kann es zu einer unregelmäßigen Fokusreihenfolge kommen, die nicht mit der Darstellung in einem Screenreader übereinstimmt. Verwenden Sie dazu das HTML-Attribut „aria-owns“.

Im vorherigen Flex-Beispiel können Sie Folgendes tun, um dasselbe Ergebnis wie mit reading-flow: flex-visual zu erzielen:

<div class="box" aria-owns="one three two">
  <a href="#" tabindex="1" id="one">One</a>
  <a href="#" tabindex="3" id="two">Two</a>
  <a href="#" tabindex="2" id="three">Three</a>
</div>

Was passiert aber, wenn ein anderes Element außerhalb des Containers auch tabindex=1 hat? Anschließend werden alle Elemente mit tabindex=1 gemeinsam besucht, bevor wir zum nächsten inkrementellen Tabindex-Wert übergehen. Diese unruhige sequenzielle Navigation führt zu einer schlechten Nutzererfahrung. Daher empfehlen Experten für Barrierefreiheit, positive Werte für „tabindex“ zu vermeiden. Wir haben versucht, dieses Problem beim Entwerfen von reading-flow zu beheben.

Ein Container, für den das Attribut reading-flow festgelegt ist, wird zum Inhaber des Fokusbereichs. Das bedeutet, dass die sequenzielle Fokusnavigation so festgelegt wird, dass jedes Element im Container besucht wird, bevor zum nächsten fokussierbaren Element in einem Webdokument gewechselt wird. Außerdem werden seine direkten untergeordneten Elemente anhand des Attributs „reading-flow“ sortiert und positive Tabindex-Werte werden für die Sortierung ignoriert. Für die Nachkommen eines Elements mit Lesefluss kann weiterhin ein positiver Tabindex festgelegt werden.

Hinweis: Ein Element mit display: contents, das die Property reading-flow von seinem übergeordneten Layout erbt, ist ebenfalls ein gültiger Lesefluss-Container. Berücksichtigen Sie dies beim Entwerfen Ihrer Website. Weitere Informationen dazu finden Sie in unserem Feedback-Anfrage zu reading-flow und display: contents.

Geben Sie uns Feedback

Probieren Sie die Beispiele in diesem Beitrag und in den reading-flowBeispielen auf chrome.dev aus und verwenden Sie diese CSS-Eigenschaften auf Ihren Websites. Wenn Sie Feedback haben, können Sie es im GitHub-Repository der CSS-Arbeitsgruppe als Problem melden. Wenn Sie Feedback speziell zum Tabindex und zum Verhalten der Fokussierung haben, können Sie es als Problem im HTML WHATNOT GitHub-Repository melden. Wir würden uns sehr über Feedback zu dieser Funktion freuen.