Data di pubblicazione: 1° maggio 2025
Le proprietà CSS reading-flow
e reading-order
sono disponibili a partire da Chrome 137.
Questo post spiega i motivi alla base del design di queste proprietà e alcuni dettagli brevi per iniziare a utilizzarle.
Metodi di layout come grid e flex hanno trasformato lo sviluppo frontend, tuttavia la loro flessibilità può causare un problema per alcuni utenti. È molto facile creare una situazione in cui l'ordine visivo non corrisponde all'ordine dell'origine nell'albero DOM. Poiché questo ordine delle origini è quello seguito dal browser se navighi nel sito utilizzando una tastiera, alcuni utenti potrebbero riscontrare salti imprevisti mentre navigano in una pagina.
Le proprietà reading-flow
e reading-order
sono state progettate e aggiunte alla specifica CSS Display per provare a risolvere questo problema di lunga data.
reading-flow
La proprietà CSS reading-flow
controlla l'ordine in cui gli elementi in un layout flessibile, a griglia o a blocchi vengono esposti agli strumenti di accessibilità e il modo in cui vengono attivati utilizzando metodi di navigazione sequenziale lineari.
Accetta un valore di parola chiave, con un valore predefinito di normal
, che mantiene il comportamento di ordinamento degli elementi nell'ordine DOM.
Per utilizzarlo all'interno di un contenitore flessibile, imposta il valore su flex-visual
o
flex-flow
. Per utilizzarlo all'interno di un contenitore della griglia, imposta il valore su
grid-rows
, grid-columns
o grid-order
.
reading-order
La proprietà CSS reading-order
ti consente di eseguire manualmente l'override dell'ordine degli elementi all'interno di un contenitore del flusso di lettura. Per utilizzare questa proprietà all'interno di un contenitore di tipo grid, flex o blocco, imposta il valore reading-flow
del contenitore su source-order
e imposta reading-order
del singolo elemento su un valore intero.
Esempio in flexbox
Ad esempio, potresti avere un contenitore con layout flessibile con tre elementi in ordine inverso delle righe e voler utilizzare la proprietà order per rimescolare l'ordine.
<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;
}
Puoi provare a navigare tra questi elementi utilizzando il tasto TAB per trovare l'elemento acquisibile successivo e i tasti TAB+MAIUSC per trovare l'elemento acquisibile precedente. Seguono gli articoli nell'ordine originale: Uno, Due, Tre.
Dal punto di vista dell'utente finale, questo non ha senso e può essere molto confusionario. Lo stesso accade se utilizziamo uno strumento di navigazione spaziale per l'accessibilità per spostarci nella pagina.
Per risolvere il problema, imposta la proprietà reading-flow
:
.box {
reading-flow: flex-visual;
}
L'ordine di messa a fuoco ora è: Uno, Tre, Due. È lo stesso ordine visivo che otterresti se leggessi in inglese da sinistra a destra.
Se invece preferisci mantenere l'ordine di attivazione come previsto inizialmente, in ordine inverso, puoi impostare:
.box {
reading-flow: flex-flow;
}
L'ordine di messa a fuoco ora è l'ordine flex inverso: Due, Tre, Uno. In entrambi i casi, viene presa in considerazione la proprietà CSS order
.
Esempio con layout a griglia
Per capire come funziona in una griglia, immagina di creare un layout con elementi posizionati automaticamente in una griglia CSS con dodici aree attivabili.
<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>
Il quinto elemento figlio deve occupare lo spazio più grande in alto, seguito dal secondo elemento figlio verso la metà della griglia. Tutti gli altri elementi secondari possono essere inseriti automaticamente all'interno della griglia seguendo un modello di colonna.
.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;
}
Prova a spostarti tra questi elementi utilizzando il tasto TAB per trovare l'elemento successivo acquisibile e i tasti TAB+Maiusc per trovare l'elemento acquisibile precedente. Seguono gli articoli nell'ordine originale: da 1 a 12.
Per risolvere il problema, imposta la proprietà reading-flow
:
.wrapper {
reading-flow: grid-rows;
}
L'ordine di messa a fuoco ora è: Cinque, Uno, Tre, Due, Quattro, Sei, Sette, Otto, Nove, Dieci, Undici, Dodici. Segue l'ordine visivo, riga per riga.
Se vuoi che il flusso di lettura segua l'ordine delle colonne, puoi utilizzare il valore della parola chiave grid-columns
. L'ordine di messa a fuoco diventa Cinque,
Sei, Nove, Sette, Dieci, Uno, Due, Undici, Tre, Quattro, Otto, Dodici.
.wrapper {
reading-flow: grid-columns;
}
Puoi anche provare a utilizzare grid-order
. L'ordine di messa a fuoco rimane da 1 a 12.
Questo perché non è stato impostato alcun ordine CSS per nessun articolo.
Un contenitore di blocchi che utilizza reading-order
La proprietà reading-order
consente di specificare quando nel flusso di lettura un elemento deve essere visitato, sostituendo l'ordine impostato dalla proprietà reading-flow
. Ha effetto solo su un contenitore del flusso di lettura valido, quando la proprietà reading-flow
non è normal
.
.wrapper {
display: block;
reading-flow: source-order;
}
.top {
reading-order: -1;
inset-inline-start: 50px;
inset-block-start: 50px;
}
Il seguente contenitore di blocchi contiene cinque elementi. Non esistono regole di layout che riordinano gli elementi dall'ordine di origine, ma è presente un elemento fuori flusso che deve essere visitato per primo.
<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>
Se imposti reading-order
su -1
per questo elemento, l'ordine di messa a fuoco lo visita prima
prima di tornare all'ordine di origine per il resto degli elementi del flusso di lettura.
Puoi trovare altri esempi sul sito chrome.dev.
Interazione con tabindex
In passato, gli sviluppatori utilizzavano l'attributo globale HTML tabindex
per rendere gli elementi HTML accessibili e determinare l'ordine relativo per la navigazione sequenziale con il fuoco. Tuttavia, questo attributo presenta molti svantaggi e problemi di accessibilità. Il problema principale è che la navigazione con il fuoco in ordine di tabindex creata utilizzando un valore tabindex positivo non è riconosciuta dall'albero di accessibilità. Se usato in modo errato, potresti ritrovarti con un ordine di attivazione discontinuo che non corrisponde all'esperienza su uno screen reader. Per risolvere il problema, monitora l'ordinamento utilizzando l'attributo HTML aria-owns.
Nell'esempio di flex precedente, per ottenere lo stesso risultato dell'utilizzo di
reading-flow: flex-visual
, puoi procedere nel seguente modo.
<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>
Ma cosa succede se un altro elemento esterno al contenitore ha anche tabindex=1
?
Successivamente, tutti gli elementi con tabindex=1
verranno visitati insieme, prima di passare al valore tabindex incrementale successivo. Questa navigazione sequenziale discontinua
porterà a un'esperienza utente negativa. Pertanto, gli esperti di accessibilità consigliano di evitare valori positivi per tabindex. Abbiamo provato a risolvere il problema durante la progettazione di reading-flow
.
Un contenitore con la proprietà reading-flow
impostata diventa un proprietario dell'ambito di attenzione.
Ciò significa che l'ambito della navigazione sequenziale dello stato attivo è visitare ogni elemento all'interno del contenitore prima di passare all'elemento attivabile successivo in un documento web. Inoltre, i relativi elementi secondari diretti sono ordinati utilizzando la proprietà reading-flow e gli elementi con tabindex positivo vengono ignorati ai fini dell'ordinamento. È ancora possibile impostare un valore tabindex positivo sui discendenti di un elemento del flusso di lettura.
Tieni presente che un elemento con display: contents
che eredita la proprietà reading-flow
dal layout principale sarà anche un contenitore del flusso di lettura valido. Tienilo presente quando progetti il tuo sito. Scopri di più nella nostra richiesta di feedback su reading-flow
e display: contents
.
Contattaci
Prova gli esempi in questo post e negli
reading-flow
esempi su chrome.dev e utilizza queste proprietà CSS
sui tuoi siti. Se hai un feedback, segnalalo come problema nel
repo GitHub del gruppo di lavoro CSS. Se hai un feedback specifico sul comportamento di ambito di tabindex e focus, segnalalo come problema nel repo GitHub HTML WHATNOT. Saremo lieti di ricevere il tuo feedback su questa funzionalità.