CSS Flexbox vs Grid: Cuándo usar cuál

· 12 min de lectura

Tabla de contenidos

Elegir entre CSS Flexbox y Grid puede resultar abrumador, especialmente cuando ambos parecen capaces de resolver los mismos problemas de diseño. La verdad es que están diseñados para propósitos diferentes, y comprender sus fortalezas te convertirá en un desarrollador más efectivo.

Esta guía desglosa todo lo que necesitas saber sobre Flexbox y Grid, desde conceptos básicos hasta aplicaciones del mundo real. Al final, sabrás exactamente qué herramienta usar en cualquier escenario de diseño.

Conceptos básicos de Flexbox (diseño 1D)

Flexbox está diseñado para diseños unidimensionales: organizar elementos en una sola fila o columna. Sobresale en la distribución de espacio y la alineación de elementos a lo largo de un eje, lo que lo hace perfecto para barras de navegación, grupos de botones y contenido que fluye en una sola dirección.

Conceptos fundamentales

Cada diseño Flexbox tiene un contenedor flex (padre) y elementos flex (hijos). El contenedor controla la dirección, el ajuste y la alineación de sus elementos:

/* El contenedor flex */
.container {
  display: flex;
  flex-direction: row;      /* row | row-reverse | column | column-reverse */
  justify-content: center;  /* Alineación del eje principal */
  align-items: center;      /* Alineación del eje transversal */
  gap: 1rem;                /* Espacio entre elementos */
  flex-wrap: wrap;          /* Permitir que los elementos se ajusten a la siguiente línea */
}

/* Elementos flex */
.item {
  flex: 1;                  /* Crecer para llenar el espacio disponible */
  /* Abreviatura de: flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
}

.item-fixed {
  flex: 0 0 200px;          /* No crecer, no encoger, 200px de ancho */
}

Comprendiendo los ejes principal y transversal

La clave para dominar Flexbox es comprender sus dos ejes. El eje principal corre en la dirección establecida por flex-direction (horizontal para fila, vertical para columna). El eje transversal corre perpendicular a él.

Este sistema de ejes determina qué propiedades controlan qué dimensiones. justify-content siempre funciona en el eje principal, mientras que align-items funciona en el eje transversal.

Propiedades de alineación

/* Eje principal (horizontal en dirección de fila) */
.container {
  justify-content: flex-start;   /* Predeterminado: empaquetar elementos al inicio */
  justify-content: flex-end;     /* Empaquetar elementos al final */
  justify-content: center;       /* Centrar elementos */
  justify-content: space-between;/* Espacio igual entre elementos */
  justify-content: space-around; /* Espacio igual alrededor de elementos */
  justify-content: space-evenly; /* Espacio igual en todas partes */
}

/* Eje transversal (vertical en dirección de fila) */
.container {
  align-items: stretch;    /* Predeterminado: estirar para llenar el contenedor */
  align-items: flex-start; /* Alinear arriba */
  align-items: flex-end;   /* Alinear abajo */
  align-items: center;     /* Centrar verticalmente */
  align-items: baseline;   /* Alinear líneas base del texto */
}

La propiedad Flex explicada

La propiedad flex es una abreviatura de tres propiedades: flex-grow, flex-shrink y flex-basis. Comprender estas individualmente te ayuda a escribir diseños más precisos.

.item-grow {
  flex: 1;        /* Equivalente a: 1 1 0% */
}

.item-fixed {
  flex: 0 0 200px; /* No crecer ni encoger, permanecer en 200px */
}

.item-shrink {
  flex: 0 1 auto;  /* No crecer, pero puede encogerse si es necesario */
}

Consejo profesional: Usa flex: 1 cuando quieras que los elementos compartan espacio por igual, y flex: 0 0 auto cuando quieras que los elementos mantengan su tamaño natural sin crecer ni encogerse.

Conceptos básicos de Grid (diseño 2D)

CSS Grid está construido para diseños bidimensionales: controlar filas y columnas simultáneamente. Es la opción preferida para diseños a nivel de página, cuadrículas de tarjetas y cualquier diseño donde necesites control preciso sobre ambas dimensiones.

Conceptos fundamentales

Los diseños Grid consisten en un contenedor grid y elementos grid. A diferencia de Flexbox, Grid te permite definir pistas explícitas (filas y columnas) y colocar elementos en cualquier lugar dentro de esa estructura:

/* El contenedor grid */
.container {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;  /* 3 columnas */
  grid-template-rows: auto 1fr auto;     /* 3 filas */
  gap: 1rem;                             /* Espacio entre celdas */
  grid-auto-flow: row;                   /* Cómo fluyen los elementos colocados automáticamente */
}

/* Elementos grid */
.item {
  grid-column: 1 / 3;    /* Abarcar desde la línea de columna 1 a 3 */
  grid-row: 1 / 2;       /* Ocupar la primera fila */
}

.item-area {
  grid-area: header;     /* Colocar en área nombrada */
}

Comprendiendo las líneas y pistas de Grid

Grid crea líneas numeradas entre pistas. Una cuadrícula de 3 columnas tiene 4 líneas verticales (1, 2, 3, 4). Los elementos se colocan especificando entre qué líneas abarcan.

Las pistas son los espacios entre líneas: tus columnas y filas reales. Puedes dimensionarlas con unidades fijas (px), unidades flexibles (fr) o dimensionamiento basado en contenido (auto, min-content, max-content).

La unidad FR

La unidad fr es el superpoder de Grid. Representa una fracción del espacio disponible, distribuyéndolo proporcionalmente entre las pistas:

.container {
  grid-template-columns: 1fr 2fr 1fr;  /* La columna del medio obtiene 2x espacio */
  grid-template-columns: 200px 1fr;    /* Barra lateral fija, contenido flexible */
  grid-template-columns: repeat(3, 1fr); /* Tres columnas iguales */
}

Áreas de Grid nombradas

La función de áreas de plantilla de Grid te permite crear diseños usando sintaxis similar a arte ASCII, haciendo que los diseños complejos sean legibles:

.container {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar content content"
    "footer footer footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
}

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

Colocación automática y flujo automático de Grid

Grid puede colocar automáticamente elementos que no posicionas explícitamente. La propiedad grid-auto-flow controla si los elementos llenan primero las filas (predeterminado) o las columnas primero:

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: dense;  /* Llenar huecos con elementos más pequeños */
}

Consejo profesional: Usa grid-auto-flow: dense para diseños tipo mampostería donde quieras llenar huecos, pero ten en cuenta que esto puede cambiar el orden visual de los elementos, afectando potencialmente la accesibilidad.

Comparación lado a lado

Comparemos Flexbox y Grid en dimensiones clave para comprender sus diferencias fundamentales:

Característica Flexbox Grid
Dimensionalidad Unidimensional (fila O columna) Bidimensional (filas Y columnas)
Impulsado por contenido Sí - los elementos controlan su tamaño No - el contenedor define la estructura
Dirección del diseño Un solo eje a la vez Ambos ejes simultáneamente
Colocación de elementos Secuencial (orden de origen) Posicionamiento explícito posible
Alineación Potente en un solo eje Potente en ambos ejes
Soporte de gap Sí (navegadores modernos) Sí (desde el principio)
Mejor para Componentes, navegación, barras de herramientas Diseños de página, cuadrículas de tarjetas, paneles
Curva de aprendizaje Moderada Más pronunciada inicialmente

Diferencias conceptuales

La diferencia fundamental se reduce al control. Flexbox es de contenido hacia afuera: los elementos influyen en el diseño según el tamaño de su contenido. Grid es de diseño hacia adentro: defines la estructura primero, luego colocas el contenido en ella.

Piensa en Flexbox como una regla flexible que se ajusta a lo que estás midiendo. Grid es más como papel cuadriculado donde decides la estructura por adelantado.

Escenario Enfoque Flexbox Enfoque Grid
Barra de navegación Ajuste natural - elementos en una fila Excesivo - demasiada estructura
Cuadrícula de tarjetas Posible pero ajuste incómodo Perfecto - filas y columnas explícitas
Diseño de formulario Bueno para formularios simples Mejor para formularios complejos de múltiples columnas
Diseño de página Requiere anidar múltiples contenedores Un solo contenedor puede manejarlo
Centrar contenido Excelente - simple e intuitivo También excelente - place-items: center

Cuándo usar Flexbox

Flexbox brilla en escenarios donde el contenido fluye en una sola dirección y los elementos necesitan adaptarse al espacio disponible. Aquí están las situaciones donde Flexbox es tu mejor opción:

Barras de navegación y menús

Los componentes de navegación son el ejemplo perfecto para Flexbox. Los elementos fluyen naturalmente en una fila, y a menudo quieres que distribuyan el espacio uniformemente o se alineen en extremos opuestos:

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
  list-style: none;
}

Grupos de botones y barras de herramientas

Cuando tienes una colección de botones o herramientas que deben estar uno al lado del otro, Flexbox maneja el espaciado y la alineación perfectamente:

.button-group {
  display: flex;
  gap: 0.5rem;
}

.toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1rem;
}

Objetos multimedia

El patrón clásico de objeto multimedia (imagen en un lado, contenido en el otro) es trivial con Flexbox:

.media {
  display: flex;
  gap: 1rem;
}

.media-image {
  flex: 0 0 100px;  /* Imagen de ancho fijo */
}

.media-content {
  flex: 1;  /* El contenido toma el espacio restante */
}

Controles de formulario

Grupos de entrada donde una etiqueta, entrada y botón se sientan en una fila son perfectos para Flexbox:

.input-group {
  display: flex;
  gap: 0.5rem;
}

.input-group input {
  flex: 1;  /* La entrada crece para llenar el espacio */
}

.input-group button {
  flex: 0 0 auto;  /* El botón permanece en tamaño natural */
}

Centrado vertical