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-columns y grid-template-rows
  • Dominar la unidad fr y las funciones repeat() y minmax()
  • Crear rejillas responsive sin media queries con auto-fill y auto-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 subgrid para 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-grid crea 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 2fr y gap: 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 es repeat(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 / -1 es 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-start y contenido-end, Grid crea automáticamente un área implícita llamada contenido, que puedes usar directamente en grid-column: contenido. Para que funcione, los sufijos tienen que ser exactamente -start y -end (en inglés); con cualquier otro nombre tendrías que escribir grid-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: dense cambia 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: *-items mueve cada ítem dentro de su celda; *-content mueve 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 en px).


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. subgrid funciona 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 de 1fr evita un problema parecido al min-width: auto de Flexbox: una columna 1fr no encoge por debajo de su contenido más ancho (una tabla, un bloque de código, una URL), y puede desbordar. Con minmax(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):

  1. En el panel Elements, junto a cada contenedor grid aparece una insignia grid. Púlsala para superponer la rejilla sobre la página.
  2. 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-areas sobre 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.
  3. Junto a display: grid en 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 span cuenta 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