Un grid en tres líneas
Pon display: grid en un contenedor y enumera sus columnas con grid-template-columns. Los hijos llenan las celdas en orden, de izquierda a derecha en español, y empieza una fila nueva cada vez que las columnas se llenan:
Siete elementos, tres columnas: dos filas completas y una tercera fila con el elemento 7 en la primera columna. Todas las columnas tienen el mismo ancho y todos los elementos de una fila tienen la misma altura, así que los bordes se alinean en las dos direcciones. Eso es lo que grid agrega sobre flexbox.
Playground de grid
Escribe cualquier valor de grid-template-columns, o haz clic en un preset. El indicador muestra los anchos de columna que calculó el navegador (con getComputedStyle) y cuántas filas necesitaron los elementos:
Algunas cosas para ver: 1fr 2fr hace que la segunda columna sea exactamente el doble de la primera. 200px 1fr mantiene 200px y le da el resto a la segunda columna. auto 1fr auto ajusta las columnas exteriores a su contenido. repeat(4, 100px) deja espacio vacío al final porque nada es flexible. Un valor inválido, como 1fr 2, se ignora, y el grid conserva el último valor válido.
La unidad fr
fr significa "una parte del espacio libre". El navegador primero descuenta las columnas fijas (px, rem, %, contenido auto) y los gaps, y luego reparte lo que queda entre las columnas fr según sus números.
grid-template-columns en un contenedor de 600px, sin gap | Anchos de columna |
|---|---|
1fr 1fr 1fr | 200, 200, 200 |
1fr 2fr | 200, 400 |
100px 1fr 1fr | 100, 250, 250 |
1fr 50% | 300, 300 |
fr no es lo mismo que %: los porcentajes más los gaps pueden sumar más del 100% y desbordarse, mientras que las columnas fr siempre se reparten solo lo que queda después de los gaps.
repeat(), minmax() y un grid responsive sin media queries
repeat(4, 1fr) es 1fr 1fr 1fr 1fr. minmax(120px, 1fr) es una columna que nunca es más angosta que 120px y crece para tomar una parte. Júntalos con auto-fill o auto-fit en lugar de un número, y el grid crea tantas columnas como quepan:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
Esa sola declaración da tantas columnas de al menos 180px como quepan en el contenedor: varias en una pantalla ancha, una en un teléfono, sin media queries. La diferencia entre auto-fill y auto-fit se ve cuando hay menos elementos que columnas:
En el contenedor caben cinco columnas de 100px. auto-fill conserva las cinco, así que A, B y C miden 112px cada una y quedan dos columnas vacías. auto-fit colapsa las vacías, así que los tres elementos se estiran hasta unos 187px cada uno.
Colocar elementos: grid-column y grid-row
Las líneas del grid se numeran desde 1 en el borde de inicio. grid-column: 1 / 3 significa "de la línea 1 a la línea 3", es decir, dos columnas. span 2 significa "dos columnas desde donde caigas", y -1 es la última línea:
El elemento oscuro ocupa toda la primera fila. El azul cubre un bloque de 2 por 2 y el ámbar dos filas. Los elementos a y b llenan solos las celdas restantes: grid coloca cada elemento que puede en la siguiente celda libre. grid-auto-rows: 60px define la altura de las filas que no declaraste con grid-template-rows.
grid-template-areas: ponles nombre a las partes de un layout
Para el layout de una página, nombra las áreas y dibújalas como texto. Cada string es una fila, cada palabra una celda, y un elemento se une a un área con grid-area:
El encabezado y el pie ocupan las dos columnas porque sus nombres llenan las dos celdas de sus filas. La fila del medio es 1fr, así que toma la altura que quede de los 280px. Para apilar todo en un teléfono, una media query solo tiene que volver a dibujar las áreas como una columna: grid-template-areas: "header" "side" "main" "footer" con grid-template-columns: 1fr. La página de media queries muestra el patrón.
Alinear dentro de las celdas
Los elementos grid se estiran para llenar su celda por defecto. Estas propiedades los mueven dentro de ella:
| Propiedad | En | Mueve |
|---|---|---|
justify-items | el contenedor | todos los elementos a lo largo de la fila (eje inline) |
align-items | el contenedor | todos los elementos hacia arriba y abajo (eje de bloque) |
place-items | el contenedor | abreviatura: place-items: center centra en los dos |
justify-self / align-self | el elemento | un elemento |
justify-content / align-content | el contenedor | todo el conjunto de pistas, cuando el grid es más pequeño que el contenedor |
display: grid; place-items: center; es la forma más corta de centrar un hijo en una caja.
Grid o flexbox
Grid es bidimensional: tú decides las columnas (y las filas) y el contenido las llena, así que todas las tarjetas de una galería tienen el mismo ancho, incluso en la última fila. Flexbox es unidimensional: los elementos toman su tamaño de su contenido a lo largo de una sola línea. Se combinan bien: un grid para la página y la galería de tarjetas, flexbox dentro de cada tarjeta para la fila del encabezado. La página de flexbox cubre la otra mitad.
Orden y accesibilidad
grid-template-areas, grid-row, grid-column y order pueden colocar un elemento en cualquier lugar, pero los lectores de pantalla y la tecla Tab siguen el orden del HTML. Mantén un orden de código con sentido (encabezado, navegación, contenido principal, pie) y usa grid para acomodarlo, no para arreglar un orden del HTML que no tiene sentido.
Errores comunes
- Poner
display: griden los elementos. Va en el padre; solo los hijos directos son elementos grid. - Usar porcentajes con gaps.
grid-template-columns: 50% 50%másgap: 16pxse desborda 16px. Usa1fr 1fr. auto-fillcuando queríasauto-fit. Con pocos elementos,auto-filldeja columnas vacías. Cambia aauto-fitpara estirar los elementos.- Una columna
1frque crece más allá de su parte. Una columna1frno se encoge por debajo de su contenido más largo (una URL larga, una imagen ancha). Usaminmax(0, 1fr)para que pueda encogerse. - Strings de áreas que no forman rectángulos. Cada área con nombre debe formar un rectángulo, y cada string de fila necesita la misma cantidad de celdas, o se ignora toda la declaración
grid-template-areas. - Olvidar que los números de línea empiezan en 1. Tres columnas tienen cuatro líneas:
1 / 4o1 / -1ocupan las tres.
Preguntas frecuentes
¿Qué es CSS grid?
Un sistema de layout que coloca elementos en filas y columnas a la vez. Pones display: grid en un contenedor, describes sus columnas con grid-template-columns (y opcionalmente sus filas), y sus hijos directos llenan las celdas en orden.
¿Qué significa 1fr en CSS grid?
fr es una fracción del espacio libre del contenedor grid. grid-template-columns: 1fr 1fr 1fr da tres columnas iguales, y 1fr 2fr hace que la segunda columna sea el doble de ancha que la primera. Primero se descuentan los tamaños fijos y los gaps; las columnas fr se reparten lo que queda.
¿Qué diferencia hay entre auto-fill y auto-fit?
Los dos crean tantas columnas como quepan. auto-fill conserva las columnas vacías, así que unos pocos elementos se quedan angostos y dejan espacio vacío al final de la fila. auto-fit colapsa las columnas vacías, así que los elementos se estiran para llenar la fila. Con suficientes elementos para llenar la fila, los dos se ven igual.
¿Cómo hago que un elemento grid ocupe dos columnas?
Usa grid-column: span 2 en el elemento, o dale líneas de inicio y fin: grid-column: 1 / 3 cubre las columnas 1 y 2. grid-column: 1 / -1 ocupa todo el ancho, porque -1 es la última línea.
¿Cuándo uso grid en lugar de flexbox?
Usa grid cuando las filas y columnas deben alinearse entre sí: galerías de tarjetas, formularios con etiquetas alineadas, una página con encabezado, barra lateral y pie. Usa flexbox para una sola fila o columna cuyos elementos toman su tamaño de su contenido, como una barra de navegación.
¿grid-gap es lo mismo que gap?
Sí. grid-gap, grid-row-gap y grid-column-gap son los nombres antiguos. Los navegadores todavía los aceptan como alias, pero escribe gap, row-gap y column-gap, que también funcionan en flexbox.