Fecha de publicación: 1 de mayo de 2025
Las propiedades reading-flow
y reading-order
de CSS están disponibles a partir de Chrome 137.
En esta publicación, se explican los motivos detrás del diseño de estas propiedades y algunos detalles breves para comenzar a usarlas.
Los métodos de diseño, como la cuadrícula y el flex, transformaron el desarrollo del frontend. Sin embargo, su flexibilidad puede causar un problema para algunos usuarios. Es muy fácil crear una situación en la que el orden visual no coincida con el orden de la fuente en el árbol del DOM. Como este orden de origen es el que sigue el navegador si navegas por el sitio con un teclado, algunos usuarios pueden encontrar saltos inesperados mientras navegan por una página.
Las propiedades reading-flow
y reading-order
se diseñaron y agregaron a la especificación de visualización de CSS para intentar resolver este problema de larga data.
reading-flow
La propiedad CSS reading-flow
controla el orden en que los elementos de un diseño flexible, de cuadrícula o de bloque se exponen a las herramientas de accesibilidad y cómo se enfocan con métodos de navegación secuencial lineal.
Toma un valor de palabra clave, con un valor predeterminado de normal
, que mantiene el comportamiento de ordenar elementos en orden DOM.
Para usarlo dentro de un contenedor flex, establece su valor en flex-visual
o flex-flow
. Para usarlo dentro de un contenedor de cuadrícula, establece su valor en grid-rows
, grid-columns
o grid-order
.
reading-order
La propiedad CSS reading-order
te permite anular manualmente el orden de los elementos dentro de un contenedor de flujo de lectura. Para usar esta propiedad dentro de una cuadrícula, un contenedor flex o de bloque, establece el valor reading-flow
del contenedor en source-order
y establece el reading-order
del elemento individual en un valor entero.
Ejemplo en Flexbox
Por ejemplo, puedes tener un contenedor de diseño flexible con tres elementos en orden de fila inverso y también deseas usar la propiedad de orden para volver a mezclar ese orden.
<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;
}
Puedes intentar navegar por estos elementos con la tecla TAB para encontrar el siguiente elemento enfocable y TAB + MAYÚSCULAS para encontrar el elemento enfocable anterior. Esto sigue los elementos en orden de origen: Uno, Dos, Tres.
Desde la perspectiva del usuario final, esto no tiene sentido y puede ser muy confuso. Lo mismo sucede si usamos una herramienta de navegación espacial de accesibilidad para navegar por la página.
Para solucionar este problema, configura la propiedad reading-flow
:
.box {
reading-flow: flex-visual;
}
El orden de enfoque ahora es: Uno, Tres, Dos. Esto es lo mismo que el orden visual que obtendrías si leyeras en inglés de izquierda a derecha.
Si, en cambio, prefieres mantener el orden de enfoque como se diseñó originalmente, en orden inverso, puedes establecer lo siguiente:
.box {
reading-flow: flex-flow;
}
El orden de enfoque ahora es el orden flexible inverso: dos, tres y uno. En ambos casos, se considera la propiedad order
del CSS.
Ejemplo con diseño de cuadrícula
Para ver cómo funciona esto en una cuadrícula, imagina que estás creando un diseño con elementos colocados automáticamente en la cuadrícula de CSS con doce áreas enfocables.
<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>
Quieres que el quinto elemento secundario ocupe el espacio más grande en la parte superior, seguido del segundo elemento secundario hacia la mitad de la cuadrícula. Todos los demás elementos secundarios se pueden colocar automáticamente dentro de la cuadrícula siguiendo una plantilla de columna.
.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;
}
Intenta navegar por estos elementos con la tecla TAB para encontrar el siguiente elemento enfocable y las teclas TAB + MAYÚSCULAS para encontrar el elemento enfocable anterior. Esto sigue los elementos en orden de origen: del uno al doce.
Para solucionar este problema, configura la propiedad reading-flow
:
.wrapper {
reading-flow: grid-rows;
}
El orden de enfoque ahora es: Cinco, Uno, Tres, Dos, Cuatro, Seis, Siete, Ocho, Nueve, Diez, Once y Doce. Sigue el orden visual, fila por fila.
Si deseas que el flujo de lectura siga el orden de las columnas, puedes usar el valor de la palabra clave grid-columns
. El orden de enfoque se convierte en Cinco,
Seis, Nueve, Siete, Diez, Uno, Dos, Once, Tres, Cuatro, Ocho, Doce.
.wrapper {
reading-flow: grid-columns;
}
También puedes intentar usar grid-order
. El orden de enfoque permanece de uno a doce.
Esto se debe a que no se estableció ningún pedido de CSS en ningún artículo.
Un contenedor de bloques con reading-order
La propiedad reading-order
te permite especificar cuándo se debe visitar un elemento en el flujo de lectura, anulando el orden establecido por la propiedad reading-flow
. Solo se aplica a un contenedor de flujo de lectura válido, cuando la propiedad reading-flow
no es normal
.
.wrapper {
display: block;
reading-flow: source-order;
}
.top {
reading-order: -1;
inset-inline-start: 50px;
inset-block-start: 50px;
}
El siguiente contenedor de bloques contiene cinco elementos. No hay reglas de diseño que reordenen los elementos de su orden de origen, pero hay un elemento fuera del flujo que se debe visitar primero.
<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>
Si configuras el reading-order
de este elemento en -1
, el orden de enfoque lo visita primero antes de volver al orden de origen para el resto de los elementos del flujo de lectura.
Puedes encontrar más ejemplos en el sitio chrome.dev.
Interacción con tabindex
Históricamente, los desarrolladores han usado el atributo global tabindex
de HTML para que los elementos HTML sean enfocables y determinar el orden relativo para la navegación de enfoque secuencial. Sin embargo, este atributo tiene muchas desventajas y problemas de accesibilidad. La principal preocupación es que el árbol de accesibilidad no reconoce la navegación de enfoque ordenada por el índice de tabulación que se crea con un índice de tabulación positivo. Si se usa de forma incorrecta, es posible que obtengas un orden de enfoque irregular que no coincida con la experiencia en un lector de pantalla. Para solucionarlo, haz un seguimiento del orden con el atributo HTML aria-owns.
En el ejemplo de flex anterior, para obtener el mismo resultado que con reading-flow: flex-visual
, puedes hacer lo siguiente.
<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>
Pero, ¿qué sucede si otro elemento fuera del contenedor también tiene tabindex=1
?
Luego, se visitarán todos los elementos con tabindex=1
juntos, antes de pasar al siguiente valor incremental de tabindex. Esta navegación secuencial con saltos generará una mala experiencia del usuario. Por lo tanto, los expertos en accesibilidad recomiendan evitar un valor positivo de tabindex. Intentamos corregir esto cuando diseñamos reading-flow
.
Un contenedor que tiene el conjunto de propiedades reading-flow
se convierte en un propietario del alcance de enfoque.
Esto significa que abarca la navegación de enfoque secuencial para visitar cada elemento dentro del contenedor antes de pasar al siguiente elemento enfocado en un documento web. Además, sus elementos secundarios directos se ordenan con la propiedad de flujo de lectura y se ignora el índice de tabulación positivo para el orden. Aún es posible establecer un tabindex positivo en los elementos secundarios de un elemento de flujo de lectura.
Ten en cuenta que un elemento con display: contents
que hereda la propiedad reading-flow
de su elemento superior de diseño también será un contenedor de flujo de lectura válido. Ten esto en cuenta cuando diseñes tu sitio. Obtén más información sobre esto en nuestra solicitud de comentarios sobre reading-flow
y display: contents
.
Envíanos tus comentarios
Prueba los ejemplos de esta publicación y los ejemplos de reading-flow
en chrome.dev, y usa estas propiedades CSS en tus sitios. Si tienes comentarios, infórmalos como un problema en el repositorio de GitHub del grupo de trabajo de CSS. Si tienes comentarios específicos sobre el comportamiento del tabindex y el enfoque de alcance, infórmalo como un problema en el repositorio de GitHub de HTML WHATNOT. Nos encantaría recibir tus comentarios sobre
esta función.