wandres.dev
GRID II · Áreas, líneas nombradas, auto-placement

El algoritmo de colocación automática

Los cuatro pasos con los que grid coloca lo que tú no colocaste: primero los anclados, luego los que tienen fila, después se decide el número de columnas, y por último el cursor recorre la rejilla sin retroceder nunca.

⏱ 19 min

Casi todo lo que pones en una rejilla lo coloca el motor, no tú. El algoritmo que lo hace tiene cuatro pasos, procesa los elementos en un orden concreto y mantiene un cursor que nunca retrocede. Ese detalle del cursor —que va hacia delante y no vuelve— es el que explica los huecos que aparecen sin motivo aparente y el que hace que dense sea una opción con consecuencias, no un ajuste cosmético.

🎯 Al terminar esta lección sabrás
  • Enumerar los cuatro pasos del algoritmo de colocación en orden.
  • Explicar cómo se determina el número de columnas de la rejilla implícita.
  • Predecir dónde caerá un elemento con solo la fila o solo la columna definida.
  • Justificar por qué el empaquetado por defecto deja huecos.

Los cuatro pasos

flowchart TB
A[Paso 1 colocar los que tienen fila y columna definidas] --> B[Paso 2 colocar los que solo tienen fila]
B --> C[Paso 3 determinar el numero de columnas de la rejilla implicita]
C --> D[Paso 4 recorrer con el cursor y colocar el resto]
D --> E[Cabe aqui]
E --> F[Si ocupar la celda y avanzar el cursor]
E --> G[No avanzar una columna y volver a probar]
G --> H[Se acabo la fila bajar a la siguiente y volver al inicio]
H --> E
F --> D
style A fill:#89b4fa,color:#11111b
style B fill:#89b4fa,color:#11111b
style C fill:#cba6f7,color:#11111b
style D fill:#89b4fa,color:#11111b
style E fill:#f9e2af,color:#11111b
style F fill:#a6e3a1,color:#11111b
style G fill:#f9e2af,color:#11111b
style H fill:#f9e2af,color:#11111b

Paso 1: los anclados. Se colocan primero todos los elementos que tienen posición definida en los dos ejes. Ocupan sus celdas y ya no se mueven. Todo lo demás tendrá que esquivarlos.

Paso 2: los que tienen fila. Los elementos con fila definida y columna automática se colocan en su fila, en orden de documento, buscando el primer hueco disponible a la derecha del último elemento colocado en esa misma fila.

Paso 3: contar columnas. Solo entonces se decide cuántas columnas tiene la rejilla implícita. Se parte de las columnas explícitas, se añaden las que hagan falta para acomodar a los elementos con columna definida, y si algún elemento de colocación automática ocupa más columnas que las que hay, se añaden más.

Paso 4: el resto. Un cursor recorre la rejilla celda a celda, en el orden que marque grid-auto-flow. Para cada elemento pendiente, avanza hasta encontrar un hueco donde quepa entero. Si al final de una fila no cabe, baja a la siguiente y vuelve al inicio.

El detalle crítico está en el paso 4: el cursor solo avanza. Nunca vuelve atrás a mirar si dejó un hueco donde el siguiente elemento sí habría cabido. Ese comportamiento se llama empaquetado disperso y es el valor por defecto.

📝
El orden de documento, modificado por order

“Orden de documento” significa el orden del HTML, salvo que hayas usado order, que sí afecta al orden de colocación en grid igual que en flex. Con order, el elemento que aparece antes en el HTML puede colocarse después, y arrastra el mismo problema de accesibilidad de siempre.

Los huecos del empaquetado disperso

El comportamiento se ve con un ejemplo mínimo. Rejilla de tres columnas, cuatro elementos, uno de ellos ocupa dos columnas.

<div class="rejilla">
  <div class="a">A</div>
  <div class="b">B</div>
  <div class="c ancha">C</div>
  <div class="d">D</div>
</div>
.rejilla { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.ancha { grid-column: span 2; }

El cursor coloca A en la celda 1 y B en la 2. Llega C, que necesita dos columnas: en la fila 1 solo queda una, así que baja a la fila 2 y ocupa las columnas 1 y 2. Llega D y va a la columna 3 de la fila 2.

Resultado: la celda 3 de la primera fila queda vacía, aunque D habría cabido perfectamente ahí. El cursor ya había pasado de largo y no vuelve.

fila 1:  [ A ][ B ][   ]
fila 2:  [   C    ][ D ]

Este es el hueco misterioso de grid, y ahora tiene una explicación completa: no es un bug, es que el algoritmo prioriza el orden sobre la densidad.

Los elementos con un solo eje definido

Es el caso que más confunde, porque el comportamiento cambia según qué eje hayas fijado.

Un elemento con fila definida y columna automática se coloca en el paso 2, antes de que se cuenten las columnas y antes que los elementos totalmente automáticos. Su fila es una promesa: estará ahí, y los demás se apañarán.

.destacado { grid-row: 1; }   /* se coloca en el paso 2 */

Un elemento con columna definida y fila automática se coloca en el paso 4, junto con el resto. El cursor lo lleva a su columna; si esa columna está antes de donde ya iba el cursor, baja una fila. Después avanza en filas hasta encontrar sitio.

.lateral { grid-column: 1; }  /* se coloca en el paso 4 */

La asimetría es real y viene de que grid-auto-flow: row da prioridad a las filas. Con grid-auto-flow: column, los papeles se invierten: los pasos 2 y 3 operan sobre columnas.

/* Rellena columnas antes que filas */
.tira { display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, auto); }

grid-auto-flow: column con grid-template-rows definido es el patrón para una lista que se lee de arriba abajo y luego salta a la columna siguiente, como un índice o una lista de enlaces en el pie.

Cómo controlar la colocación sin colocar

Un patrón muy útil y poco conocido: puedes influir en el resultado sin dar coordenadas, solo declarando amplitudes.

/* Rejilla editorial: la primera pieza ocupa dos por dos,
   el resto se acomoda alrededor sin coordenadas */
.editorial {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 10rem;
  gap: 1rem;
}
.editorial > :first-child { grid-column: span 2; grid-row: span 2; }
.editorial > :nth-child(7n + 4) { grid-column: span 2; }

Con span y sin coordenadas, el algoritmo sigue teniendo libertad para colocar, y el layout aguanta cualquier número de elementos. Con coordenadas fijas, cada elemento nuevo obliga a revisar el conjunto.

Esta es la forma de trabajar con grid que mejor escala: describe amplitudes, no posiciones, y deja el paso 4 hacer su trabajo.

El cursor que no retrocede es una decisión sobre el orden de lectura, no sobre la estética

El empaquetado disperso deja huecos y todo el mundo lo ve como una carencia que dense viene a corregir. Es al revés: el hueco es la funcionalidad. Un algoritmo que retrocediera para rellenar huecos tendría que reordenar los elementos, y el orden en el que un usuario los recorre con el teclado o los oye en un lector de pantalla es el del DOM, no el visual. Con empaquetado disperso, el orden visual y el orden del DOM coinciden siempre: el elemento tres se ve después del dos y antes del cuatro, sin excepciones. Esa garantía tiene un precio en píxeles vacíos, y la especificación decidió pagarlo por defecto. Es la misma familia de decisiones que ya has visto en el tamaño mínimo automático de flexbox: cuando hay conflicto entre lo que se ve bien y lo que se entiende bien, el valor inicial protege a quien no puede ver la pantalla. Merece la pena tener catalogadas estas decisiones, porque forman un patrón coherente que dice mucho de cómo se diseña la plataforma web: el comportamiento por defecto casi siempre es el accesible, y las opciones que rompen la accesibilidad existen pero hay que pedirlas explícitamente. order, row-reverse, dense y la colocación por coordenadas son las cuatro puertas por las que se sale de esa garantía en el layout. Ninguna está prohibida, pero cruzarlas es asumir una responsabilidad que antes tenía el motor.