Publicado em 1º de maio de 2025
As propriedades CSS reading-flow
e reading-order
estão disponíveis a partir do Chrome 137.
Esta postagem explica os motivos por trás do design dessas propriedades e alguns
detalhes para você começar a usá-las.
Métodos de layout, como grade e flex, transformaram o desenvolvimento de front-end, mas a flexibilidade deles pode causar problemas para alguns usuários. É muito fácil criar uma situação em que a ordem visual não corresponde à ordem de origem na árvore DOM. Como essa ordem de origem é a que o navegador segue se você navegar pelo site usando um teclado, alguns usuários podem encontrar saltos inesperados ao navegar por uma página.
As propriedades reading-flow
e reading-order
foram projetadas e adicionadas à
especificação de
exibição do CSS para tentar
resolver esse problema de longa data.
reading-flow
A propriedade CSS reading-flow
controla a ordem em que os elementos em um layout flexível, de grade
ou de bloco são expostos às ferramentas de acessibilidade e como eles são focados
usando métodos de navegação sequencial linear.
Ele usa um valor de palavra-chave, com um
padrão de normal
, que mantém o comportamento de ordenar elementos na ordem do DOM.
Para usá-lo em um contêiner flexível, defina o valor como flex-visual
ou
flex-flow
. Para usá-lo em um contêiner de grade, defina o valor como
grid-rows
, grid-columns
ou grid-order
.
reading-order
A propriedade CSS reading-order
permite que você substitua manualmente a ordem dos
itens em um contêiner de fluxo de leitura. Para usar essa propriedade em um contêiner de grade, flex ou
bloco, defina o valor reading-flow
no contêiner como
source-order
e defina o reading-order
do item individual como um valor inteiro.
Exemplo em flexbox
Por exemplo, você pode ter um contêiner de layout flexível com três elementos na ordem inversa das linhas e também querer usar a propriedade de ordem para reorganizar essa ordem.
<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;
}
Você pode navegar por esses elementos usando a tecla TAB para encontrar o próximo elemento focalizável e as teclas TAB+SHIFT para encontrar o elemento focalizável anterior. Isso segue os itens na ordem da fonte: Um, Dois, Três.
Do ponto de vista do usuário final, isso não faz sentido e pode ser muito confuso. O mesmo acontece se usarmos uma ferramenta de navegação espacial de acessibilidade para navegar pela página.
Para corrigir isso, defina a propriedade reading-flow
:
.box {
reading-flow: flex-visual;
}
A ordem de foco agora é: Um, Três, Dois. Essa é a mesma ordem visual que você teria se estivesse lendo em inglês da esquerda para a direita.
Se você preferir manter a ordem de foco como foi originalmente, na ordem inversa, defina:
.box {
reading-flow: flex-flow;
}
A ordem de foco agora é a ordem flex reversa: dois, três, um. Em
ambos os casos, a propriedade order
do CSS é considerada.
Exemplo com layout de grade
Para entender como isso funciona em uma grade, imagine que você está criando um layout com itens autoajustados da grade CSS com 12 áreas de foco.
<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>
Você quer que o quinto filho ocupe o maior espaço na parte de cima, seguido pelo segundo filho em direção ao meio da grade. Todas as outras filhas podem ser colocadas automaticamente na grade seguindo um modelo de coluna.
.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;
}
Tente navegar por esses elementos usando a tecla TAB para encontrar o próximo elemento focalizável e as teclas TAB + SHIFT para encontrar o elemento focalizável anterior. Isso segue os itens na ordem da fonte: um a doze.
Para corrigir isso, defina a propriedade reading-flow
:
.wrapper {
reading-flow: grid-rows;
}
A ordem de foco agora é: Cinco, Um, Três, Dois, Quatro, Seis, Sete, Oito, Nove, Dez, Onze, Doze. Ele segue a ordem visual, linha por linha.
Se você quiser que o fluxo de leitura siga a ordem das colunas, use o valor da palavra-chave grid-columns
. A ordem de foco passa a ser Cinco,
Seis, Nove, Sete, Dez, Um, Dois, Onze, Três, Quatro, Oito, Doze.
.wrapper {
reading-flow: grid-columns;
}
Também é possível usar grid-order
. A ordem de foco permanece como Um a Doze.
Isso ocorre porque não havia uma ordem de CSS definida em nenhum item.
Um contêiner de bloco usando reading-order
A propriedade reading-order
permite especificar quando um item
precisa ser visitado no fluxo de leitura, substituindo a ordem definida pela propriedade reading-flow
. Ela
só entra em vigor em um contêiner de fluxo de leitura válido, quando a propriedade reading-flow
não é normal
.
.wrapper {
display: block;
reading-flow: source-order;
}
.top {
reading-order: -1;
inset-inline-start: 50px;
inset-block-start: 50px;
}
O contêiner de bloco a seguir contém cinco itens. Não há regras de layout que reordenem os elementos da ordem de origem, mas há um item fora do fluxo que precisa ser visitado primeiro.
<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>
Ao definir o reading-order
do item como -1
, a ordem de foco o visita primeiro
antes de retornar à ordem de origem para o restante dos itens do fluxo de leitura.
Confira mais exemplos no site chrome.dev.
Interação com tabindex
Historicamente, os desenvolvedores usaram o atributo global tabindex
do HTML para tornar
os elementos HTML com foco e determinar a ordem relativa para a navegação sequencial
de foco. No entanto, esse atributo tem muitas desvantagens e preocupações
de acessibilidade. A principal preocupação é que a navegação de foco ordenada por tabindex criada
usando tabindex positivo não é reconhecida pela árvore de acessibilidade. Quando
usado incorretamente, você pode acabar com uma ordem de foco irregular que não corresponde à
experiência em um leitor de tela. Para corrigir isso, rastreie a ordem usando o
atributo HTML aria-owns.
No exemplo de flex anterior, para ter o mesmo resultado que o uso de
reading-flow: flex-visual
, você pode fazer o seguinte.
<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>
Mas o que acontece se outro elemento fora do contêiner também tiver tabindex=1
?
Em seguida, todos os elementos com tabindex=1
serão visitados juntos antes de passarmos para
o próximo valor incremental de tabindex. Essa navegação sequencial irregular
resulta em uma experiência ruim para o usuário. Por isso, especialistas em acessibilidade recomendam evitar
tabindex positivo. Tentamos
corrigir isso ao projetar o reading-flow
.
Um contêiner com a propriedade reading-flow
definida se torna um proprietário do escopo de foco.
Isso significa que ele define o escopo da navegação sequencial do foco para visitar todos os elementos
dentro do contêiner antes de passar para o próximo elemento com foco em um documento
da Web. Além disso, os filhos diretos são ordenados usando a propriedade
reading-flow, e o tabindex positivo é ignorado para fins de ordenação. Ainda é
possível definir um tabindex positivo nos descendentes de um item de fluxo de leitura.
Um elemento com display: contents
que herda a propriedade reading-flow
do layout pai também será um contêiner de fluxo de leitura válido. Considere
isso ao projetar seu site. Leia mais sobre isso na nossa
solicitação de feedback sobre reading-flow
e display: contents
.
Conte para nós
Teste os exemplos desta postagem e nos
exemplos de reading-flow
no chrome.dev e use essas propriedades
CSS nos seus sites. Se você tiver algum feedback, envie-o como um problema no
repositório do GitHub do grupo de trabalho do CSS. Se
você tiver feedback específico sobre o comportamento de escopo de foco e tabindex, envie
como um problema para o repositório do HTML WHATNOT no
GitHub. Queremos saber sua opinião sobre
esse recurso.