// css · Web Platform Advent #16
Subgrid CSS: que las rejillas anidadas compartan las líneas del padre
Una rejilla anidada inventa sus propias pistas, así que las tarjetas vecinas nunca se alinean. Subgrid hace que el hijo adopte las líneas de su padre: qué resuelve, las dos reglas que hay que recordar y en qué se diferencia de display: contents.
Subgrid resuelve una frustración concreta, y conviene enunciarla con precisión porque todo lo demás se deriva de ahí: una rejilla anidada crea sus propias pistas, que no tienen nada que ver con las del padre. Tres tarjetas en fila, cada una organizando su título, su cuerpo y su pie como rejilla interna, dimensionarán esas filas de forma independiente - y los pies no quedarán alineados.
Subgrid le dice al hijo que deje de inventar pistas y use las líneas del padre.
El problema, en concreto
Este es el diseño con el que todo el mundo tropieza. Una rejilla exterior de tarjetas, y cada tarjeta es a su vez una rejilla de tres filas:
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.card {
display: grid;
grid-template-rows: auto 1fr auto;
} Ahora cada tarjeta dimensiona sus tres filas a partir de su propio contenido. Una tarjeta con un título de dos líneas obtiene una primera fila más alta que su vecina con el título en una sola. El resultado: tres tarjetas cuyos elementos internos están todos ligeramente desfasados - y ningún estilo aplicado dentro de la tarjeta lo arregla, porque cada tarjeta mide de forma aislada.
La solución, y las dos reglas
Convierte la tarjeta en una subgrid en el eje que quieras alinear:
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
} Ahora las tres filas de cada tarjeta son las tres filas del padre. El título más alto del conjunto define la fila 1 para todas, de modo que títulos, cuerpos y pies caen sobre las mismas líneas a lo largo de toda la fila.
Merece la pena memorizar dos reglas, porque casi todos los casos de « subgrid no funciona » se reducen a una de ellas:
- El elemento debe ser hijo directo de la rejilla cuyas pistas adopta. Subgrid no atraviesa un envoltorio: mete un
<div>corriente entre la rejilla padre y la tarjeta y la relación se rompe. - Solo adopta las pistas que abarca. Una tarjeta que abarca tres filas adopta tres. Si no declaras el span, abarca una, y obtienes una sola pista - lo que se parece exactamente a un subgrid que no hace nada.
Funciona eje por eje
Subgrid se aplica a filas y columnas de forma independiente. Un hijo puede tomar las columnas del padre y definir sus propias filas, algo muy habitual:
.child {
display: grid;
grid-column: span 4;
grid-template-columns: subgrid; /* columnas del padre */
grid-template-rows: auto auto; /* sus propias filas */
} Así se alinea un bloque anidado con un sistema de columnas válido para toda la página sin renunciar al control de su ritmo vertical.
Los huecos y las líneas con nombre vienen incluidos
Dos comodidades fáciles de pasar por alto:
- El hueco se hereda del padre en el eje subgridado, que suele ser lo que quieres. Declara
gapen el hijo para sobrescribirlo. - Las líneas con nombre también se heredan: si el padre define
[content-start]y[content-end], el hijo puede colocar elementos directamente sobre esos nombres.
Subgrid frente a display: contents
Antes de subgrid, el apaño habitual era display: contents en el envoltorio, que elimina su caja y promueve a sus hijos a elementos de la rejilla exterior. Alinea, y cuesta la caja: sin fondo, sin borde, sin padding, sin border-radius en la tarjeta, porque la tarjeta ya no genera una caja donde pintarlos.
display: contents | subgrid | |
|---|---|---|
| Alineación entre vecinos | Sí | Sí |
| Conserva la caja del envoltorio | No | Sí |
| Fondo, borde, padding | Se pierden | Se conservan |
| Control por eje | No | Sí |
Si la tarjeta tiene que parecer una tarjeta, subgrid es la respuesta, y display: contents nunca lo fue.
Compatibilidad con navegadores
Firefox lanzó subgrid primero, ya en 2019, y pasó varios años siendo el único motor que lo tenía. Safari lo añadió en 2022 y Chrome en 2023, así que está disponible en las versiones actuales de todos los navegadores principales - lo bastante reciente como para que convenga comprobar tu propio objetivo de compatibilidad en vez de darlo por hecho.
El modelo mental es sencillo en cuanto encaja: una rejilla anidada normal pregunta « ¿cuánto espacio tengo y cómo lo reparto? ». Una subgrid pregunta « ¿dónde están las líneas de mi padre? » - y es esa segunda pregunta la que hace que una fila de tarjetas parezca diseñada en lugar de simplemente colocada. Si aún estás eligiendo mecanismo de maquetación, empieza por CSS Grid frente a Flexbox; y para componentes que deben adaptarse al espacio que reciben y no a la pantalla, combínalo con las container queries.