CSS Grid para crear layouts y estructuras

Intermedio
CSS
CSS
Actualizado: 26/08/2025

Grid container y grid items

CSS Grid es un sistema de layout bidimensional que permite crear diseños complejos de manera intuitiva y eficiente. Para comenzar a trabajar con Grid, es fundamental comprender la relación básica entre dos conceptos clave: el contenedor grid (grid container) y los elementos grid (grid items).

El grid container

El grid container es el elemento padre que actúa como contenedor de toda la estructura grid. Para convertir cualquier elemento HTML en un grid container, simplemente aplicamos la propiedad display: grid.

.container {
  display: grid;
}

Una vez que un elemento se convierte en grid container, automáticamente establece un nuevo contexto de formato que afecta directamente a todos sus hijos inmediatos. Este comportamiento es similar a como funciona Flexbox, pero con capacidades bidimensionales.

Ejemplo básico de grid container:

<div class="gallery">
  <div class="item">Imagen 1</div>
  <div class="item">Imagen 2</div>
  <div class="item">Imagen 3</div>
  <div class="item">Imagen 4</div>
</div>
.gallery {
  display: grid;
  /* El contenedor ahora es un grid container */
  background-color: #f0f0f0;
  padding: 20px;
  gap: 10px; /* Espaciado entre elementos */
}

.item {
  background-color: #3498db;
  color: white;
  padding: 20px;
  text-align: center;
}

Los grid items

Los grid items son todos los elementos hijos directos del grid container. Estos elementos se posicionan automáticamente dentro de la cuadrícula que crea el contenedor. Es importante destacar que solo los hijos inmediatos del grid container se convierten en grid items.

Características de los grid items:

  • Se posicionan automáticamente en la cuadrícula
  • Ocupan una celda por defecto (una fila y una columna)
  • Pueden extenderse a través de múltiples celdas si se especifica
  • Mantienen sus propiedades CSS normales (margin, padding, etc.)

Ejemplo con diferentes tipos de elementos:

<main class="layout">
  <header>Cabecera</header>
  <nav>Navegación</nav>
  <section>Contenido principal</section>
  <aside>Barra lateral</aside>
  <footer>Pie de página</footer>
</main>
.layout {
  display: grid;
  min-height: 100vh;
  gap: 15px;
}

/* Todos estos elementos son grid items */
header, nav, section, aside, footer {
  background-color: #2c3e50;
  color: white;
  padding: 20px;
  border-radius: 8px;
}

Comportamiento por defecto

Sin definir explícitamente la estructura de la cuadrícula, CSS Grid aplica un comportamiento por defecto que es importante conocer:

  • Una sola columna: Todos los grid items se apilan verticalmente en una columna
  • Filas automáticas: Se crean tantas filas como grid items haya
  • Tamaño automático: Cada fila se ajusta al contenido del elemento más alto
.basic-grid {
  display: grid;
  /* Sin especificar columnas ni filas */
}

Este comportamiento por defecto significa que inicialmente, convertir un contenedor en grid no produce cambios visuales dramáticos, pero prepara el terreno para aplicar las propiedades de cuadrícula más avanzadas.

Grid explícito vs grid implícito

CSS Grid maneja automáticamente dos tipos de cuadrículas:

Grid explícito: Las filas y columnas que defines específicamente usando propiedades como grid-template-columns y grid-template-rows.

Grid implícito: Las filas y columnas adicionales que CSS Grid crea automáticamente cuando hay más elementos de los que caben en el grid explícito.

.auto-grid {
  display: grid;
  grid-template-columns: 200px 200px; /* Grid explícito: 2 columnas */
  /* Si hay más de 2 items, se crean filas implícitas automáticamente */
}

Propiedades básicas del grid container

El grid container acepta varias propiedades específicas que controlan el comportamiento de la cuadrícula:

  • gap: Define el espaciado entre grid items
  • justify-items: Alinea los items horizontalmente dentro de sus celdas
  • align-items: Alinea los items verticalmente dentro de sus celdas
  • justify-content: Alinea toda la cuadrícula horizontalmente dentro del contenedor
  • align-content: Alinea toda la cuadrícula verticalmente dentro del contenedor

Ejemplo con propiedades de alineación:

.centered-grid {
  display: grid;
  gap: 20px;
  justify-items: center; /* Centra items horizontalmente */
  align-items: center;   /* Centra items verticalmente */
  min-height: 400px;
}

Elementos no grid items

Es importante recordar que solo los hijos directos se convierten en grid items. Los elementos anidados más profundamente mantienen su comportamiento normal de flujo:

<div class="container">
  <div class="item">Soy un grid item
    <p>No soy un grid item, soy contenido normal</p>
  </div>
  <div class="item">También soy un grid item</div>
</div>

En este ejemplo, los elementos div con clase item son grid items, pero el párrafo <p> dentro del primer div mantiene su comportamiento de flujo normal y no participa directamente en la cuadrícula.

Grid template columns y rows

Las propiedades **grid-template-columns** y **grid-template-rows** son fundamentales para definir la estructura explícita de nuestra cuadrícula. Estas propiedades determinan cuántas columnas y filas tendrá nuestro grid, así como el tamaño de cada una.

Definir columnas con grid-template-columns

La propiedad **grid-template-columns** establece el número y tamaño de las columnas en el grid container. Cada valor separado por espacios representa una columna:

.grid-container {
  display: grid;
  grid-template-columns: 200px 300px 150px;
  /* Crea 3 columnas: 200px, 300px y 150px */
}

Ejemplo práctico con tres columnas fijas:

<div class="three-columns">
  <div>Columna 1</div>
  <div>Columna 2</div>
  <div>Columna 3</div>
  <div>Columna 1</div>
  <div>Columna 2</div>
  <div>Columna 3</div>
</div>
.three-columns {
  display: grid;
  grid-template-columns: 200px 300px 150px;
  gap: 15px;
  background-color: #f8f9fa;
  padding: 20px;
}

.three-columns div {
  background-color: #007bff;
  color: white;
  padding: 20px;
  text-align: center;
}

Definir filas con grid-template-rows

De manera similar, **grid-template-rows** controla la altura y cantidad de filas en la cuadrícula:

.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 200px 150px;
  /* Crea 3 filas con alturas específicas */
}

La unidad fr (fracción)

La unidad **fr** representa una fracción del espacio disponible en el contenedor. Es extremadamente útil para crear layouts flexibles y responsivos:

.flexible-grid {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  /* La columna del medio ocupa el doble de espacio */
}

Ejemplo comparando diferentes unidades:

<div class="unit-comparison">
  <div>200px fijo</div>
  <div>2fr flexible</div>
  <div>1fr flexible</div>
</div>
.unit-comparison {
  display: grid;
  grid-template-columns: 200px 2fr 1fr;
  gap: 10px;
  height: 200px;
}

En este ejemplo, la primera columna siempre mide 200px, mientras que las otras dos se reparten el espacio restante en proporción 2:1.

Mezclar diferentes unidades

Puedes combinar diferentes tipos de unidades según tus necesidades de diseño:

.mixed-units {
  display: grid;
  grid-template-columns: 250px 1fr auto;
  /*
  - Primera columna: 250px fijos
  - Segunda columna: toma todo el espacio disponible
  - Tercera columna: se ajusta a su contenido
  */
}

La función repeat()

Para crear patrones repetitivos, la función repeat() simplifica enormemente la sintaxis:

/* En lugar de escribir: 1fr 1fr 1fr 1fr */
.efficient-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* Crea 4 columnas iguales */
}

Ejemplos avanzados con repeat():

.pattern-grid {
  display: grid;
  /* Alterna entre 100px y 1fr, 3 veces */
  grid-template-columns: repeat(3, 100px 1fr);
}

.responsive-cards {
  display: grid;
  /* Columnas que se adaptan automáticamente */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

La función minmax()

La función **minmax()** define un rango de tamaño mínimo y máximo para columnas o filas:

.adaptive-layout {
  display: grid;
  grid-template-columns: 
    minmax(200px, 300px) 
    minmax(300px, 1fr) 
    minmax(150px, 200px);
}

Ejemplo práctico con sidebar responsivo:

<div class="layout-with-sidebar">
  <nav>Navegación</nav>
  <main>Contenido principal</main>
  <aside>Sidebar</aside>
</div>
.layout-with-sidebar {
  display: grid;
  grid-template-columns: 
    minmax(200px, 250px)  /* Navegación: min 200px, max 250px */
    1fr                   /* Contenido: toma el espacio restante */
    minmax(150px, 200px); /* Sidebar: min 150px, max 200px */
  gap: 20px;
  min-height: 100vh;
}

Auto-fit y auto-fill con repeat()

Estas palabras clave especiales crean grids que se adaptan automáticamente al espacio disponible:

  • **auto-fill**: Crea tantas columnas como quepan, manteniendo las vacías
  • **auto-fit**: Crea tantas columnas como quepan, colapsa las vacías
.auto-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 15px;
}

Este patrón es especialmente útil para galerías de imágenes o rejillas de tarjetas que necesitan adaptarse a diferentes tamaños de pantalla.

Combinar columns y rows

Puedes usar ambas propiedades simultáneamente para control total sobre la cuadrícula:

<div class="complete-grid">
  <header>Header</header>
  <nav>Nav</nav>
  <main>Main</main>
  <aside>Aside</aside>
  <footer>Footer</footer>
</div>
.complete-grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 80px 1fr 60px;
  gap: 10px;
  min-height: 100vh;
}

Valores especiales: auto y max-content

  • **auto**: Se ajusta al contenido, similar a max-content pero respeta las restricciones de grid
  • **max-content**: El tamaño mínimo necesario para mostrar el contenido sin overflow
  • **min-content**: El tamaño más pequeño posible sin overflow
.content-sized {
  display: grid;
  grid-template-columns: 
    max-content  /* Se ajusta al contenido más ancho */
    1fr          /* Toma el espacio restante */
    auto;        /* Se ajusta automáticamente */
}

Ejemplo completo: Dashboard responsivo

<div class="dashboard">
  <div class="metric">Usuarios: 1,234</div>
  <div class="metric">Ventas: €45,678</div>
  <div class="metric">Pedidos: 567</div>
  <div class="chart">Gráfico principal</div>
  <div class="recent">Actividad reciente</div>
  <div class="stats">Estadísticas</div>
</div>
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-template-rows: auto auto 1fr;
  gap: 20px;
  padding: 20px;
}

.metric {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px;
  border-radius: 8px;
  text-align: center;
  font-size: 1.2rem;
}

.chart, .recent, .stats {
  background-color: white;
  border: 1px solid #e1e5e9;
  border-radius: 8px;
  padding: 20px;
}

Esta combinación de propiedades te permite crear layouts flexibles y robustos que se adaptan automáticamente a diferentes tamaños de contenido y pantalla, aprovechando toda la potencia del sistema Grid de CSS.

Grid areas y posicionamiento

Las grid areas representan una de las características más elegantes de CSS Grid, permitiendo definir y posicionar elementos mediante nombres descriptivos en lugar de números de línea. Este enfoque hace que el código sea más legible y mantenible, especialmente en layouts complejos.

Grid template areas

La propiedad **grid-template-areas** permite crear un mapa visual de la cuadrícula usando nombres descriptivos. Cada cadena de texto representa una fila, y cada nombre separado por espacios representa una celda:

.layout {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 80px 1fr 60px;
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
}

Ejemplo práctico de layout con areas:

<div class="page-layout">
  <header class="header">Cabecera del sitio</header>
  <nav class="navigation">Navegación</nav>
  <main class="content">Contenido principal</main>
  <aside class="sidebar">Barra lateral</aside>
  <footer class="footer">Pie de página</footer>
</div>
.page-layout {
  display: grid;
  grid-template-columns: 250px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "nav    main   sidebar"
    "footer footer footer";
  gap: 15px;
  min-height: 100vh;
}

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

Asignar elementos a areas

Para posicionar un elemento en un área específica, utilizamos la propiedad grid-area con el nombre que definimos en grid-template-areas:

.header {
  grid-area: header;
  background-color: #2c3e50;
  color: white;
  padding: 20px;
}

.content {
  grid-area: main;
  background-color: #ecf0f1;
  padding: 20px;
}

Areas que ocupan múltiples celdas

Un área puede extenderse a través de varias celdas repitiendo el mismo nombre en grid-template-areas:

<div class="dashboard-layout">
  <div class="title">Panel de Control</div>
  <div class="widget-1">Widget 1</div>
  <div class="widget-2">Widget 2</div>
  <div class="large-chart">Gráfico Principal</div>
  <div class="stats">Estadísticas</div>
</div>
.dashboard-layout {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto 200px 200px;
  grid-template-areas:
    "title  title  title  title"
    "widget1 widget2 chart chart"
    "stats   stats  chart chart";
  gap: 20px;
}

.title { grid-area: title; }
.widget-1 { grid-area: widget1; }
.widget-2 { grid-area: widget2; }
.large-chart { grid-area: chart; }
.stats { grid-area: stats; }

Celdas vacías con puntos

Para dejar celdas vacías en la cuadrícula, utiliza un punto (.) o múltiples puntos (...) en lugar de un nombre de área:

.asymmetric-layout {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  grid-template-areas:
    "header header ."
    "nav    main   ."
    ".      main   sidebar";
}

Posicionamiento manual con grid-column y grid-row

Además de las áreas nombradas, puedes posicionar elementos manualmente usando números de línea con grid-column y grid-row:

.manual-positioning {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}

.item-1 {
  grid-column: 1 / 3; /* Ocupa de la línea 1 a la 3 (2 columnas) */
  grid-row: 1;        /* Primera fila */
}

.item-2 {
  grid-column: 3 / 5; /* Ocupa de la línea 3 a la 5 (2 columnas) */
  grid-row: 1 / 3;    /* Ocupa 2 filas */
}

La propiedad grid-area como shorthand

La propiedad **grid-area** también funciona como un shorthand para especificar posición usando números de línea:

.positioned-item {
  /* grid-area: row-start / column-start / row-end / column-end */
  grid-area: 1 / 2 / 3 / 4;
  /* Equivale a:
     grid-row: 1 / 3;
     grid-column: 2 / 4; */
}

Usando span para el tamaño

La palabra clave **span** permite especificar cuántas líneas debe ocupar un elemento:

.spanning-item {
  grid-column: 2 / span 2; /* Empieza en línea 2, ocupa 2 columnas */
  grid-row: span 3;        /* Ocupa 3 filas desde su posición inicial */
}

Ejemplo con diferentes métodos de posicionamiento:

<div class="mixed-positioning">
  <div class="item-a">A - Con span</div>
  <div class="item-b">B - Con líneas</div>
  <div class="item-c">C - Con area</div>
  <div class="item-d">D - Automático</div>
</div>
.mixed-positioning {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 80px);
  grid-template-areas:
    ". . . ."
    ". area . ."
    ". . . .";
  gap: 10px;
}

.item-a {
  grid-column: span 2;  /* Ocupa 2 columnas */
  grid-row: 1;
  background-color: #e74c3c;
}

.item-b {
  grid-column: 3 / 5;   /* Líneas específicas */
  grid-row: 1;
  background-color: #3498db;
}

.item-c {
  grid-area: area;      /* Área nombrada */
  background-color: #2ecc71;
}

.item-d {
  /* Posicionamiento automático */
  background-color: #f39c12;
}

Reordenar elementos con grid areas

Una ventaja importante de las grid areas es la facilidad para reordenar elementos cambiando solo el CSS, sin modificar el HTML:

/* Layout para pantallas grandes */
.responsive-layout {
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";
}

/* En pantallas pequeñas, reordenamos */
@media (max-width: 768px) {
  .responsive-layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
  }
}

Superposición de elementos

CSS Grid permite que los elementos se superpongan ocupando las mismas celdas:

<div class="overlay-grid">
  <div class="background">Fondo</div>
  <div class="content">Contenido</div>
  <div class="overlay">Overlay</div>
</div>
.overlay-grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 300px;
}

.background {
  grid-area: 1 / 1; /* Misma posición */
  background-color: #3498db;
  z-index: 1;
}

.content {
  grid-area: 1 / 1; /* Misma posición */
  z-index: 2;
  padding: 20px;
  color: white;
}

.overlay {
  grid-area: 1 / 1; /* Misma posición */
  background-color: rgba(0, 0, 0, 0.7);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

Ejemplo completo: Layout de revista

<article class="magazine-layout">
  <h1 class="title">Título del Artículo</h1>
  <p class="subtitle">Subtítulo explicativo</p>
  <img class="hero-image" src="#" alt="Imagen principal">
  <p class="intro">Párrafo de introducción...</p>
  <p class="content-1">Primer párrafo del contenido...</p>
  <p class="content-2">Segundo párrafo del contenido...</p>
  <aside class="quote">Cita destacada</aside>
</article>
.magazine-layout {
  display: grid;
  grid-template-columns: 2fr 1fr 2fr;
  grid-template-rows: auto auto auto auto auto;
  grid-template-areas:
    "title    title    title"
    "subtitle subtitle subtitle"
    "image    image    quote"
    "intro    intro    quote"
    "content1 content2 .";
  gap: 20px;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.title { 
  grid-area: title;
  font-size: 2.5rem;
  margin: 0;
}

.subtitle { 
  grid-area: subtitle;
  font-size: 1.2rem;
  color: #666;
  margin: 0;
}

.hero-image { 
  grid-area: image;
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
}

.intro { grid-area: intro; }
.content-1 { grid-area: content1; }
.content-2 { grid-area: content2; }

.quote { 
  grid-area: quote;
  background-color: #f8f9fa;
  padding: 20px;
  border-left: 4px solid #007bff;
  font-style: italic;
  align-self: start;
}

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en CSS

Documentación oficial de CSS
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, CSS es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de CSS

Explora más contenido relacionado con CSS y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la diferencia entre grid container y grid items.
  • Definir la estructura de la cuadrícula con grid-template-columns y grid-template-rows.
  • Utilizar unidades flexibles como fr, minmax(), repeat(), auto-fit y auto-fill.
  • Aplicar grid-template-areas para nombrar y posicionar elementos de forma semántica.
  • Posicionar elementos manualmente con grid-column, grid-row y grid-area, incluyendo superposiciones y reordenamientos responsivos.