Grid no coloca cajas una detrás de otra: dibuja una rejilla y las cajas caen dentro. Y lo que define esa rejilla son líneas, no columnas.
Una rejilla de 3 columnas y 2 filas tiene 4 líneas verticales y 3 líneas horizontales. Siempre hay una línea más que columnas, igual que en una estantería hay una balda más que huecos.
1 2 3 4 ← líneas de columna
1 ┌──────────┬──────────┬──────────┐
│ │ │ │
2 ├──────────┼──────────┼──────────┤
│ │ │ │
3 └──────────┴──────────┴──────────┘
↑
líneas de fila
-1 es siempre la última línea,
sin tener que saber cuántas hay.display: grid: convierte al elemento en una
rejilla. Sus hijos pasan a colocarse en celdas.grid-template-columns: dibuja las columnas. Se
escriben los anchos uno detrás de otro, y el número de valores es el número de
columnas.
grid-template-columns: 1fr 2fr 1fr; — tres columnas; la
unidad fr es una fracción del espacio disponible.
Hay 1+2+1 = 4 partes, así que la del centro ocupa el doble que las de los lados,
sea cual sea el tamaño de la pantalla.grid-template-columns: 200px 200px 200px; — tres columnas de
200 px. Se pueden mezclar: 200px 1fr 1fr deja la primera fija y
reparte el resto.grid-template-columns: repeat(3, 1fr); — lo mismo que
escribir 1fr 1fr 1fr. Útil cuando hay muchas columnas iguales.grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
— el navegador pone tantas columnas como quepan, de 200 px como
mínimo, y reparte lo que sobre. Es una galería fluida sin escribir medidas de
pantalla.grid-template-rows: lo mismo con las filas.
grid-template-rows: 1fr 3fr 1fr; reparte la altura disponible en cinco
partes y le da tres a la del medio.
grid-auto-rows:
grid-auto-rows: 200px; hace que todas las filas nuevas midan
200 px.gap: separación entre celdas.
gap: 10px; la aplica a filas y columnas a la vez; también existen
row-gap y column-gap por separado. Es mejor que poner
márgenes a los hijos, porque no sobra espacio en los bordes.grid-template-areas: en vez de números, se
dibuja la maqueta con nombres.
.padre {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"cabecera cabecera"
"lateral contenido"
"pie pie";
}
Cada palabra ocupa una celda, y repetir un nombre en celdas contiguas hace que esa
zona se extienda. Después, cada hijo dice en qué zona va con
grid-area.justify-items y
align-items: cómo se coloca cada caja
dentro de su celda, en horizontal y en vertical. Por defecto valen
stretch, así que la caja llena la celda entera.grid-column: entre qué líneas se coloca la caja,
en horizontal.
grid-column: 1 / 3; — va de la línea 1 a la línea 3, o sea
que ocupa dos columnas. Aquí es donde hace falta tener claro
que se cuentan líneas y no columnas.grid-column: span 2; — ocupa dos columnas, donde le toque,
sin decir desde qué línea.grid-column: 1 / -1; — de la primera línea a la última,
o sea el ancho entero de la rejilla, haya las columnas que haya.grid-row: lo mismo en vertical.
grid-row: 2 / 4; ocupa dos filas.grid-area: el nombre de la zona que le
corresponde, cuando el padre ha usado grid-template-areas.
grid-area: cabecera;justify-self y
align-self: como los -items del
padre, pero para una sola caja, cuando se quiere que esa se comporte distinto de
las demás.La diferencia con Flexbox: en Grid el reparto se escribe
una vez en el padre, con grid-template-columns; en Flexbox lo
declara cada hijo, con flex.
Lo que Grid necesita saber de antemano es la forma de la rejilla, no cuántos hijos van a entrar: los que sobren crean filas nuevas automáticamente. Flexbox no necesita saber ninguna de las dos cosas, porque no hay rejilla: pone en una tira los hijos que le lleguen.