CSS Grid
¿Qué es CSS Grid?
Grid Layout es un sistema de maquetación bidimensional: permite colocar elementos en filas y columnas simultáneamente. Es la herramienta adecuada para layouts de página, cuadrículas de tarjetas, o cualquier composición que tenga estructura tanto horizontal como vertical.
Al igual que Flexbox, Grid se activa en el contenedor:
.contenedor {
display: grid;
}
Sin más configuración, el grid coloca los hijos en una sola columna. Para que sea útil, hay que definir las columnas (y opcionalmente las filas).
Definir columnas y filas
grid-template-columns define cuántas columnas tiene el grid y el ancho de cada una. grid-template-rows hace lo mismo para las filas (aunque las filas suelen dejarse en auto para que se ajusten al contenido):
/* Tres columnas: fija, auto, fija */
.contenedor {
display: grid;
grid-template-columns: 200px auto 200px;
}
/* Tres columnas del mismo tamaño */
.contenedor {
display: grid;
grid-template-columns: 33% 33% 33%; /* aproximado */
}
/* Dos filas con altura definida */
.contenedor {
display: grid;
grid-template-rows: 80px auto;
}
La unidad fr
fr (fracción) representa una parte del espacio disponible después de restar los elementos con tamaños fijos. Es la unidad nativa de Grid:
/* Dos columnas que se reparten el espacio al 50% */
grid-template-columns: 1fr 1fr;
/* Columna lateral fija + contenido principal que ocupa el resto */
grid-template-columns: 250px 1fr;
/* Barra lateral + contenido + barra secundaria (proporciones 1:3:1) */
grid-template-columns: 1fr 3fr 1fr;
La ventaja sobre los porcentajes es que fr respeta los gaps: el espacio entre columnas no afecta al cálculo.
repeat() y minmax()
repeat() evita repetir el mismo valor varias veces:
/* Cuatro columnas iguales */
grid-template-columns: repeat(4, 1fr);
/* Equivale a: 1fr 1fr 1fr 1fr */
minmax(mínimo, máximo) define un rango de tamaño para una columna o fila: no menos del mínimo, no más del máximo:
/* Columnas que nunca son menores de 200px ni mayores de 1fr */
grid-template-columns: repeat(3, minmax(200px, 1fr));
Espacio entre celdas: gap
Funciona igual que en Flexbox: añade espacio entre los elementos del grid sin afectar a los bordes exteriores:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem; /* mismo espacio en filas y columnas */
gap: 1rem 2rem; /* filas | columnas */
}
Colocación de elementos
Por defecto, los hijos se colocan automáticamente en el grid, uno por celda. Puedes controlar explícitamente dónde va cada elemento y cuántas celdas ocupa:
.elemento {
grid-column: 1 / 3; /* desde la línea 1 hasta la línea 3 (ocupa 2 columnas) */
grid-row: 1 / 2; /* desde la línea 1 hasta la línea 2 (ocupa 1 fila) */
}
/* Forma alternativa: indicar cuántas celdas se expande */
.elemento {
grid-column: 1 / span 2; /* comienza en columna 1, se extiende 2 columnas */
grid-row: span 2; /* se extiende 2 filas desde su posición automática */
}
Las líneas del grid se numeran desde 1. También se pueden usar números negativos para contar desde el final: -1 es la última línea, -2 la penúltima, etc.
/* Elemento que ocupa todas las columnas */
.ancho-completo {
grid-column: 1 / -1;
}
Áreas con nombre: grid-template-areas
La característica más legible de Grid: defines la estructura visual del layout directamente en CSS, como un mapa:
.pagina {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
/* Asigna cada hijo a su área */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
<div class="pagina">
<header class="header">...</header>
<aside class="sidebar">...</aside>
<main class="main">...</main>
<footer class="footer">...</footer>
</div>
En la cadena de grid-template-areas, cada fila va entre comillas y los nombres separados por espacios representan las columnas. Un punto (.) significa celda vacía. Las áreas de más de una celda deben formar un rectángulo.
Colocación automática y auto-fit
La combinación de repeat() con auto-fit y minmax() crea cuadrículas responsivas sin media queries: el navegador coloca tantas columnas como quepan:
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
En pantallas anchas puede haber 4 o 5 columnas. En móvil, solo 1. Sin una sola media query.
auto-fill es similar pero mantiene columnas vacías si el contenido no las llena. auto-fit colapsa las vacías y estira las que hay. Para la mayoría de usos, auto-fit es el correcto.
Para filas de altura automática que se ajustan al contenido:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: minmax(150px, auto); /* mínimo 150px, crece con el contenido */
gap: 1rem;
}
Flexbox vs Grid: ¿cuándo usar cada uno?
No son excluyentes: se usan juntos, en distintos niveles de la misma página.
Usa Flexbox cuando el layout es principalmente en una dimensión: una barra de navegación, una fila de iconos, un grupo de botones, centrar un elemento en su contenedor.
Usa Grid cuando el layout es bidimensional: la estructura completa de la página, una cuadrícula de tarjetas, un calendario, cualquier composición donde las filas y las columnas deben alinearse entre sí.
Un patrón habitual: Grid para el layout general de la página, Flexbox para los componentes internos (la barra de navegación dentro del header, las acciones dentro de una tarjeta).
Recapitulación
display: gridactiva CSS Grid en el contenedor. Los hijos directos son grid items.grid-template-columnsdefine el número y ancho de las columnas.grid-template-rowshace lo mismo para las filas.- La unidad
frrepresenta una fracción del espacio disponible después de restar tamaños fijos. Es más robusta que los porcentajes con gaps. repeat(N, tamaño)repite una definición N veces.minmax(min, max)define un rango de tamaño.gapañade espacio entre celdas sin afectar a los bordes externos.grid-columnygrid-rowcolocan un elemento en posiciones concretas o lo extienden conspan.1 / -1ocupa todas las columnas.grid-template-areaspermite definir el layout como un mapa visual de nombres. Cada hijo se asigna congrid-area.repeat(auto-fit, minmax(X, 1fr))crea cuadrículas responsivas sin media queries.- Grid es bidimensional (filas y columnas). Flexbox es unidimensional (fila o columna). Se complementan y usan juntos en distintos niveles del layout.
Tu proyecto
Sustituye la tabla de proyectos por una cuadrícula de tarjetas. Cambia el HTML de la sección #proyectos y añade el CSS correspondiente:
<section id="proyectos">
<h2>Proyectos</h2>
<div class="grid-proyectos">
<div class="tarjeta">
<img src="imagenes/proyecto1.jpg" alt="Vivienda en el Retiro">
<h3>Vivienda en el Retiro</h3>
<p>Residencial · Madrid, 2023</p>
</div>
<div class="tarjeta">...</div>
<div class="tarjeta">...</div>
</div>
</section>
.grid-proyectos {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.5rem;
margin-top: 1.5rem;
}
.tarjeta img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
.tarjeta h3 {
font-size: 1rem;
font-weight: 600;
margin-top: 0.75rem;
}
.tarjeta p {
font-size: 0.85rem;
color: #888;
margin-top: 0.25rem;
}
La cuadrícula se adapta sola al ancho disponible gracias a auto-fit y minmax: en pantalla grande muestra tres columnas, en tablet dos, en móvil una. Sin una sola media query.
En la próxima lección: selectores avanzados: combinadores, pseudoclases de estado y estructura, y selectores de atributo.