Patrón
Ritmo visual
Una tarjeta breve abre la composición.
Crea layouts tipo masonry con CSS nativo: cambia entre waterfall y brick, combina patrones de lanes, controla la tolerancia del flujo y prueba una mejora progresiva en navegadores sin soporte.
Usa Tab para comprobar que el foco conserva el orden del DOM aunque cambie la colocación visual.
<ul class="lanes">
<li id="lane-1" class="lane-card">
<article>
<p class="eyebrow">Patrón</p>
<h2>Ritmo visual</h2>
<p>Una tarjeta breve abre la composición.</p>
<a href="#lane-1" aria-label="Abrir tarjeta: Ritmo visual">01</a>
</article>
</li>
<li id="lane-2" class="lane-card">
<article>
<p class="eyebrow">CSS</p>
<h2>Sin JavaScript</h2>
<p>Los elementos se reparten entre lanes y se acercan al inicio del contenedor de forma nativa.</p>
<a href="#lane-2" aria-label="Abrir tarjeta: Sin JavaScript">02</a>
</article>
</li>
<li id="lane-3" class="lane-card">
<article>
<p class="eyebrow">Layout</p>
<h2>Tracks flexibles</h2>
<p>Combina repeat(), minmax() y unidades fr.</p>
<a href="#lane-3" aria-label="Abrir tarjeta: Tracks flexibles">03</a>
</article>
</li>
<li id="lane-4" class="lane-card">
<article>
<p class="eyebrow">Orden</p>
<h2>El DOM permanece intacto</h2>
<p>La lectura y el foco siguen el orden de origen aunque cambie la colocación visual.</p>
<a href="#lane-4" aria-label="Abrir tarjeta: El DOM permanece intacto">04</a>
</article>
</li>
<li id="lane-5" class="lane-card">
<article>
<p class="eyebrow">Detalle</p>
<h2>Tolerancia</h2>
<p>flow-tolerance decide cuándo dos posiciones se consideran equivalentes.</p>
<a href="#lane-5" aria-label="Abrir tarjeta: Tolerancia">05</a>
</article>
</li>
<li id="lane-6" class="lane-card">
<article>
<p class="eyebrow">Responsive</p>
<h2>Sin media queries</h2>
<p>auto-fit puede añadir o retirar lanes según el espacio disponible.</p>
<a href="#lane-6" aria-label="Abrir tarjeta: Sin media queries">06</a>
</article>
</li>
<li id="lane-7" class="lane-card">
<article>
<p class="eyebrow">Ejes</p>
<h2>Waterfall o brick</h2>
<p>Define columnas o filas para cambiar la dirección.</p>
<a href="#lane-7" aria-label="Abrir tarjeta: Waterfall o brick">07</a>
</article>
</li>
<li id="lane-8" class="lane-card">
<article>
<p class="eyebrow">Contenido</p>
<h2>Alturas distintas</h2>
<p>Textos, imágenes y componentes pueden conservar su tamaño intrínseco.</p>
<a href="#lane-8" aria-label="Abrir tarjeta: Alturas distintas">08</a>
</article>
</li>
<li id="lane-9" class="lane-card">
<article>
<p class="eyebrow">Grid</p>
<h2>Spans y colocación</h2>
<p>Cada ítem puede ocupar varias lanes o empezar en una línea concreta.</p>
<a href="#lane-9" aria-label="Abrir tarjeta: Spans y colocación">09</a>
</article>
</li>
</ul><ul class="columns-4 [column-gap:16px] supports-[display:grid-lanes]:columns-auto supports-[display:grid-lanes]:[display:grid-lanes] supports-[display:grid-lanes]:[grid-template-columns:repeat(auto-fit,_minmax(min(12rem,_100%),_1fr))] supports-[display:grid-lanes]:gap-y-[16px] supports-[display:grid-lanes]:gap-x-[16px]">
<li id="lane-1" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Patrón</p>
<h2>Ritmo visual</h2>
<p>Una tarjeta breve abre la composición.</p>
<a href="#lane-1" aria-label="Abrir tarjeta: Ritmo visual">01</a>
</article>
</li>
<li id="lane-2" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">CSS</p>
<h2>Sin JavaScript</h2>
<p>Los elementos se reparten entre lanes y se acercan al inicio del contenedor de forma nativa.</p>
<a href="#lane-2" aria-label="Abrir tarjeta: Sin JavaScript">02</a>
</article>
</li>
<li id="lane-3" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Layout</p>
<h2>Tracks flexibles</h2>
<p>Combina repeat(), minmax() y unidades fr.</p>
<a href="#lane-3" aria-label="Abrir tarjeta: Tracks flexibles">03</a>
</article>
</li>
<li id="lane-4" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Orden</p>
<h2>El DOM permanece intacto</h2>
<p>La lectura y el foco siguen el orden de origen aunque cambie la colocación visual.</p>
<a href="#lane-4" aria-label="Abrir tarjeta: El DOM permanece intacto">04</a>
</article>
</li>
<li id="lane-5" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Detalle</p>
<h2>Tolerancia</h2>
<p>flow-tolerance decide cuándo dos posiciones se consideran equivalentes.</p>
<a href="#lane-5" aria-label="Abrir tarjeta: Tolerancia">05</a>
</article>
</li>
<li id="lane-6" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Responsive</p>
<h2>Sin media queries</h2>
<p>auto-fit puede añadir o retirar lanes según el espacio disponible.</p>
<a href="#lane-6" aria-label="Abrir tarjeta: Sin media queries">06</a>
</article>
</li>
<li id="lane-7" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Ejes</p>
<h2>Waterfall o brick</h2>
<p>Define columnas o filas para cambiar la dirección.</p>
<a href="#lane-7" aria-label="Abrir tarjeta: Waterfall o brick">07</a>
</article>
</li>
<li id="lane-8" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Contenido</p>
<h2>Alturas distintas</h2>
<p>Textos, imágenes y componentes pueden conservar su tamaño intrínseco.</p>
<a href="#lane-8" aria-label="Abrir tarjeta: Alturas distintas">08</a>
</article>
</li>
<li id="lane-9" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Grid</p>
<h2>Spans y colocación</h2>
<p>Cada ítem puede ocupar varias lanes o empezar en una línea concreta.</p>
<a href="#lane-9" aria-label="Abrir tarjeta: Spans y colocación">09</a>
</article>
</li>
</ul>@supports (display: grid-lanes) {
.lanes {
display: grid-lanes;
grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
gap: 16px;
}
}
.lanes {
margin: 0;
padding: 0;
list-style: none;
}
.lane-card {
padding: 1rem;
border: 1px solid #cbd5e1;
border-radius: 1rem;
background: #f8fafc;
color: #0f172a;
}
@supports not (display: grid-lanes) {
.lanes {
columns: 4;
column-gap: 16px;
}
.lane-card {
display: inline-block;
inline-size: 100%;
break-inside: avoid;
margin-block-end: 16px;
vertical-align: top;
}
}.lanes {
@supports (display: grid-lanes) {
display: grid-lanes;
grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
gap: 16px;
}
margin: 0;
padding: 0;
list-style: none;
> .lane-card {
padding: 1rem;
border: 1px solid #cbd5e1;
border-radius: 1rem;
background: #f8fafc;
color: #0f172a;
}
@supports not (display: grid-lanes) {
columns: 4;
column-gap: 16px;
> .lane-card {
display: inline-block;
inline-size: 100%;
break-inside: avoid;
margin-block-end: 16px;
vertical-align: top;
}
}
}Guía educativa de CSS Grid Lanes
Una galería de imágenes o tarjetas puede tener alturas distintas y seguir compartiendo columnas. Grid Lanes ofrece ese reparto tipo masonry con CSS: aprende cómo se distribuyen las piezas, cuándo conviene usarlo y cómo conservar un resultado útil sin soporte.
Define tracks en un eje y deja que las piezas se apilen en el otro. No hay una cuadrícula de filas y columnas que cada tarjeta deba rellenar.
El eje de Grid contiene las lanes: sus tamaños se definen con la sintaxis conocida de Grid, como repeat(), minmax() y fr. El eje de apilamiento permite que cada pieza conserve el tamaño que necesita su contenido.
La colocación automática procesa las piezas en orden y busca una posición cercana al inicio entre las lanes disponibles, teniendo en cuenta su ocupación y la tolerancia. Una tarjeta breve deja espacio para la siguiente sin esperar a la más alta de una fila común.
display: grid-lanes crea un contenedor de nivel de bloque; inline-grid-lanes crea uno de nivel inline. Esa diferencia afecta a la caja exterior, no convierte el algoritmo en una fila de Flexbox.
Elige qué eje necesita tracks. En un modo de escritura horizontal, columnas producen un waterfall vertical y filas un brick horizontal.
grid-template-columns define las lanes del waterfall. Para brick, usa grid-template-rows y deja grid-template-columns en none; conservar una plantilla de columnas del layout anterior puede mantener la orientación que no esperabas.
En la receta, repeat(auto-fit, minmax(min(12rem, 100%), 1fr)) crea tracks responsivos. El mínimo interior min() permite una sola lane estrecha sin desbordar el contenedor. La cantidad de lanes depende del espacio disponible y del gap.
grid-column coloca o extiende una pieza en waterfall; grid-row cumple ese papel en brick. span 2 ocupa dos lanes, pero no fija una altura. Las líneas negativas cuentan desde el final del grid explícito. No coloques piezas en supuestas filas del eje de apilamiento.
Fragmentos para dos contenedores alternativos con una pieza .featured. En waterfall se garantizan dos columnas para el span; en brick se garantizan dos filas. Añade el estilo de las tarjetas y comprueba el scroll del brick en su contexto.
Estos dibujos son esquemas conceptuales. Elige el layout por las relaciones que debe conservar el contenido, además de por su densidad visual.
display: grid-lanes;frente adisplay: grid;Grid mantiene filas y columnas compartidas: sirve para formularios, paneles o tarjetas que necesitan alinearse. Grid Lanes conserva tracks en un solo eje. grid-auto-flow: dense rellena huecos entre celdas de Grid, pero no crea masonry de alturas intrínsecas.
Explorar CSS Griddisplay: grid-lanes;frente acolumns: 2;Columns hace fluir contenido por una columna y después por la siguiente. break-inside: avoid ayuda a mantener una tarjeta junta, pero no elige la lane más corta. Puede ser un fallback útil si aceptas ese recorrido; no reproduce la distribución de Grid Lanes.
Explorar CSS ColumnsLas dos listas usan el mismo contenido, con longitudes distintas, y mantienen enlaces reales. La primera es la base estable; la segunda activa Grid Lanes solo cuando el navegador reconoce su sintaxis.
La base usa Grid con alineación al inicio, sin igualar la altura de las tarjetas. @supports cambia el display de la segunda lista y reutiliza sus tracks y gap. El contenido sigue accesible sin JavaScript y no necesita medir alturas ni calcular spans de filas.
Cuando las filas compartidas importan.
Abrir labUn texto largo puede fluir entre columnas sin convertirse en una galería de piezas independientes. El orden se recorre por columnas.
Abrir labUna fila o columna cuyo contenido guía el reparto del espacio.
Abrir labSi el contenido debe avanzar dentro de una zona de scroll, define primero ese contenedor y sus destinos. El ajuste de scroll es una decisión distinta al empaquetado de tarjetas.
Abrir labUn borde que acompaña al tamaño del contenido.
Abrir labLos efectos visuales cambian el resultado dibujado. Antes de combinarlos con el layout, comprueba qué elemento recibe el filtro y qué contenido debe permanecer legible.
Abrir labEsta receta está usando Grid Lanes nativo.Esta receta está usando el respaldo con CSS Grid; no demuestra masonry nativo.
Cuando las filas compartidas importan.
Abrir labUn texto largo puede fluir entre columnas sin convertirse en una galería de piezas independientes. El orden se recorre por columnas.
Abrir labUna fila o columna cuyo contenido guía el reparto del espacio.
Abrir labSi el contenido debe avanzar dentro de una zona de scroll, define primero ese contenedor y sus destinos. El ajuste de scroll es una decisión distinta al empaquetado de tarjetas.
Abrir labUn borde que acompaña al tamaño del contenido.
Abrir labLos efectos visuales cambian el resultado dibujado. Antes de combinarlos con el layout, comprueba qué elemento recibe el filtro y qué contenido debe permanecer legible.
Abrir labEl playground también permite observar su fallback con Columns en waterfall y Grid en brick. Esta receta elige Grid como base para conservar una lectura por filas predecible. El fallback es una decisión de producto y puede tener otro aspecto sin perder contenido.
Una composición compacta no garantiza un recorrido fácil de seguir. Comprueba el foco con los enlaces de la receta y con las tarjetas reales del producto.
Estas listas no usan order, tabindex positivo ni reordenación del DOM: Tab sigue la secuencia de origen. La posición visual puede saltar entre lanes. Evita masonry para pasos, rankings o contenido cuya secuencia sea imprescindible si ese recorrido resulta confuso.
flow-tolerance define cuánta diferencia entre posiciones puede tratarse como un empate. normal equivale a 1em; 0px exige distinguir incluso diferencias pequeñas. Un valor mayor puede reducir cambios de lane por diferencias insignificantes, a costa de un empaquetado menos ajustado.
infinite ignora esas diferencias al repartir en orden por las lanes, pero puede producir saltos grandes en el eje de apilamiento cuando las alturas difieren mucho. No es una solución automática de accesibilidad. Prueba primero longitudes finitas y comprueba el resultado.
Los spans mixtos y la colocación explícita pueden hacer que una pieza posterior aparezca visualmente antes que otra. La tolerancia no elimina todos esos retrocesos. Revisa tamaños extremos, imágenes cargadas, textos traducidos, móvil y navegación con teclado antes de elegir la composición.
Diagnostica el eje, el soporte y el recorrido antes de retocar la altura de cada tarjeta.
El soporte del algoritmo, sus valores y la evolución del borrador deben revisarse por separado de las propiedades conocidas de Grid.
Grid Lanes tiene disponibilidad limitada. Las fuentes consultadas indican soporte desde Safari 26.4, incluido iOS, y ausencia de soporte estable en Chrome, Edge y Firefox. La tarjeta Baseline no convierte el soporte de un motor en interoperabilidad.
CSS Grid Layout Level 3 sigue siendo un borrador en desarrollo. Esta guía usa display: grid-lanes y flow-tolerance; ejemplos antiguos con otras propuestas no son intercambiables. Comprueba cada subfeature y el navegador de destino antes de publicar.
@supports (display: grid-lanes) comprueba que se acepta esa declaración. No verifica todos los valores, el algoritmo completo ni la accesibilidad del resultado. Si dependes de un valor concreto de flow-tolerance, compruébalo por separado y prueba su comportamiento.