Las pistas implícitas y la rejilla que no declaraste
Qué ocurre cuando un elemento cae fuera de la rejilla explícita: cómo se generan las pistas implícitas, cómo dimensionarlas con grid-auto-rows, por qué el índice -1 las ignora y qué son las líneas negativas implícitas.
La rejilla que declaras con grid-template-columns y grid-template-rows es la explícita. La que acabas teniendo casi nunca coincide con ella: cada vez que un elemento se coloca fuera de las pistas declaradas, el motor genera pistas implícitas para acomodarlo. Como esas pistas tienen auto por defecto y no aparecen en tu código, son la fuente de las filas de altura inconsistente, del índice -1 que apunta a un sitio raro y de la rejilla que crece en una dirección que no esperabas.
- Explicar cuándo se genera una pista implícita y en qué eje.
- Dimensionar las pistas implícitas con
grid-auto-rowsygrid-auto-columns. - Explicar por qué el índice
-1no cuenta las pistas implícitas. - Reconocer el caso de las líneas negativas y las pistas implícitas al inicio.
Cuándo aparecen
Se genera una pista implícita en tres situaciones.
Cuando hay más elementos que celdas explícitas. Es la más frecuente: defines tres columnas y no defines filas, metes nueve elementos, y el motor crea tres filas implícitas.
/* Tres columnas explícitas, cero filas explícitas.
Todas las filas que veas son implícitas. */
.rejilla { display: grid; grid-template-columns: repeat(3, 1fr); }
Cuando colocas un elemento fuera del rango declarado. Un grid-row: 5 en una rejilla con dos filas explícitas genera las filas 3, 4 y 5.
Cuando colocas un elemento en índices negativos por debajo del inicio. Un grid-column: -1 / 1 con la línea -1 fuera de lugar, o directamente un grid-row: 0, que no existe: la numeración empieza en 1 y no hay línea 0.
Los índices van de 1 hacia delante y de −1 hacia atrás; no hay línea 0. Escribir grid-column: 0 es un valor inválido y la declaración se descarta. Es un error fácil de cometer viniendo de lenguajes donde los índices empiezan en cero.
Dimensionar lo implícito
Las pistas implícitas se dimensionan con auto por defecto, es decir, se ajustan a su contenido. Para controlarlas están grid-auto-rows y grid-auto-columns.
/* Todas las filas implícitas miden al menos 10rem y crecen si hace falta */
.rejilla {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(10rem, auto);
gap: 1rem;
}
Ese minmax(10rem, auto) es probablemente la declaración más útil de toda esta lección: garantiza una altura mínima uniforme sin impedir que una fila con más contenido crezca. Es lo que produce rejillas de tarjetas con aspecto ordenado sin recortar nada.
Ambas propiedades aceptan una lista de valores que se cicla:
/* Las filas implícitas alternan alta, baja, alta, baja... */
.zigzag { grid-auto-rows: 12rem 6rem; }
Es una funcionalidad poco conocida y produce patrones editoriales interesantes sin colocar nada a mano.
Y grid-auto-flow decide en qué eje crece la rejilla implícita: con row, se añaden filas; con column, columnas. Es la misma propiedad que gobierna la colocación automática, y es coherente: la dirección en la que se recorre la rejilla es la dirección en la que crece.
Los índices negativos y lo implícito
Este es el comportamiento que más desconcierta. El índice -1 se refiere a la última línea de la rejilla explícita, no de la rejilla real.
.rejilla {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 10rem); /* dos filas explícitas */
}
/* Esto NO llega hasta el final visual si hay filas implícitas */
.barra { grid-row: 1 / -1; }
Con cinco elementos, la rejilla tendrá dos filas explícitas y una implícita. grid-row: 1 / -1 cubre solo las dos explícitas.
La razón es de diseño y es defendible: si -1 apuntara al final de la rejilla real, cualquier elemento colocado con -1 cambiaría de tamaño según cuántos elementos hubiera, y peor aún, el propio elemento con -1 puede generar pistas implícitas al colocarse, con lo que la definición sería circular. Anclar los negativos a lo explícito es lo único que da un resultado determinista.
La consecuencia práctica: si necesitas un elemento que llegue al final real, define las filas explícitamente o usa span con un número. Y si tu rejilla es toda implícita, -1 es igual a 1 porque solo hay una línea explícita en ese eje.
/* Con repeat(auto-fill, ...) las pistas SÍ son explícitas,
así que 1 / -1 funciona como esperas */
.tarjetas {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
}
.tarjetas > .destacada { grid-column: 1 / -1; }
Hay un caso raro pero real en el otro extremo: si un elemento se coloca antes de la línea 1, la rejilla crece hacia el inicio y las líneas se renumeran.
.rejilla { display: grid; grid-template-columns: repeat(3, 1fr); }
.rara { grid-column: -5 / -4; }
Con tres columnas explícitas, las líneas explícitas son −4, −3, −2 y −1. Pedir la línea −5 genera una pista implícita antes del inicio. Los elementos que estaban en la columna 1 siguen ahí, pero ahora hay una columna a su izquierda.
Esto casi nunca lo haces a propósito. Aparece por errores de cálculo con negativos, y el síntoma es una rejilla con un margen inexplicable a la izquierda que las DevTools sí muestran si activas el superpuesto: las pistas implícitas se dibujan con línea discontinua y las explícitas con línea continua. Es la forma más rápida de saber cuál es cuál.
Un patrón que aprovecha lo implícito
No todo son problemas. Hay un patrón que se apoya deliberadamente en las pistas implícitas y funciona muy bien: la rejilla de una sola dimensión declarada, donde el otro eje crece solo.
/* Lista de artículos: las columnas están declaradas,
las filas aparecen según haga falta y todas miden lo mismo */
.articulos {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
grid-auto-rows: minmax(14rem, auto);
gap: 1.5rem;
}
No hay ningún grid-template-rows y no hace falta: declarar el eje que te importa y dejar que el otro se genere es lo que hace que este layout aguante desde un elemento hasta mil sin tocar nada. Declarar filas explícitas aquí sería un error: te obligaría a saber cuántos elementos hay.
Detrás de la separación entre rejilla explícita e implícita hay una pregunta de diseño que conviene hacerse antes de escribir la primera línea: ¿estás describiendo una estructura o un comportamiento? Una plantilla de página con cabecera, lateral, contenido y pie es una estructura: sabes cuántas zonas hay, tienen nombres, y no cambian con los datos. Ahí todo debe ser explícito, y las pistas implícitas que aparezcan son un síntoma de que algo se ha colocado mal. Una lista de resultados es un comportamiento: no sabes cuántos elementos habrá, la rejilla tiene que absorber desde cero hasta muchos, y ahí las pistas implícitas son el mecanismo, no el accidente. El error caro es mezclar los dos modos en el mismo contenedor: una rejilla que declara tres filas explícitas para una lista de longitud variable acabará teniendo filas explícitas e implícitas de comportamientos distintos, con -1 apuntando a mitad de camino y con la tercera fila dimensionada por una regla y la cuarta por otra. Los layouts de grid más difíciles de mantener que te vas a encontrar tienen todos esa forma. La regla que evita el problema es de una frase: en un eje, o declaras todas las pistas o no declaras ninguna. Si te ves declarando algunas y dejando que el resto se genere, casi siempre es que estás usando un contenedor para dos cosas distintas.
- Monta una rejilla de tres columnas sin filas y comprueba en DevTools que las filas se dibujan discontinuas.
- Añade
grid-template-rows: repeat(2, 10rem)y verifica que ahora las dos primeras son continuas y el resto no. - Coloca un elemento con
grid-row: 1 / -1y comprueba que no llega al final. - Arréglalo de dos formas: con
spany declarando todas las filas. - Usa
grid-auto-rowscon dos valores y observa el ciclo. - Provoca una pista implícita al inicio con un negativo fuera de rango y localízala en el superpuesto.