Saltar al contenido

CSS, de a poco

Curso de CSS

Grid

Lección 12 de 37 · 4 min

Grid acomoda los hijos de una caja en columnas y filas a la vez. Vos definís las columnas y el navegador reparte el espacio.

Columnas y gap

Con display: grid la caja se vuelve una grilla, y cada hijo directo ocupa una celda. Dos propiedades alcanzan para empezar:

  1. Columnasgrid-template-columnsLa lista de columnas, un tamaño por columna. Las filas se crean solas, a medida que hacen falta.
  2. EspaciogapEl espacio entre columnas y entre filas. Va solo entre celdas, nunca contra el borde de la grilla.

Elegí una plantilla y mové el gap en el menú del café: la regla naranja de arriba marca el ancho de cada columna, y el rayado entre platos es el gap.

display: grid3 columnas de 88px · gap 12px
grid-template-columns
menu.css
.menu {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 12px;
}
menu.html
<ul class="grid grid-cols-3 gap-3">
<li>Latte</li>
<li>Bowl</li>
<li>Crepes</li>
<li>Salmón</li>
<li>Parfait</li>
<li>Scon</li>
</ul>

La grilla mide 288px. Con 1fr 1fr 1fr y un gap de 12px quedan 264px para repartir, así que cada columna mide 88px. Los seis platos llenan la primera fila y siguen en la segunda, en orden.

La unidad fr

fr es una fracción del espacio libre: lo que sobra después de restar las columnas de tamaño fijo y los gaps. El navegador suma los fr y reparte en proporción. En la grilla de 288px con gap de 12px:

  1. Proporción1fr 2frSobran 276px. Hay 3fr en total, así que la primera columna se lleva un tercio, 92px, y la segunda dos tercios, 184px.
  2. Fijo y flexible200px 1frLa primera mide 200px fijos y la segunda se queda con el resto, 288 − 200 − 12 = 76px.
Dos grillas de 288px con gap de 12px. Con 1fr 2fr sobran 276px: la primera columna mide 92px y la segunda 184px. Con 200px 1fr la primera mide 200px fijos y la segunda se queda con 76px.

repeat() evita escribir lo mismo varias veces: repeat(3, 1fr) equivale a 1fr 1fr 1fr. minmax() le pone un mínimo y un máximo a una columna. Juntos arman una grilla que se adapta al ancho sin media queries:

grilla.css
.grilla {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
gap: 12px;
}

auto-fill crea tantas columnas como entren: en la demo, 3 de 88px con gap de 12px, y 4 con un gap de 10px o menos. auto-fit hace lo mismo, pero colapsa las columnas que quedan vacías y las celdas se estiran para ocupar la fila. Un detalle: 1fr no se achica por debajo del ancho mínimo de su contenido, como una palabra larga; si necesitás que sí, usá minmax(0, 1fr).

Ubicar elementos

Las columnas están separadas por líneas numeradas desde 1: tres columnas tienen cuatro líneas. También se cuentan desde el final con números negativos, y -1 es la última. grid-column dice entre qué líneas va un elemento, y grid-row hace lo mismo con las filas. Con span indicás cuántas columnas o filas ocupa.

Una grilla de tres columnas de 88px con gaps de 12px, vista en perspectiva. Las líneas de columna van numeradas de 1 a 4, y la 4 también es la -1. Un elemento con grid-column: span 2 ocupa dos pistas y el gap entre ellas.
ubicar.css
/* de la primera a la última línea: toda la fila */
.titulo { grid-column: 1 / -1; }
/* dos columnas, desde donde le toque */
.destacado { grid-column: span 2; }
/* de la línea 1 a la 3: dos filas */
.lateral { grid-row: 1 / 3; }

Para el layout de una página, grid-template-areas deja dibujar la grilla con nombres. Cada string es una fila, un nombre repetido ocupa varias celdas y cada elemento elige su área con grid-area. Las áreas tienen que ser rectángulos.

pagina.css
.pagina {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas:
"cabecera cabecera"
"lateral contenido";
gap: 12px;
}
.cabecera { grid-area: cabecera; }
.lateral { grid-area: lateral; }
.contenido { grid-area: contenido; }

En Tailwind

En Tailwind la grilla se arma con clases en el contenedor y en los hijos. Los valores que no están en la escala van entre corchetes, con guiones bajos en lugar de espacios: 200px 1fr se escribe grid-cols-[200px_1fr]. El gap usa la escala de espaciado, donde cada paso vale 4px.

CSSTailwind
display: gridgrid
repeat(3, minmax(0, 1fr))grid-cols-3
1fr 2frgrid-cols-[1fr_2fr]
gap: 12px · por ejegap-3 · gap-x-3 · gap-y-3 · gap-[7px]
grid-column: span 2 · 1 / -1col-span-2 · col-span-full
grid-column-start: 2 · end: 4col-start-2 col-end-4
grid-row: span 2 · 1 / 3row-span-2 · row-start-1 row-end-3
pagina.html
<div class="grid grid-cols-[200px_1fr] gap-3
[grid-template-areas:'cabecera_cabecera'_'lateral_contenido']">
<header class="[grid-area:cabecera]">…</header>
<aside class="[grid-area:lateral]">…</aside>
<main class="[grid-area:contenido] grid gap-3
grid-cols-[repeat(auto-fill,minmax(64px,1fr))]">
<h2 class="col-span-full">Fotos</h2>
<img class="col-span-2 row-span-2" src="destacada.jpg" alt="" />
<img src="1.jpg" alt="" />
</main>
</div>