CSS Grid: guía completa para crear layouts responsive paso a paso

Marco Risco
De la mente de: Marco Risco 18-Ago-2026 Programación
CSS Grid: guía completa para crear layouts responsive paso a paso 0 Comentarios
Basado en 0 votos

CSS Grid es un sistema de maquetación de CSS pensado para organizar contenido en filas y columnas. Con unas pocas reglas puedes construir desde una galería de tarjetas hasta la estructura completa de una página, controlar el espacio entre bloques y adaptar el resultado a distintos anchos de pantalla.

En esta guía vamos a crear un layout responsive desde cero. Empezaremos por una cuadrícula básica, añadiremos columnas flexibles, aprenderemos a colocar zonas con nombre y terminaremos con una página que cambia de estructura en móvil. Puedes copiar cada ejemplo y modificarlo mientras avanzas.

Si quieres conseguir… Empieza por…
Varias columnas del mismo ancho repeat(3, 1fr)
Tarjetas que se adapten solas repeat(auto-fit, minmax(16rem, 1fr))
Separación entre filas y columnas gap
Una estructura con cabecera, menú y contenido grid-template-areas
Centrar el contenido de las celdas place-items
Cambiar la distribución en móvil Una media query que redefina columnas o áreas

Qué es CSS Grid y cuándo merece la pena usarlo

Grid se diferencia de otros métodos de maquetación por trabajar en dos dimensiones. El navegador puede coordinar las filas y las columnas a la vez, por lo que cada bloque encaja en una cuadrícula común. Esto resulta especialmente útil en layouts de página, galerías, listados de productos, paneles y composiciones con zonas bien definidas.

Al declarar display: grid, el elemento se convierte en contenedor grid y sus hijos directos pasan a ser elementos grid. A partir de ahí puedes decidir cuántas columnas habrá, cuánto medirán, qué separación existirá entre ellas y dónde se colocará cada elemento.

Grid no sustituye a Flexbox. Flexbox suele encajar mejor cuando el contenido avanza en una sola dirección (una fila de botones o los elementos de un menú), mientras que Grid aporta más control cuando filas y columnas deben relacionarse entre sí. En una web real es habitual usar Grid para la estructura general y Flexbox dentro de sus componentes.

Los conceptos de Grid CSS que necesitas conocer

Estos conceptos parecen más complicados de lo que son. Imagina una hoja cuadriculada:

  • Línea: límite horizontal o vertical que separa las pistas. Una cuadrícula de tres columnas tiene cuatro líneas verticales.

  • Pista: espacio comprendido entre dos líneas; puede ser una fila o una columna.

  • Celda: intersección de una fila y una columna.

  • Área: conjunto rectangular de una o varias celdas.

  • Gap: espacio entre pistas. No hace falta simularlo con márgenes en cada elemento.

  • Cuadrícula explícita: filas y columnas que declaras con grid-template-columns y grid-template-rows.

  • Cuadrícula implícita: pistas que el navegador crea cuando hay más elementos de los previstos.

Esta distinción ayuda a entender por qué algunas propiedades se aplican al padre y otras a los hijos:

Propiedad Se aplica a Para qué sirve
display: grid Contenedor Activa el contexto de cuadrícula
grid-template-columns Contenedor Define las columnas explícitas
grid-template-rows Contenedor Define las filas explícitas
gap Contenedor Separa filas y columnas
grid-template-areas Contenedor Dibuja una distribución mediante nombres
grid-column y grid-row Elemento Colocan o expanden un hijo entre líneas
grid-area Elemento Asigna un hijo a un área con nombre
place-items Contenedor Alinea el contenido dentro de las celdas

Paso 1: prepara una estructura HTML sencilla

Empezaremos con seis tarjetas. Grid no exige clases distintas para cada una si quieres que el navegador las coloque automáticamente.

<section class="tarjetas">
 <article class="tarjeta">Proyecto 1</article>
 <article class="tarjeta">Proyecto 2</article>
 <article class="tarjeta">Proyecto 3</article>
 <article class="tarjeta">Proyecto 4</article>
 <article class="tarjeta">Proyecto 5</article>
 <article class="tarjeta">Proyecto 6</article>
</section>

El section será el contenedor y cada article, un elemento grid. Los nietos que pudieran existir dentro de cada tarjeta no se colocan en esta cuadrícula; pertenecen al flujo interno de su tarjeta.

Paso 2: activa Grid y crea las primeras columnas

Para crear la cuadrícula más básica bastan dos declaraciones:

.tarjetas {
 display: grid;
 grid-template-columns: 1fr 1fr 1fr;
}

fr representa una fracción del espacio disponible. Al escribir tres veces 1fr, el navegador reparte el ancho en tres columnas iguales. La misma regla puede expresarse de forma más compacta:

.tarjetas {
 display: grid;
 grid-template-columns: repeat(3, 1fr);
}

Ahora añadimos separación. gap crea espacio solo entre las pistas, sin añadir margen en los bordes exteriores del contenedor.

.tarjetas {
 display: grid;
 grid-template-columns: repeat(3, 1fr);
 gap: 1.5rem;
}

También puedes controlar cada eje por separado con column-gap y row-gap, aunque una sola medida suele bastar para mantener un ritmo uniforme.

Paso 3: combina fr, repeat() y minmax()

Las columnas iguales funcionan bien en una demo, pero un layout real necesita límites. minmax() permite indicar el tamaño mínimo y máximo de una pista:

.tarjetas {
 display: grid;
 grid-template-columns: repeat(3, minmax(14rem, 1fr));
 gap: 1.5rem;
}

Cada columna intentará medir al menos 14rem y podrá crecer hasta ocupar una fracción del espacio libre. Si el contenedor no tiene sitio para las tres, esta versión puede provocar desbordamiento: el número de columnas sigue fijado en tres.

Otra combinación habitual mezcla una zona lateral estable con un contenido que aprovecha el resto del ancho:

.pagina {
 display: grid;
 grid-template-columns: minmax(14rem, 18rem) minmax(0, 1fr);
 gap: 2rem;
}

El segundo minmax(0, 1fr) tiene un detalle importante. El 0 permite que la pista se encoja aunque su contenido tenga un ancho intrínseco mayor. Sin ese límite, una tabla, una URL larga o un bloque de código puede empujar la columna y generar scroll horizontal.

Grid reparte el espacio del contenedor, no decide por sí solo cuánto debe medir este. Si necesitas limitar el ancho total de la composición, puedes combinarlo con la propiedad max-width en CSS y centrar el contenedor con margin-inline: auto.

Paso 4: crea un CSS Grid responsive sin media queries

Una galería de tarjetas no siempre necesita puntos de ruptura. auto-fit permite que el navegador calcule cuántas columnas caben según el ancho disponible:

.tarjetas {
 display: grid;
 grid-template-columns: repeat(
 auto-fit,
 minmax(min(100%, 16rem), 1fr)
 );
 gap: clamp(1rem, 2vw, 1.5rem);
}

Esta regla combina tres decisiones:

  1. auto-fit crea tantas columnas como quepan.

  2. minmax() evita que una columna baje del mínimo previsto y le permite crecer.

  3. min(100%, 16rem) impide que el mínimo de 16rem desborde un móvil más estrecho.

Con suficiente espacio aparecerán varias columnas. Al reducirse el contenedor, las tarjetas pasarán a dos y luego a una sin que tengas que indicar anchos de dispositivo.

Diferencia entre auto-fit y auto-fill

Ambos valores calculan el número de pistas posibles. La diferencia aparece cuando sobran huecos:

  • auto-fit colapsa las pistas vacías y deja que las columnas existentes aprovechen ese espacio.

  • auto-fill conserva el espacio de las pistas que podrían existir aunque no haya elementos para llenarlas.

Para una colección de tarjetas que debe ocupar todo el ancho, auto-fit suele dar el resultado esperado. auto-fill es útil cuando quieres conservar la cuadrícula imaginaria y evitar que los pocos elementos disponibles se estiren.

Esta técnica resuelve bien componentes repetitivos, pero no todas las decisiones responsive. Si en móvil necesitas mover una navegación, ocultar una zona secundaria o alterar la jerarquía visual, tendrás que definir un cambio explícito. La guía sobre media queries y diseño responsive explica cómo elegir y organizar esos puntos de ruptura.

Paso 5: construye un layout con grid-template-areas

Las áreas con nombre permiten describir la página de una forma muy visual. Partimos de una estructura semántica:

<div class="layout">
 <header class="cabecera">Cabecera</header>
 <nav class="lateral">Navegación</nav>
 <main class="contenido">Contenido principal</main>
 <aside class="relacionado">Contenido relacionado</aside>
 <footer class="pie">Pie de página</footer>
</div>

Después dibujamos tres columnas y tres filas en CSS:

.layout {
 display: grid;
 min-height: 100dvh;
 grid-template-columns:
 minmax(12rem, 16rem)
 minmax(0, 1fr)
 minmax(12rem, 16rem);
 grid-template-rows: auto 1fr auto;
 grid-template-areas:
 "cabecera cabecera cabecera"
 "lateral contenido relacionado"
 "pie pie pie";
 gap: 1rem;
 padding: clamp(1rem, 3vw, 2rem);
}
.cabecera {
 grid-area: cabecera;
}
.lateral {
 grid-area: lateral;
}
.contenido {
 grid-area: contenido;
}
.relacionado {
 grid-area: relacionado;
}
.pie {
 grid-area: pie;
}

Cada línea entre comillas representa una fila y cada palabra, una columna. Por eso todas las filas de grid-template-areas deben tener el mismo número de celdas. Repetir un nombre hace que esa zona abarque varias columnas; un punto (.) deja una celda vacía.

Los nombres no tienen un significado reservado. Elegir términos que describan la función de cada zona hace que la distribución sea más fácil de mantener que una colección de coordenadas numéricas.

Paso 6: adapta las áreas a móvil con una media query

En una pantalla estrecha, las tres columnas anteriores dejarían muy poco espacio al contenido. No hace falta reconstruir el HTML: basta con redefinir la cuadrícula.

@media (max-width: 56.25rem) {
 .layout {
 grid-template-columns: 1fr;
 grid-template-rows: auto;
 grid-template-areas:
 "cabecera"
 "lateral"
 "contenido"
 "relacionado"
 "pie";
 }
}

El punto de ruptura no debería elegirse porque corresponda a un modelo concreto de tablet. Reduce la ventana o usa el modo responsive del navegador y observa cuándo el contenido deja de respirar, se solapa o genera desplazamiento horizontal. Ahí está el punto en el que la composición pide un cambio.

Mantén, además, un orden lógico en el HTML. Grid puede mover visualmente los bloques, pero un lector de pantalla y la navegación por teclado siguen el orden del documento. Una cuadrícula atractiva no compensa una secuencia difícil de entender.

Cómo colocar elementos con líneas y span

No siempre necesitas áreas con nombre. Para hacer que una tarjeta destacada ocupe dos columnas, puedes indicar entre qué líneas se extiende:

.tarjeta-destacada {
 grid-column: 1 / 3;
}

También puedes expresar la misma idea con span sin fijar la línea final:

.tarjeta-destacada {
 grid-column: span 2;
}

Con span, la colocación suele ser más flexible cuando el navegador ordena los elementos automáticamente. También funciona en filas:

.tarjeta-alta {
 grid-row: span 2;
}

Usa coordenadas cuando la posición forme parte de la estructura. Si buscas superponer un elemento, fijarlo al viewport o sacarlo del flujo, entonces estás resolviendo otro problema; conviene revisar cómo funciona position en CSS antes de mezclar ambos sistemas.

Alineación dentro de la cuadrícula

Grid distingue entre alinear el contenido de cada celda y alinear la cuadrícula completa dentro del contenedor.

.galeria {
 display: grid;
 place-items: center;
}

place-items combina align-items y justify-items. Con center, los elementos se centran en ambos ejes dentro de sus celdas. Si solo quieres cambiar una tarjeta, utiliza align-self, justify-self o su abreviatura place-self.

.tarjeta-especial {
 place-self: end center;
}

Por otro lado, justify-content, align-content y place-content distribuyen la cuadrícula como conjunto cuando sus pistas ocupan menos que el contenedor. Confundir ambos grupos es una causa frecuente de que “no pase nada” al cambiar una propiedad.

Si tu objetivo concreto es alinear una caja en el centro, encontrarás una comparación de métodos en la guía para centrar un div con CSS.

Controla las filas que Grid crea automáticamente

Cuando hay más elementos que celdas declaradas, el algoritmo de colocación crea nuevas pistas. Puedes definir su tamaño con grid-auto-rows:

.listado {
 display: grid;
 grid-template-columns: repeat(3, 1fr);
 grid-auto-rows: minmax(8rem, auto);
 gap: 1rem;
}

Cada fila implícita medirá como mínimo 8rem, pero podrá crecer si el contenido lo necesita. Evita alturas rígidas cuando el texto pueda variar; de lo contrario, una descripción larga terminará desbordando su tarjeta.

grid-auto-flow controla la dirección de colocación automática. Su valor inicial es row, por lo que el navegador completa cada fila antes de pasar a la siguiente. El valor dense intenta rellenar huecos anteriores con elementos posteriores, pero puede alterar el orden visual respecto al HTML. Resérvalo para colecciones puramente visuales en las que esa diferencia no perjudique la lectura ni la interacción.

CSS Grid o Flexbox: cuál elegir

Elegir bien depende de cuántas dimensiones necesites coordinar, no de que un sistema sea mejor que el otro.

Situación Grid Flexbox
Layout completo con cabecera, lateral y contenido Recomendado Posible, pero menos directo
Galería con filas y columnas alineadas Recomendado Puede perder la alineación entre filas
Menú horizontal Posible Recomendado
Grupo de botones de ancho variable Posible Recomendado
Tarjetas que cambian de número de columnas Recomendado Posible con flex-wrap
Alinear elementos dentro de una tarjeta Posible Suele ser más sencillo

Una combinación habitual queda así:

.listado {
 display: grid;
 grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
 gap: 1.5rem;
}
.tarjeta {
 display: flex;
 flex-direction: column;
}
.tarjeta .acciones {
 margin-top: auto;
 display: flex;
 gap: 0.75rem;
}

Grid organiza las tarjetas; Flexbox mantiene sus botones agrupados y pegados a la parte inferior aunque las descripciones tengan longitudes distintas.

Errores frecuentes al trabajar con CSS Grid

Aplicar Grid al elemento equivocado

Las columnas afectan a los hijos directos del contenedor. Si declaras display: grid en una tarjeta esperando ordenar sus tarjetas hermanas, no ocurrirá: la regla debe ir en el padre común.

Fijar demasiadas columnas

repeat(4, 1fr) siempre intenta conservar cuatro columnas. Para una galería flexible, combina auto-fit con minmax() o cambia el número de columnas en los puntos donde el contenido lo necesite.

Usar anchos que no pueden encogerse

Una columna 1fr tiene en cuenta el tamaño mínimo intrínseco de su contenido. Si aparece scroll horizontal, prueba minmax(0, 1fr) y revisa también imágenes, tablas, palabras largas y bloques de código. Las imágenes deberían tener, como mínimo, max-width: 100% y height: auto.

Mezclar gap y márgenes sin una razón

gap ya resuelve el espacio regular entre elementos. Mantener además márgenes laterales en cada tarjeta puede duplicar la separación y complicar los bordes de la cuadrícula.

Reordenar la página solo de forma visual

Colocar el contenido principal antes en pantalla pero después en el DOM crea una experiencia distinta para quienes navegan con teclado o lector de pantalla. Empieza por un HTML con sentido y utiliza Grid para presentarlo, no para corregir una estructura semántica deficiente.

Esperar que una media query arregle el contenido

Un punto de ruptura cambia la distribución, pero no corrige una imagen sin límites, un texto interminable o una tabla demasiado ancha. Antes de añadir más condiciones, identifica qué elemento provoca el desbordamiento.

Ejemplo completo de layout responsive con CSS Grid

Este CSS reúne las decisiones principales de la guía y puede servir como base para una página real:

* {
 box-sizing: border-box;
}
body {
 margin: 0;
 font-family: system-ui, sans-serif;
 background: #f4f5f7;
 color: #172033;
}
.layout {
 display: grid;
 min-height: 100dvh;
 grid-template-columns:
 minmax(12rem, 16rem)
 minmax(0, 1fr)
 minmax(12rem, 16rem);
 grid-template-areas:
 "cabecera cabecera cabecera"
 "lateral contenido relacionado"
 "pie pie pie";
 gap: 1rem;
 padding: clamp(1rem, 3vw, 2rem);
}
.cabecera,
.lateral,
.contenido,
.relacionado,
.pie {
 padding: 1.25rem;
 border-radius: 0.75rem;
 background: #ffffff;
}
.cabecera { grid-area: cabecera; }
.lateral { grid-area: lateral; }
.contenido { grid-area: contenido; }
.relacionado { grid-area: relacionado; }
.pie { grid-area: pie; }
.proyectos {
 display: grid;
 grid-template-columns: repeat(
 auto-fit,
 minmax(min(100%, 15rem), 1fr)
 );
 gap: 1rem;
}
@media (max-width: 56.25rem) {
 .layout {
 grid-template-columns: 1fr;
 grid-template-areas:
 "cabecera"
 "lateral"
 "contenido"
 "relacionado"
 "pie";
 }
}

En el exterior, la estructura cambia de tres columnas a una mediante una media query porque existe una decisión de diseño clara: las zonas laterales ya no caben junto al contenido. La cuadrícula interior de proyectos, en cambio, se adapta por sí sola con auto-fit porque solo necesita añadir o quitar columnas según el espacio disponible.

Esa combinación suele producir un CSS más estable que llenar la hoja de estilos de puntos de ruptura. Deja que el navegador resuelva los cambios repetitivos y reserva las media queries para transformaciones reales de la composición.

Cuando la maquetación forma parte de un proyecto con requisitos propios (jerarquía de contenidos, conversión, accesibilidad y rendimiento), el siguiente paso es diseñar el sistema completo, no acumular reglas aisladas. En Overant podemos trasladar esa estructura a un proyecto de diseño web a medida adaptado al contenido y a los objetivos del negocio.

¿Qué te ha parecido este artículo?
Deja tu comentario
Acepto facilitar mis datos con la finalidad de dejar mis comentarios en el blog
Acepto recibir información comercial
¿Necesitas hablar? ¡Contacta con nosotros!