CSS Grid y Flexbox son las dos herramientas de layout más poderosas de CSS moderno, y la pregunta que más escucho de desarrolladores junior es: "¿Cuál uso?". La respuesta corta es que no son competidoras — son complementarias. En esta guía te voy a mostrar exactamente cuándo usar cada una, con ejemplos reales que puedes copiar y adaptar a tus proyectos.
Después de maquetar cientos de interfaces con ambas tecnologías, puedo decirte que la regla es simple: Flexbox para una dimensión, Grid para dos dimensiones. Vamos a profundizar en qué significa esto.
Flexbox: layout en una dimensión
Flexbox está diseñado para distribuir elementos a lo largo de un solo eje — horizontal o vertical. Es perfecto para componentes donde los items se alinean en una fila o columna.
Cuándo usar Flexbox
- Barras de navegación (navbars)
- Alinear elementos dentro de un componente (botones, iconos + texto)
- Centrar un elemento vertical y horizontalmente
- Distribuir espacio entre items de una fila
- Elementos que necesitan crecer/encoger proporcionalmente
Las propiedades esenciales del contenedor flex
.contenedor {
display: flex;
/* Dirección del eje principal */
flex-direction: row; /* horizontal (default) */
flex-direction: column; /* vertical */
/* Alineación en el eje principal */
justify-content: flex-start; /* al inicio */
justify-content: center; /* centrado */
justify-content: space-between; /* espacio entre items */
justify-content: space-evenly; /* espacio uniforme */
/* Alineación en el eje transversal */
align-items: stretch; /* estirar (default) */
align-items: center; /* centrar verticalmente */
align-items: flex-start; /* arriba */
/* Permitir salto de línea */
flex-wrap: wrap; /* items pasan a la siguiente línea */
/* Espacio entre items */
gap: 1rem; /* moderno y limpio */
}
Propiedades de los items flex
.item {
/* Crecer para llenar espacio disponible */
flex-grow: 1;
/* No encoger más allá de su contenido */
flex-shrink: 0;
/* Tamaño base antes de distribuir espacio */
flex-basis: 200px;
/* Atajo: flex-grow | flex-shrink | flex-basis */
flex: 1 0 200px;
/* Un item puede alinearse diferente al resto */
align-self: flex-end;
}
Ejemplo práctico: Navbar responsive
<nav class="navbar">
<a href="/" class="logo">MiSitio</a>
<ul class="nav-links">
<li><a href="/about">About</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contact">Contacto</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #1a1a2e;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
/* Responsive: en móvil, apilar verticalmente */
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 1rem;
}
}
Ejemplo práctico: Centrar un elemento (el clásico)
Antes de Flexbox, centrar un div era notoriamente difícil. Ahora son 3 líneas:
.centrado {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Ejemplo práctico: Card con footer al fondo
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-body {
flex: 1; /* Crece para ocupar todo el espacio disponible */
}
.card-footer {
/* Se queda abajo automáticamente, sin importar la cantidad de contenido */
margin-top: auto;
}
CSS Grid: layout en dos dimensiones
Grid controla filas y columnas simultáneamente. Es ideal para layouts de página completa y cualquier diseño que necesite control en ambos ejes.
Cuándo usar CSS Grid
- Layout general de la página (header, sidebar, content, footer)
- Galerías de imágenes o productos
- Dashboards con múltiples paneles
- Cualquier diseño que necesite alinear items en filas Y columnas
- Layouts asimétricos o con items que ocupan múltiples celdas
Propiedades esenciales del contenedor grid
.grid {
display: grid;
/* Definir columnas */
grid-template-columns: 200px 1fr 200px; /* 3 columnas */
grid-template-columns: repeat(3, 1fr); /* 3 columnas iguales */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* responsive automático */
/* Definir filas */
grid-template-rows: auto 1fr auto;
/* Espaciado entre celdas */
gap: 1.5rem;
column-gap: 2rem;
row-gap: 1rem;
/* Nombrar áreas del grid */
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
}
Propiedades de los items grid
.item {
/* Posicionar un item en una celda específica */
grid-column: 1 / 3; /* de la línea 1 a la 3 (ocupa 2 columnas) */
grid-row: 1 / 2; /* primera fila */
/* Ocupar varias celdas */
grid-column: span 2; /* ocupa 2 columnas */
grid-row: span 3; /* ocupa 3 filas */
/* Usar áreas nombradas */
grid-area: header;
}
Ejemplo práctico: Layout de página completa
<div class="page-layout">
<header class="header">Header</header>
<nav class="sidebar">Sidebar</nav>
<main class="content">Contenido principal</main>
<footer class="footer">Footer</footer>
</div>
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 0;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }
/* Responsive: en móvil, una sola columna */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"content"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
Ejemplo práctico: Galería de imágenes responsive
Este es uno de los patrones más útiles de Grid. Con auto-fit y minmax() creas una grilla que se adapta automáticamente sin media queries:
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
padding: 1.5rem;
}
.galeria img {
width: 100%;
height: 250px;
object-fit: cover;
border-radius: 8px;
}
Esto crea columnas de mínimo 280px que se ajustan automáticamente al ancho disponible. En pantalla grande verás 4 columnas, en tablet 2, y en móvil 1 — todo sin una sola media query. Así funciona la función repeat() de CSS Grid.
Ejemplo práctico: Dashboard con paneles de diferentes tamaños
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto;
gap: 1rem;
}
/* Panel grande (ocupa 2 columnas y 2 filas) */
.panel-grande {
grid-column: span 2;
grid-row: span 2;
}
/* Panel ancho (ocupa toda una fila) */
.panel-ancho {
grid-column: 1 / -1; /* de la primera a la última línea */
}
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
}
.panel-grande {
grid-column: span 1;
grid-row: span 1;
}
}
Grid + Flexbox juntos: el patrón más poderoso
La verdadera magia aparece cuando combinas Grid para el layout general y Flexbox para los componentes internos. Este es el patrón que uso en prácticamente todos mis proyectos:
/* Grid para el layout de la página */
.page {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
/* Flexbox para cada card individual */
.card {
display: flex;
flex-direction: column;
border: 1px solid #e2e8f0;
border-radius: 12px;
overflow: hidden;
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-body {
flex: 1;
padding: 1.5rem;
}
/* Flexbox para el footer de la card */
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-top: 1px solid #e2e8f0;
margin-top: auto;
}
La función minmax() y unidades fr
Dos conceptos que hacen Grid increíblemente flexible:
fr(fraction): Representa una fracción del espacio disponible.1fr 2frsignifica que la segunda columna es el doble de ancha que la primera.minmax(min, max): Define un rango de tamaño.minmax(200px, 1fr)significa "mínimo 200px, máximo el espacio disponible".
/* 3 columnas: sidebar fija, contenido flexible, sidebar fija */
grid-template-columns: 250px minmax(0, 1fr) 300px;
/* Columnas que se adaptan: mínimo 200px, máximo igual */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* 3 columnas proporcionales */
grid-template-columns: 1fr 2fr 1fr;
Tabla comparativa: Grid vs Flexbox
| Criterio | Flexbox | CSS Grid |
|---|---|---|
| Dimensiones | Una (fila o columna) | Dos (filas y columnas) |
| Dirección del contenido | Desde el contenido hacia fuera | Desde el layout hacia dentro |
| Mejor para | Componentes, alineación | Layouts de página, grillas |
| Responsive | Con flex-wrap + media queries | Auto-fit/auto-fill + minmax |
| Overlap de items | No soportado | Sí, con grid-area |
| Nombrar áreas | No | Sí (grid-template-areas) |
| Gap | Sí | Sí |
| Soporte navegadores | 99%+ | 97%+ |
Errores comunes que debes evitar
- Usar Grid para todo: Si solo necesitas alinear items en una fila, Flexbox es más simple y directo.
- Olvidar
min-width: 0: En Flexbox y Grid, los items no se encogerán más allá de su contenido mínimo. Si tienes overflow, agregamin-width: 0al item. - No usar
gap: Evita usar margins para separar items dentro de un flex/grid container.gapes más limpio y no causa problemas con el primer/último item. - Media queries innecesarias: Antes de escribir un breakpoint, prueba si
auto-fit+minmax()resuelve tu responsive automáticamente. - Porcentajes en Grid: Usa
fren lugar de porcentajes.1frrespeta elgap, los porcentajes no.
Recursos para seguir aprendiendo
- A Complete Guide to Flexbox — CSS-Tricks (la referencia definitiva)
- A Complete Guide to CSS Grid — CSS-Tricks
- Flexbox Froggy — Juego interactivo para practicar Flexbox
- Grid Garden — Juego interactivo para practicar CSS Grid
- MDN: CSS Grid Layout — Documentación oficial y completa
Mi recomendación final: no intentes memorizar todas las propiedades. Entiende los conceptos de ejes, alineación y distribución de espacio. Una vez que internalizas el modelo mental, las propiedades específicas se buscan en un segundo en MDN. Lo importante es saber cuándo usar Grid y cuándo Flexbox — y eso viene con la práctica.