En esta página

CSS Grid completo

15 min lectura TextoCap. 3 — Layout moderno

Qué es CSS Grid?

CSS Grid es un sistema de layout bidimensional que permite controlar filas y columnas al mismo tiempo. Mientras Flexbox maneja una sola dimensión, Grid te da control total sobre ambos ejes simultaneamente.

Se activa con display: grid en el contenedor padre.

Definir columnas y filas

grid-template-columns y grid-template-rows

Definen la estructura de la cuadricula:

.grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;  /* 3 columnas */
  grid-template-rows: auto 1fr auto;        /* 3 filas */
}

La unidad fr (fraccion)

fr representa una fraccion del espacio disponible. Es el equivalente a flex: 1 pero para Grid:

.grid {
  grid-template-columns: 1fr 2fr 1fr;
  /* Primera y tercera columna: 25% cada una */
  /* Segunda columna: 50% */
}

La función repeat()

Simplifica la declaración de tracks repetitivos:

.grid {
  grid-template-columns: repeat(4, 1fr);      /* 4 columnas iguales */
  grid-template-columns: repeat(3, 100px 1fr); /* Patron que se repite */
}

Grid areas: layout semántico

grid-template-areas permite definir el layout usando nombres, como un mapa visual:

.página {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "sidebar main   main"
    "footer  footer  footer";
  grid-template-columns: 250px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Usa un punto (.) para representar celdas vacias:

grid-template-areas:
  "header header header"
  ".      main   main"
  "footer footer footer";

Posicionar items manualmente

Puedes colocar items en celdas especificas usando números de linea:

.destacado {
  grid-column: 1 / 3;  /* De la linea 1 a la 3 (ocupa 2 columnas) */
  grid-row: 1 / 2;     /* Primera fila */
}

/* O con span */
.ancho {
  grid-column: span 2;  /* Ocupa 2 columnas desde donde esta */
}

Layouts responsivos automaticos

minmax() + auto-fill

La combinación más poderosa de Grid para layouts responsivos sin media queries:

.grid-responsivo {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

Esto crea tantas columnas como quepan con un mínimo de 280px cada una. Si solo cabe una columna, ocupa el 100%.

auto-fill vs auto-fit

  • auto-fill: crea columnas aunque esten vacias
  • auto-fit: colapsa las columnas vacias para que las items se estiren
/* 3 items en un contenedor de 1200px con minmax(200px, 1fr) */
/* auto-fill: crea 6 columnas, 3 vacias */
/* auto-fit: crea 3 columnas que se estiran a 400px cada una */

Gap: espaciado entre celdas

.grid {
  gap: 1rem;          /* Mismo gap en filas y columnas */
  gap: 1rem 2rem;     /* 1rem entre filas, 2rem entre columnas */
  row-gap: 1rem;      /* Solo filas */
  column-gap: 2rem;   /* Solo columnas */
}

Alineacion en Grid

Alinear el contenido de las celdas

Propiedad Eje Aplica a
justify-items Horizontal Todos los items
align-items Vertical Todos los items
place-items Ambos Shorthand (align / justify)

Alinear items individuales

Propiedad Eje
justify-self Horizontal (un solo item)
align-self Vertical (un solo item)
place-self Ambos (shorthand)

Alinear la cuadricula completa

Si la cuadricula es más pequeña que su contenedor:

Propiedad Eje
justify-content Horizontal (toda la cuadricula)
align-content Vertical (toda la cuadricula)

Subgrid

subgrid permite que un item hijo herede las tracks (filas o columnas) de su grid padre. Esto es esencial para alinear contenido entre cards hermanas:

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
}

Con subgrid, los títulos de todas las cards se alinean a la misma altura, sin importar la longitud del texto.


Ahora que dominas Grid y Flexbox, es momento de aprender a hacer que tus layouts se adapten a cualquier pantalla con responsive design.

Práctica

  1. Construye un layout de pagina con grid-template-areas: Crea un layout con header, sidebar, main y footer usando grid-template-areas. Asigna cada seccion a su area correspondiente.
  2. Crea una galeria responsiva: Usa repeat(auto-fill, minmax(250px, 1fr)) para construir una galeria de imagenes que se adapte automaticamente al ancho del contenedor.
  3. Experimenta con subgrid: Crea un grid de 3 tarjetas con subgrid en las filas para que los titulos y descripciones de todas las tarjetas se alineen a la misma altura.
Flexbox vs Grid
Usa Flexbox cuando el contenido define el layout (una fila de botones, una navbar). Usa Grid cuando TU defines el layout (página con header, sidebar, main, footer). Ambos se complementan, no compiten.
auto-fill vs auto-fit
auto-fill crea tantas columnas como quepan, dejando espacio vacio si sobra. auto-fit colapsa las columnas vacias para que las existentes se estiren. Usa auto-fill para galerias y auto-fit cuando quieras que los items se expandan.
/* Layout de página completa con Grid */
.página {
  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;
  gap: 0;
}

.header  { grid-area: header;  background: #1a1a2e; color: white; padding: 1rem; }
.sidebar { grid-area: sidebar; background: #f5f5f5; padding: 1rem; }
.main    { grid-area: main;    padding: 2rem; }
.footer  { grid-area: footer;  background: #1a1a2e; color: white; padding: 1rem; }

/* Galeria responsiva con auto-fill */
.galeria {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
  padding: 1rem;
}

.galeria > img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
}
/* Subgrid: heredar las tracks del padre */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

.card {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3; /* Ocupa 3 filas del padre */
  border: 1px solid #ddd;
  border-radius: 12px;
  overflow: hidden;
}

.card > img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
}

.card > h3 { padding: 0 1rem; }
.card > p  { padding: 0 1rem 1rem; }