Módulo 11: CSS Grid
Objetivos del módulo
- Entender qué es CSS Grid y su vocabulario: líneas, pistas, celdas y áreas
- Saber cuándo usar Grid y cuándo Flexbox
- Definir columnas y filas con
grid-template-columnsygrid-template-rows - Dominar la unidad
fry las funcionesrepeat()yminmax() - Crear rejillas responsive sin media queries con
auto-fillyauto-fit - Colocar elementos por líneas y con áreas con nombre
- Controlar el grid implícito y el autoposicionamiento
- Alinear ítems y pistas en ambos ejes
- Usar
subgridpara alinear contenido entre componentes - Construir layouts completos y depurarlos con DevTools
1. ¿Qué es CSS Grid?
CSS Grid Layout es un sistema de maquetación bidimensional: controla filas y columnas a la vez. Mientras que Flexbox coloca elementos en una línea, Grid define una rejilla completa y te permite colocar cada elemento exactamente en la celda o zona que quieras.
📘 Concepto: Piensa en una hoja de cálculo o en el plano de un edificio. Primero dibujas la cuadrícula (cuántas columnas y filas, de qué tamaño) y después decides qué ocupa cada zona: “la cabecera ocupa toda la fila de arriba, el menú la columna izquierda, el contenido el centro…”. Los elementos se adaptan a la estructura, no al revés.
Vocabulario de Grid
línea 1 línea 2 línea 3 línea 4 ← líneas de columna
│ │ │ │
línea 1 ──┼─────────┼─────────┼─────────┼──
│ celda │ │ │ ← pista de fila 1
línea 2 ──┼─────────┼─────────┼─────────┼──
│ │ área de 2×2 │ ← pista de fila 2
│ │ (varias celdas) │
línea 3 ──┼─────────┤ ├──
│ │ │ ← pista de fila 3
línea 4 ──┼─────────┼─────────┼─────────┼──
│ pista │
│ de │ (los huecos entre pistas son el gap)
│ columna │
| Término | Qué es |
|---|---|
| Contenedor grid | El elemento con display: grid |
| Ítem grid | Cada hijo directo del contenedor |
| Línea | Las divisiones horizontales y verticales de la rejilla. Se numeran desde 1 |
| Pista (track) | El espacio entre dos líneas consecutivas: una columna o una fila |
| Celda | La intersección de una fila y una columna: la unidad mínima |
| Área | Un rectángulo formado por una o varias celdas |
| Hueco (gap) | La separación entre pistas |
⚠️ Importante: Una rejilla de 3 columnas tiene 4 líneas de columna. Las líneas se cuentan en los bordes de las pistas, no en las pistas. Este detalle es clave para colocar elementos.
2. Grid frente a Flexbox
| Aspecto | Flexbox | Grid |
|---|---|---|
| Dimensiones | Una (fila o columna) | Dos (filas y columnas) |
| Enfoque | Desde el contenido hacia fuera: el contenido decide el tamaño | Desde la estructura hacia dentro: la rejilla decide el tamaño |
| Alineación entre filas | Cada línea es independiente | Las columnas se alinean en todas las filas |
| Colocación | Secuencial (con order) | En cualquier celda, con solapamientos si quieres |
| Ideal para | Menús, barras de botones, componentes, centrar | Layout de página, galerías, paneles, formularios complejos |
💡 Consejo: No son rivales, se combinan. Lo habitual es usar Grid para la estructura general de la página (cabecera, menú, contenido, pie) y Flexbox dentro de cada componente (los enlaces del menú, el contenido de una tarjeta). Pregúntate: “¿necesito controlar filas y columnas a la vez?”. Si la respuesta es sí, Grid.
3. Definir la rejilla
<div class="rejilla">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
.rejilla {
display: grid;
grid-template-columns: 200px 300px 200px; /* 3 columnas: tamaño de cada una */
grid-template-rows: 100px 150px; /* 2 filas */
gap: 1rem;
}
.item {
padding: 1rem;
background-color: #ddd6fe;
border: 1px solid #7c3aed;
}
Los ítems se colocan automáticamente, uno por celda, de izquierda a derecha y de arriba a abajo. No necesitas indicarle nada a cada ítem.
Puedes mezclar unidades:
.rejilla {
display: grid;
grid-template-columns: 250px auto 20%; /* fija | se adapta al contenido | porcentaje */
}
📘 Concepto: Igual que en Flexbox, solo los hijos directos son ítems grid. Y
display: inline-gridcrea un contenedor grid que se comporta como elemento en línea.
4. La unidad fr
fr (fracción) representa una parte del espacio libre del contenedor. Es la unidad estrella de Grid.
.tres-iguales { grid-template-columns: 1fr 1fr 1fr; } /* tres columnas iguales */
.central-doble { grid-template-columns: 1fr 2fr 1fr; } /* la central, el doble */
.lateral-fija { grid-template-columns: 250px 1fr; } /* barra de 250px + resto */
.mixta { grid-template-columns: 200px 1fr 2fr; }
💻 Ejemplo: Contenedor de 1000px con
grid-template-columns: 200px 1fr 2frygap: 20px. Primero se restan las partes fijas: 1000 − 200 − 2 × 20 (dos huecos) = 760px libres. Se dividen en 1 + 2 = 3 fracciones de 253,33px. Resultado: 200px, 253px y 507px.
¿Por qué fr y no porcentajes?
/* ✗ Con porcentajes + gap: 33.33% × 3 + 2 huecos > 100 % → desbordamiento */
.mal { grid-template-columns: 33.33% 33.33% 33.33%; gap: 20px; }
/* ✓ Con fr: el gap se descuenta primero y las columnas se reparten el resto */
.bien { grid-template-columns: 1fr 1fr 1fr; gap: 20px; }
5. repeat() y minmax()
repeat()
Evita escribir el mismo valor muchas veces:
.doce-columnas { grid-template-columns: repeat(12, 1fr); } /* rejilla de 12 columnas */
.patron { grid-template-columns: repeat(3, 100px 1fr); } /* 100px 1fr 100px 1fr 100px 1fr */
.mixto { grid-template-columns: 200px repeat(3, 1fr); } /* fija + tres iguales */
minmax(mínimo, máximo)
Define un tamaño que nunca bajará del mínimo ni superará el máximo:
.rejilla {
grid-template-columns: minmax(200px, 300px) 1fr; /* la primera entre 200 y 300px */
grid-auto-rows: minmax(150px, auto); /* filas de al menos 150px; crecen si hace falta */
}
💡 Consejo:
minmax(150px, auto)en filas es muy útil: garantiza una altura mínima homogénea, pero si una tarjeta tiene más texto, su fila crece y no se desborda.
6. auto-fill y auto-fit: rejillas responsive sin media queries
Esta es probablemente la línea de CSS más útil de todo el curso:
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
Se lee así: “crea tantas columnas como quepan, cada una de al menos 250px y, si sobra espacio, estíralas por igual”. En un móvil habrá 1 columna; en una tableta, 2 o 3; en un monitor grande, 5 o 6. Sin una sola media query.
La diferencia entre auto-fill y auto-fit
Solo se nota cuando hay pocos ítems y sobra espacio para más columnas:
Contenedor de 1200px, minmax(200px, 1fr), solo 3 ítems:
auto-fill: [ 1 ][ 2 ][ 3 ][ ][ ][ ] ← crea 6 columnas; 3 quedan vacías
auto-fit: [ 1 ][ 2 ][ 3 ] ← colapsa las vacías; los ítems se estiran
| Palabra clave | Columnas vacías | Resultado con pocos ítems |
|---|---|---|
auto-fill | Se mantienen (ocupan espacio) | Los ítems conservan el tamaño de una columna |
auto-fit | Se colapsan a 0 | Los ítems se estiran para llenar la fila |
⚠️ Importante: Si el mínimo de
minmax()es mayor que el ancho de la pantalla (por ejemplo, 350px en un móvil de 320px), la columna desborda. La versión a prueba de todo esrepeat(auto-fit, minmax(min(250px, 100%), 1fr)): el mínimo nunca superará el 100 % del contenedor.
7. gap
.rejilla {
gap: 1rem; /* filas y columnas */
gap: 2rem 1rem; /* row-gap | column-gap */
row-gap: 2rem;
column-gap: 1rem;
}
El hueco solo aparece entre pistas, nunca en los bordes exteriores del contenedor. (Quizá lo veas escrito como grid-gap en código antiguo: es el nombre obsoleto.)
8. Colocar ítems por líneas
Por defecto los ítems se colocan solos, pero puedes indicar exactamente entre qué líneas va cada uno.
.destacado {
grid-column-start: 1;
grid-column-end: 3; /* de la línea 1 a la 3: ocupa 2 columnas */
grid-row-start: 1;
grid-row-end: 2;
}
/* Abreviada: inicio / fin */
.destacado {
grid-column: 1 / 3;
grid-row: 1 / 2;
}
span: ocupar N pistas
.ancho { grid-column: span 2; } /* ocupa 2 columnas desde donde le toque */
.alto { grid-row: span 3; } /* ocupa 3 filas */
.desde-2 { grid-column: 2 / span 3; } /* empieza en la línea 2 y ocupa 3 columnas */
Líneas negativas
Las líneas también se cuentan desde el final con números negativos: -1 es la última línea.
.cabecera { grid-column: 1 / -1; } /* de la primera a la última línea: todo el ancho */
💡 Consejo:
grid-column: 1 / -1es el modo más robusto de hacer que algo ocupe toda la fila: funciona aunque cambies el número de columnas.
La abreviada grid-area con líneas
/* grid-area: fila-inicio / columna-inicio / fila-fin / columna-fin */
.zona { grid-area: 1 / 2 / 3 / 4; }
Líneas con nombre
Puedes poner nombre a las líneas entre corchetes y usarlos al colocar:
.pagina {
display: grid;
grid-template-columns:
[completo-start] 1fr
[contenido-start] minmax(0, 60rem)
[contenido-end] 1fr
[completo-end];
}
.pagina > * { grid-column: contenido; } /* todo el contenido, en la columna central */
.pagina > .ancho { grid-column: completo; } /* las imágenes destacadas, a todo el ancho */
📘 Concepto: Al nombrar dos líneas como
contenido-startycontenido-end, Grid crea automáticamente un área implícita llamadacontenido, que puedes usar directamente engrid-column: contenido. Para que funcione, los sufijos tienen que ser exactamente-starty-end(en inglés); con cualquier otro nombre tendrías que escribirgrid-column: mi-linea-a / mi-linea-b.
Solapamientos
En Grid, varios ítems pueden ocupar las mismas celdas. Se apilan según el orden del HTML y puedes controlarlo con z-index (sin necesidad de position):
.portada { display: grid; }
.portada > img,
.portada > .texto { grid-area: 1 / 1; } /* ambos en la misma celda */
.portada > .texto { z-index: 1; align-self: end; padding: 2rem; color: white; }
9. Áreas con nombre: grid-template-areas
La forma más visual de definir un layout: dibujas la rejilla con nombres.
<div class="layout">
<header class="cabecera">Cabecera</header>
<nav class="menu">Menú</nav>
<main class="contenido">Contenido</main>
<aside class="lateral">Lateral</aside>
<footer class="pie">Pie</footer>
</div>
.layout {
display: grid;
grid-template-columns: 200px 1fr 250px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"cabecera cabecera cabecera"
"menu contenido lateral"
"pie pie pie";
gap: 1rem;
min-height: 100dvh;
}
/* Cada ítem se asigna a su área por nombre (sin comillas) */
.cabecera { grid-area: cabecera; }
.menu { grid-area: menu; }
.contenido { grid-area: contenido; }
.lateral { grid-area: lateral; }
.pie { grid-area: pie; }
Reglas de grid-template-areas:
- Cada cadena entre comillas es una fila; cada palabra, una columna.
- Todas las filas deben tener el mismo número de columnas.
- Repetir un nombre hace que el área ocupe varias celdas, pero el área debe ser rectangular (no puedes hacer formas en “L”).
- Un punto
.(o varios seguidos,...) representa una celda vacía.
.con-huecos {
grid-template-areas:
"logo . buscar"
"menu menu menu";
}
Cambiar el layout es redibujar el mapa
La gran ventaja: para la versión móvil solo cambias el dibujo, sin tocar el HTML ni los ítems:
/* Móvil: todo en una columna */
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"cabecera"
"menu"
"contenido"
"lateral"
"pie";
}
/* A partir de 900px: tres columnas (media queries en el módulo 12) */
@media (width >= 900px) {
.layout {
grid-template-columns: 200px 1fr 250px;
grid-template-areas:
"cabecera cabecera cabecera"
"menu contenido lateral"
"pie pie pie";
}
}
10. El grid implícito
Si defines 2 filas pero hay ítems para 5, Grid crea las filas que falten automáticamente: es el grid implícito. Por defecto, esas filas tienen tamaño auto.
.rejilla {
display: grid;
grid-template-columns: repeat(3, 1fr); /* columnas explícitas */
grid-auto-rows: 200px; /* tamaño de las filas que se creen solas */
}
.rejilla-flexible {
grid-auto-rows: minmax(150px, auto); /* al menos 150px, crecen con el contenido */
}
| Propiedad | Controla |
|---|---|
grid-template-rows / -columns | Pistas explícitas (las que defines tú) |
grid-auto-rows / -columns | Tamaño de las pistas implícitas (las que crea Grid) |
grid-auto-flow | Cómo se colocan los ítems automáticamente |
grid-auto-flow
| Valor | Efecto |
|---|---|
row | Por defecto: rellena fila a fila, creando filas nuevas |
column | Rellena columna a columna, creando columnas nuevas |
dense | Rellena los huecos que quedan atrás con ítems posteriores que quepan |
row dense / column dense | Combinaciones |
Galería tipo mosaico con dense
<div class="mosaico">
<img src="1.jpg" alt="..." class="grande">
<img src="2.jpg" alt="...">
<img src="3.jpg" alt="..." class="horizontal">
<img src="4.jpg" alt="...">
<img src="5.jpg" alt="..." class="vertical">
<img src="6.jpg" alt="...">
<img src="7.jpg" alt="...">
</div>
.mosaico {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-auto-rows: 150px;
grid-auto-flow: dense; /* sin esto quedarían huecos cuando un ítem grande no cabe */
gap: 0.5rem;
}
.mosaico img { width: 100%; height: 100%; object-fit: cover; }
.horizontal { grid-column: span 2; }
.vertical { grid-row: span 2; }
.grande { grid-column: span 2; grid-row: span 2; }
⚠️ Importante:
densecambia el orden visual de los ítems respecto al HTML. Es perfecto para galerías de imágenes, pero no lo uses cuando el orden importe (artículos numerados, pasos de un proceso), por accesibilidad.
11. Alineación en Grid
Grid usa las mismas palabras que Flexbox, pero con dos ejes fijos: inline (horizontal, justify-*) y block (vertical, align-*).
| Propiedad | Se aplica en | Alinea… | Eje |
|---|---|---|---|
justify-items | Contenedor | Todos los ítems dentro de su celda | Horizontal |
align-items | Contenedor | Todos los ítems dentro de su celda | Vertical |
place-items | Contenedor | Abreviada: align-items justify-items | Ambos |
justify-self | Ítem | Un ítem dentro de su celda | Horizontal |
align-self | Ítem | Un ítem dentro de su celda | Vertical |
place-self | Ítem | Abreviada | Ambos |
justify-content | Contenedor | Toda la rejilla dentro del contenedor (si sobra espacio) | Horizontal |
align-content | Contenedor | Toda la rejilla dentro del contenedor | Vertical |
place-content | Contenedor | Abreviada | Ambos |
Valores habituales: stretch (por defecto en ítems), start, end, center; y para *-content también space-between, space-around y space-evenly.
/* Centrado perfecto con Grid: ¡dos líneas! */
.centrar {
display: grid;
place-items: center;
min-height: 100dvh;
}
/* Iconos centrados en sus celdas */
.iconos {
display: grid;
grid-template-columns: repeat(4, 80px);
justify-items: center;
align-items: center;
}
/* Un ítem concreto, abajo a la derecha de su celda */
.firma { justify-self: end; align-self: end; }
💡 Consejo: Recuerda la diferencia:
*-itemsmueve cada ítem dentro de su celda;*-contentmueve las pistas completas dentro del contenedor, y solo tiene efecto si la rejilla es más pequeña que el contenedor (por ejemplo, con columnas enpx).
12. subgrid
Un ítem grid puede ser a su vez un contenedor grid, pero su rejilla interna es independiente de la del padre. Con subgrid, el hijo hereda las pistas del padre, de modo que su contenido se alinea con el de sus hermanos.
El caso de uso clásico: una fila de tarjetas con título, texto y botón. Si los títulos tienen longitudes distintas, los textos empiezan a distintas alturas. Con subgrid, todos los títulos, textos y botones quedan perfectamente alineados entre tarjetas:
<div class="tarjetas">
<article class="tarjeta">
<h3>Plan básico</h3>
<p>Para empezar.</p>
<a href="#">Elegir</a>
</article>
<article class="tarjeta">
<h3>Plan profesional con soporte prioritario</h3>
<p>Incluye todo lo del plan básico y además informes avanzados, copias diarias y un gestor dedicado.</p>
<a href="#">Elegir</a>
</article>
<article class="tarjeta">
<h3>Empresa</h3>
<p>Para equipos grandes.</p>
<a href="#">Elegir</a>
</article>
</div>
.tarjetas {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1.5rem;
}
.tarjeta {
grid-row: span 3; /* cada tarjeta ocupa 3 filas del padre... */
display: grid;
grid-template-rows: subgrid; /* ...y usa esas mismas 3 filas para su contenido */
gap: 0.75rem;
padding: 1.5rem;
border: 1px solid #e2e8f0;
border-radius: 12px;
}
.tarjeta a { align-self: end; } /* botón abajo */
📘 Concepto: La fila de los títulos mide lo que necesita el título más largo de toda la fila de tarjetas, y lo mismo con los textos. Así, todos los párrafos empiezan a la misma altura y todos los botones quedan alineados.
subgridfunciona en todos los navegadores actuales, tanto en filas como en columnas.
13. Layouts completos
13.1. Página típica con cabecera, contenido, lateral y pie
.sitio {
display: grid;
min-height: 100dvh;
grid-template-rows: auto 1fr auto; /* cabecera | contenido (crece) | pie */
grid-template-columns: minmax(0, 1fr);
grid-template-areas:
"cabecera"
"principal"
"pie";
}
.sitio__cabecera { grid-area: cabecera; }
.sitio__principal { grid-area: principal; }
.sitio__pie { grid-area: pie; }
/* Dentro del contenido principal: artículo + barra lateral */
.sitio__principal {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 2rem;
width: min(100% - 2rem, 1200px);
margin-inline: auto;
padding-block: 2rem;
}
@media (width >= 900px) {
.sitio__principal {
grid-template-columns: minmax(0, 1fr) 300px; /* artículo flexible + lateral fijo */
}
}
💡 Consejo:
minmax(0, 1fr)en lugar de1frevita un problema parecido almin-width: autode Flexbox: una columna1frno encoge por debajo de su contenido más ancho (una tabla, un bloque de código, una URL), y puede desbordar. Conminmax(0, 1fr), sí encoge.
13.2. Galería responsive sin media queries
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
gap: 1rem;
}
.galeria figure {
margin: 0;
}
.galeria img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
border-radius: 8px;
}
13.3. Panel de control (dashboard)
<div class="dashboard">
<aside class="d-menu">Menú</aside>
<header class="d-barra">Barra superior</header>
<section class="d-kpi">Ventas</section>
<section class="d-kpi">Usuarios</section>
<section class="d-kpi">Pedidos</section>
<section class="d-kpi">Ingresos</section>
<section class="d-grafico">Gráfico principal</section>
<section class="d-actividad">Actividad reciente</section>
<section class="d-tabla">Últimos pedidos</section>
</div>
.dashboard {
display: grid;
min-height: 100dvh;
grid-template-columns: 240px repeat(4, minmax(0, 1fr));
grid-template-rows: 64px 120px minmax(300px, auto) auto;
grid-template-areas:
"menu barra barra barra barra"
"menu . . . ."
"menu grafico grafico grafico actividad"
"menu tabla tabla tabla tabla";
gap: 1rem;
padding: 1rem;
background-color: #f1f5f9;
}
.d-menu { grid-area: menu; }
.d-barra { grid-area: barra; }
.d-grafico { grid-area: grafico; }
.d-actividad { grid-area: actividad; }
.d-tabla { grid-area: tabla; }
/* Los cuatro .d-kpi no tienen área: se colocan solos en las celdas vacías (".") de la fila 2 */
.dashboard > * {
padding: 1rem;
background-color: white;
border-radius: 12px;
box-shadow: 0 1px 3px rgb(0 0 0 / 0.1);
}
📘 Concepto: Fíjate en el truco de las tarjetas KPI: no les asignamos área. El algoritmo de autoposicionamiento las coloca en las primeras celdas libres, que son precisamente las cuatro marcadas con
.en la segunda fila. Si añades una quinta tarjeta, Grid creará una fila implícita al final.
14. Depurar Grid con DevTools
Las DevTools de Chrome, Edge y Firefox tienen herramientas excelentes para Grid (Firefox fue pionero en esto):
- En el panel Elements, junto a cada contenedor grid aparece una insignia
grid. Púlsala para superponer la rejilla sobre la página. - En la pestaña Layout puedes activar varias rejillas a la vez y elegir qué mostrar:
- Números de línea (positivos y negativos).
- Nombres de líneas y nombres de áreas (dibuja el mapa de
grid-template-areassobre la página). - Tamaños de pista, para ver cuánto ha calculado cada
fr. - Extender las líneas hasta el borde de la ventana.
- Junto a
display: griden Styles hay un icono que abre un editor visual de alineación.
💡 Consejo: Cuando un ítem “no aparece donde esperas”, activa la superposición con números de línea. El 90 % de las veces es un error de conteo: recuerda que 3 columnas tienen 4 líneas, y que
spancuenta pistas, no líneas.
15. Ejercicios
Ejercicio 1: Primeras rejillas
Crea tres contenedores con 6 ítems cada uno: el primero con 3 columnas de 200px; el segundo con 1fr 2fr 1fr; el tercero con 250px 1fr (barra lateral fija). Añade gap: 1rem y comprueba con la superposición de DevTools los tamaños calculados.
Ejercicio 2: Galería sin media queries
Crea una galería de 12 imágenes con repeat(auto-fit, minmax(min(200px, 100%), 1fr)), imágenes con aspect-ratio: 1 y object-fit: cover. Redimensiona la ventana y anota cuántas columnas hay en cada ancho. Después deja solo 3 imágenes y compara auto-fit con auto-fill en una pantalla ancha.
Ejercicio 3: Colocación por líneas
En una rejilla de 4 columnas y 3 filas, coloca: un ítem que ocupe toda la primera fila (1 / -1); otro que ocupe 2 columnas y 2 filas en la esquina inferior izquierda; y un tercero que se solape parcialmente con el anterior y quede por encima con z-index.
Ejercicio 4: Layout con áreas
Maqueta una página con cabecera, navegación, contenido, barra lateral, zona de anuncios y pie usando grid-template-areas. Diseña tres mapas distintos: móvil (una columna), tableta (dos columnas, con la barra lateral debajo del contenido) y escritorio (tres columnas). Cambia solo el mapa en cada media query.
Ejercicio 5: Mosaico con dense
Crea un mosaico de 15 imágenes en el que algunas ocupen 2 columnas, otras 2 filas y otras 2×2. Compara el resultado con y sin grid-auto-flow: dense y explica qué ocurre con el orden.
Ejercicio 6: Tarjetas alineadas con subgrid
Crea 4 tarjetas de blog con imagen, categoría, título (de longitudes muy distintas), resumen y enlace “Leer más”. Primero hazlo sin subgrid y observa el desalineamiento. Después aplica grid-row: span 5 y grid-template-rows: subgrid y comprueba que todas las partes quedan alineadas entre tarjetas.
Ejercicio 7: Dashboard
Construye el panel de control de la sección 13.3 y añade: una versión para tableta donde el menú lateral pase a ser una barra superior, y una versión móvil con una sola columna. Usa minmax(0, 1fr) en las columnas y comprueba que una tabla ancha dentro de “Últimos pedidos” no rompe el diseño (envuélvela en un contenedor con overflow-x: auto).
Resumen
| Concepto | Sintaxis / idea clave |
|---|---|
| Activar Grid | display: grid en el padre |
| Columnas y filas | grid-template-columns: 200px 1fr 2fr; grid-template-rows: auto 1fr auto; |
| Fracción | fr: parte del espacio libre (tras restar fijos y huecos) |
| Repetir | repeat(12, 1fr) |
| Límites | minmax(200px, 1fr); minmax(0, 1fr) para evitar desbordes |
| Responsive automático | repeat(auto-fit, minmax(min(250px, 100%), 1fr)) |
auto-fill / auto-fit | Mantener columnas vacías / colapsarlas |
| Separación | gap: fila columna |
| Por líneas | grid-column: 1 / 3; grid-row: span 2; grid-column: 1 / -1; |
| Áreas | grid-template-areas: "a a" "b c"; + grid-area: a; |
| Grid implícito | grid-auto-rows: minmax(150px, auto); |
| Autoposicionamiento | grid-auto-flow: row \| column \| dense |
| Alinear ítems | justify-items, align-items, place-items: center |
| Alinear un ítem | justify-self, align-self, place-self |
| Alinear la rejilla | justify-content, align-content, place-content |
| Subgrid | grid-template-rows: subgrid; en un ítem que ocupa varias pistas |