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 breves para você começar a usá-las.
Métodos de layout, como grade e flex, transformaram o desenvolvimento de front-end. No entanto, 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 é o 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 antigo.
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 sequenciais lineares.
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 usar em um contêiner flexível, defina o valor como flex-visual ou flex-flow. Para usar dentro de um contêiner de grade, defina o valor como
grid-rows, grid-columns ou grid-order.
reading-order
A propriedade CSS reading-order permite substituir 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 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 em ordem de linha invertida e também querer usar a propriedade "order" 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 tentar 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 de origem: 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 ela foi originalmente planejada, em ordem inversa, defina:
.box {
reading-flow: flex-flow;
}
A ordem de foco agora é a ordem flexível inversa: 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 de grade CSS posicionados automaticamente com 12 áreas focalizáveis.
<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 no meio da grade. Todos os outros elementos filhos podem ser posicionados 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 de origem: de um a doze.
Para corrigir isso, defina a propriedade reading-flow:
.wrapper {
reading-flow: grid-rows;
}
A ordem de foco agora é: 5, 1, 3, 2, 4, 6, 7, 8, 9, 10, 11, 12. 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;
}
Você também pode tentar usar grid-order. A ordem de foco permanece de um a doze.
Isso ocorre porque não havia um pedido do CSS definido em nenhum item.
Um contêiner de bloco usando reading-order
A propriedade reading-order permite especificar quando um item deve ser visitado no fluxo de leitura, substituindo a ordem definida pela propriedade reading-flow. Ele
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 reordenam os elementos da ordem de origem, mas há um item fora do fluxo que deve 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 deste item como -1, a ordem de foco o visita primeiro
antes de voltar à 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 usam o atributo global tabindex do HTML para tornar os elementos HTML focalizáveis e determinar a ordenação relativa para a navegação sequencial por foco. No entanto, esse atributo tem muitas desvantagens e problemas de acessibilidade. O principal problema é que a navegação por 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 instável que não corresponde à experiência em um leitor de tela. Para corrigir isso, rastreie a ordenação usando o atributo HTML
aria-owns.
No exemplo flexível anterior, para ter o mesmo resultado que usando
reading-flow: flex-visual, faça 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 instável resulta em uma experiência ruim para o usuário. Por isso, especialistas em acessibilidade recomendam evitar
tabindex positivo. Tentamos corrigir isso ao criar 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 limita a navegação sequencial por foco para visitar todos os elementos
dentro do contêiner antes de passar para o próximo elemento focalizável em um documento
da Web. Além disso, os filhos diretos são ordenados usando a propriedade de fluxo de leitura, 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 elemento pai de layout também será um contêiner de fluxo de leitura válido. Tenha isso em mente ao criar seu site. Leia mais sobre isso no nosso pedido de feedback sobre reading-flow e display: contents.
Queremos saber.
Teste os exemplos desta postagem e os exemplos de reading-flow em chrome.dev e use essas propriedades de CSS nos seus sites. Se tiver feedback, levante a questão como um problema no
repositório do grupo de trabalho do CSS no GitHub. Se você tiver feedback específico sobre o comportamento do tabindex e do escopo de foco, informe isso como um problema no repositório HTML WHATNOT do GitHub. Queremos saber sua opinião sobre
esse recurso.