ToolPal
Editor de código mostrando CSS en un monitor

CSS Flexbox: Construir cualquier diseño en minutos con un generador visual

📷 Sai Kiran Anagani / Pexels

CSS Flexbox: Construir cualquier diseño en minutos con un generador visual

flex-direction, justify-content, align-items — ve exactamente qué hace cada propiedad con un playground visual en vivo. Incluye recetas de diseño comunes.

DPor Daniel Park30 de marzo de 202612 min de lectura

Mi viaje con Flexbox (y por qué todavía busco cosas)

Recuerdo el momento exacto en que pensé que entendía flexbox. Había estado luchando con una barra de navegación durante la mayor parte de una tarde, los flotantes no hacían lo que quería, inline-block estaba añadiendo espacios fantasma, y entonces alguien en un comentario de Stack Overflow dijo "usa flexbox." Así que lo hice. Escribí display: flex y todo se alineó. Magia.

Al día siguiente intenté centrar algo verticalmente y estaba completamente perdido de nuevo.

Eso es la cosa con flexbox — el punto de entrada se siente fácil, pero el modelo mental tarda un tiempo en hacer clic de verdad. El momento en que finalmente hizo clic para mí fue cuando dejé de pensar en términos de "izquierda, derecha, arriba, abajo" y empecé a pensar en términos de ejes. Una vez que ese cambio sucedió, flexbox se convirtió en genuinamente una de las herramientas más satisfactorias en CSS.

Si quieres experimentar visualmente mientras lees, echa un vistazo al Generador CSS Flexbox en ToolBox Hubs — te permite ajustar propiedades y ver el resultado en tiempo real, que honestamente es la forma más rápida de construir el modelo mental.


El modelo de contenedor flex

Todo en flexbox comienza con una regla: tienes un contenedor y tienes elementos dentro de él. Estableces display: flex en el contenedor, y los hijos directos se convierten en elementos flex. Esa es toda la jerarquía — contenedor y elementos.

.container {
  display: flex;
}

Esa una sola línea cambia mucho. Tus elementos ahora estarán en una fila por defecto, se extenderán para llenar la altura del contenedor, y se encogerán si no hay suficiente espacio. La mayoría de las propiedades de flexbox se establecen en el contenedor, no en los elementos.

Los dos ejes

Esta es la parte que confunde a casi todos los que aprenden flexbox, y diría que es el concepto más importante a interiorizar. Flexbox opera en dos ejes:

  • Eje principal — la dirección en que fluyen tus elementos (fila o columna)
  • Eje transversal — perpendicular al eje principal

Cuando flex-direction es row (el valor por defecto), el eje principal va de izquierda a derecha, y el eje transversal de arriba a abajo. Cuando cambias a column, esos se invierten. Esto importa enormemente porque justify-content y align-items están definidos relativos a estos ejes, no relativos a las direcciones absolutas.

Una vez que recuerdas que justify siempre significa "a lo largo del eje principal" y align siempre significa "a lo largo del eje transversal", todo lo demás se vuelve predecible.


Cada propiedad que realmente necesitas

flex-direction

Controla en qué dirección fluyen tus elementos.

.container {
  display: flex;
  flex-direction: row;         /* por defecto — izquierda a derecha */
  flex-direction: row-reverse; /* derecha a izquierda */
  flex-direction: column;      /* arriba a abajo */
  flex-direction: column-reverse; /* abajo a arriba */
}

column es algo que uso más de lo que esperaba cuando empecé. Cada vez que quieres apilar cosas verticalmente y controlar su espaciado, flex-direction: column combinado con gap es fantástico.

justify-content

Alinea elementos a lo largo del eje principal. En una fila, eso es horizontal. En una columna, eso es vertical.

.container {
  display: flex;
  justify-content: flex-start;    /* por defecto — elementos al inicio */
  justify-content: flex-end;      /* elementos al final */
  justify-content: center;        /* elementos en el medio */
  justify-content: space-between; /* espacio igual entre elementos, ninguno en los bordes */
  justify-content: space-around;  /* espacio igual alrededor de cada elemento */
  justify-content: space-evenly;  /* espacio verdaderamente igual en todas partes */
}

space-between es el que más uso para barras de navegación — los elementos se dispersan a ambos extremos con espacios iguales entre ellos. center es lo que quieres cuando solo necesitas que algo esté en el medio.

align-items

Alinea elementos a lo largo del eje transversal. En una fila, eso es vertical. En una columna, eso es horizontal.

.container {
  display: flex;
  align-items: stretch;     /* por defecto — los elementos se estiran para llenar la altura del contenedor */
  align-items: flex-start;  /* los elementos están en la parte superior */
  align-items: flex-end;    /* los elementos están en la parte inferior */
  align-items: center;      /* los elementos centrados verticalmente */
  align-items: baseline;    /* los elementos alineados por la línea base del texto */
}

stretch como valor por defecto es bastante útil en realidad — es por eso que los elementos flex en una fila terminan todos con la misma altura incluso cuando tienen diferentes cantidades de contenido. Pero una vez que quieres centrado vertical, usas align-items: center.

flex-wrap

Por defecto, los elementos flex intentan caber en una línea y se encogerán para lograrlo. flex-wrap te permite cambiar ese comportamiento.

.container {
  display: flex;
  flex-wrap: nowrap;       /* por defecto — elementos se quedan en una línea */
  flex-wrap: wrap;         /* elementos se envuelven a nuevas líneas */
  flex-wrap: wrap-reverse; /* elementos se envuelven hacia arriba */
}

flex-wrap: wrap es esencial para cuadrículas de tarjetas responsivas. Sin él, tus elementos seguirán encogiéndose sin importar cuán pequeño sea el viewport.

gap

gap no es técnicamente una propiedad solo-flex — vino de CSS Grid — pero funciona con flexbox y es genuinamente genial. Antes de gap, hacíamos hacks de margin. Ahora:

.container {
  display: flex;
  gap: 16px;          /* mismo espacio en ambas direcciones */
  gap: 12px 24px;     /* gap-fila gap-columna */
}

Úsalo en todas partes. Es más simple que margin y no añade espacio en los bordes.

align-content

Esta es fácil de pasar por alto. align-content es como justify-content pero para el eje transversal, y solo hace algo cuando tienes múltiples filas (es decir, cuando flex-wrap: wrap está en juego y los elementos han envuelto realmente). Si todos tus elementos están en una línea, align-content no tiene efecto visible.

.container {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  align-content: center;
  align-content: space-between;
}

Esta es probablemente la propiedad flexbox más comúnmente malinterpretada — la gente la establece esperando que algo pase y nada ocurre, porque sus elementos no están envolviendo.

Propiedades a nivel de elemento

Algunas propiedades van en los elementos flex mismos en lugar del contenedor.

flex-grow — cuánto crece un elemento para llenar el espacio disponible (por defecto: 0)

flex-shrink — cuánto se encoge un elemento cuando el espacio es escaso (por defecto: 1)

flex-basis — el tamaño inicial del elemento antes de crecer o encoger (por defecto: auto)

Estos tres se combinan a menudo con el shorthand flex:

.item {
  flex: 1;          /* grow: 1, shrink: 1, basis: 0 — elementos de igual ancho */
  flex: 0 0 200px;  /* ancho fijo, sin crecer ni encoger */
  flex: 2;          /* este elemento crece el doble de rápido que los hermanos flex: 1 */
}

align-self permite a un solo elemento anular la configuración align-items del contenedor:

.special-item {
  align-self: flex-end; /* este elemento se queda en la parte inferior aunque sus hermanos no lo hagan */
}

Patrones comunes

Centrar cualquier cosa (el clásico)

Este es probablemente el fragmento CSS más buscado en Google de la historia. Centrar un div tanto horizontal como verticalmente:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh; /* necesita algo de altura para centrar verticalmente dentro */
}

Eso es todo. Dos líneas (tres si cuentas la altura). Antes de flexbox, el centrado vertical era genuinamente doloroso. Ahora es memoria muscular.

Barra de navegación responsive

Una navegación horizontal que empuja el logo a la izquierda y los enlaces de navegación a la derecha:

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px;
}

Y para móvil, podrías cambiar a columna:

@media (max-width: 768px) {
  .navbar {
    flex-direction: column;
    gap: 12px;
  }
}

Cuadrícula de tarjetas responsive

Tarjetas que están una al lado de la otra en escritorio y se apilan en móvil:

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.card {
  flex: 1 1 300px; /* crecer, encoger, ancho mínimo de 300px */
  max-width: 400px;
}

El flex: 1 1 300px es la clave — dice "empieza con 300px de ancho, pero crece y encoge según sea necesario." Las tarjetas naturalmente refluirán en menos columnas en pantallas más pequeñas sin una sola media query.

El patrón clásico de "el footer se queda en la parte inferior incluso con poco contenido":

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1; /* el contenido principal crece para empujar el footer hacia abajo */
}

footer {
  /* se queda en la parte inferior */
}

Este está en casi todos los proyectos que construyo.


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

Hay mucho debate innecesario sobre esto en línea. La respuesta honesta es: usa ambos, son para cosas diferentes.

Elige Flexbox cuando:

  • Tienes una sola fila o columna de elementos
  • Quieres que los elementos se envuelvan naturalmente (como etiquetas, listas de tarjetas)
  • Estás construyendo una barra de navegación, toolbar o grupo de botones
  • Necesitas un eje de control con tamaño de elemento flexible

Elige CSS Grid cuando:

  • Tienes un diseño bidimensional con filas y columnas
  • Estás construyendo un diseño a nivel de página con encabezado, barra lateral, principal, pie de página
  • Quieres colocación explícita de elementos en celdas específicas
  • Necesitas alturas de fila consistentes en múltiples columnas

En la práctica, una página real podría usar Grid para el diseño general de la página, Flexbox para la navegación, Flexbox para el diseño interno de una tarjeta, y Grid de nuevo para una tabla de datos. Se complementan bien.


Errores comunes y trampas

flex-shrink: 0 para imágenes

Por defecto, los elementos flex pueden encoger. Las imágenes en contenedores flex se encogerán por debajo de su tamaño natural, lo que se ve terrible. Corrígelo:

img {
  flex-shrink: 0;
}

O usa el shorthand:

img {
  flex: 0 0 auto; /* no crecer, no encoger, usar tamaño natural */
}

El problema de desbordamiento min-width: 0

Este es sutil y vuelve loca a la gente. Por defecto, los elementos flex tienen min-width: auto, lo que significa que no se encogerán por debajo de su tamaño de contenido. Si tienes un elemento flex que contiene texto largo o un elemento ancho, puede desbordarse de su contenedor incluso cuando flex: 1 está establecido.

La solución:

.flex-item {
  min-width: 0; /* permitir que el elemento se encoja por debajo del tamaño del contenido */
  overflow: hidden; /* o overflow: auto si quieres desplazamiento */
}

align-content solo funciona con envoltura

Como se mencionó anteriormente, establecer align-content en un contenedor flex de una sola línea no hace absolutamente nada. Necesitas:

  1. flex-wrap: wrap en el contenedor
  2. Suficientes elementos para realmente envolver en múltiples líneas

margin: auto es poderoso en contenedores flex

Esto es más un arma secreta que una trampa, pero sorprende a la gente: establecer margin-left: auto en un elemento flex lo empujará (y todo lo que le sigue) al extremo lejano del contenedor. Así es como puedes hacer diseños de navegación con un logo a la izquierda y un botón de login en el extremo derecho sin elementos envolventes:

.nav {
  display: flex;
  align-items: center;
}

.nav-login {
  margin-left: auto; /* empuja el botón de login al borde derecho */
}

Construir diseños visualmente

Leer sobre las propiedades de flexbox es útil, pero la forma más rápida de realmente interiorizar el modelo mental es jugar con ellas. El Generador CSS Flexbox te permite alternar cada propiedad y ver el diseño actualizarse en tiempo real.

En serio, pasa 10 minutos haciendo clic en las propiedades. Consolidarás el modelo mental más rápido que horas de leer documentación.


Soporte de navegadores

Una cosa de la que no necesitas preocuparte con flexbox: el soporte de navegadores. Flexbox ha sido universalmente soportado desde alrededor de 2015. Cada navegador moderno lo soporta completamente. Incluso IE 11 tenía soporte parcial (aunque honestamente, si todavía soportas IE 11, tienes problemas mayores).

Puedes usar flexbox con confianza sin prefijos de proveedor ni polyfills. Los viejos prefijos -webkit-flex y -ms-flexbox están hace tiempo jubilados. Simplemente escribe flexbox estándar y envíalo.


Conclusión

Flexbox hizo clic para mí en el momento en que dejé de pensar en ello como "una forma de mover cosas a izquierda o derecha" y empecé a pensar en ello como un sistema de ejes y comportamientos de elementos. El eje principal es donde fluyen tus elementos. El eje transversal es perpendicular. justify-content controla el eje principal. align-items controla el eje transversal. Todo lo demás fluye de eso.

Los patrones que uso diariamente:

  • display: flex; justify-content: center; align-items: center para centrar
  • justify-content: space-between para navbars y toolbars
  • flex-wrap: wrap con gap para cuadrículas responsivas
  • flex: 1 para elementos de igual ancho o áreas de contenido que crecen
  • flex-direction: column; min-height: 100vh con flex: 1 en main para footers pegajosos

Ten cuidado con el problema de encoger imágenes, el problema de desbordamiento min-width: 0, y el hecho de que align-content necesita elementos envueltos para hacer algo.

Flexbox es genuinamente una de esas características CSS donde una vez que tienes el modelo mental, sientes que desbloqueaste un superpoder. No reemplaza CSS Grid — usa ambos — pero para diseños de un solo eje, es difícil superarlo.

Preguntas Frecuentes

D

Sobre el autor

Daniel Park

Senior frontend engineer based in Seoul. Seven years of experience building web applications at Korean SaaS companies, with a focus on developer tooling, web performance, and privacy-first architecture. Open-source contributor to the JavaScript ecosystem and founder of ToolPal.

Saber más

Compartir

XLinkedIn

Publicaciones relacionadas