Menu

Flexbox en CSS: display flex, ejes, alineación y flex

Flexbox coloca elementos en una fila o una columna y controla cómo comparten el espacio y cómo se alinean. Aprende display: flex, el eje principal y el transversal, todas las propiedades del contenedor, flex-grow, flex-shrink y flex-basis, con un playground en vivo que mide dónde queda cada elemento.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Qué hace display: flex

Pon display: flex en un padre y sus hijos directos se alinean en una fila, uno al lado del otro, y se estiran a la misma altura. Esa sola declaración reemplaza a los floats, a inline-block y a la mayoría de los trucos de posicionamiento para colocar una fila de cosas.

En la primera caja cada div ocupa una línea entera. En la segunda, los tres elementos quedan en una fila, cada uno tan ancho como su contenido, y One y Three se estiran hasta la altura de Two. Solo cambió el padre: display: flex va en el contenedor, nunca en los elementos.

Playground de flexbox

Elige valores y mira cómo se mueven los elementos. La línea de código debajo de la caja es el CSS de lo que ves, y la lista de abajo es dónde colocó el navegador cada elemento, medido con getBoundingClientRect().

Cosas para probar:

  • justify-content: space-between: el elemento 1 queda en x 0 y el elemento 3 toca el borde opuesto.
  • align-items: center: los tres elementos conservan sus propias alturas y sus centros se alinean. Con el stretch por defecto, el elemento 1 no tiene altura propia y ocupa los 170px completos del contenedor.
  • flex-direction: column: ahora justify-content mueve los elementos en vertical y align-items en horizontal. Las dos propiedades siguen a los ejes, no a la pantalla.

Eje principal y eje transversal

Todo contenedor flex tiene dos ejes. El eje principal es la dirección en la que fluyen los elementos, definida por flex-direction. El eje transversal lo cruza.

flex-directionEje principalEje transversaljustify-content mueve los elementosalign-items mueve los elementos
row (por defecto)horizontal, en orden de lecturaverticalen horizontalen vertical
row-reversehorizontal, invertidoverticalen horizontalen vertical
columnvertical, de arriba abajohorizontalen verticalen horizontal
column-reversevertical, de abajo arribahorizontalen verticalen horizontal

En una página de derecha a izquierda (dir="rtl"), row empieza en el borde derecho, porque el eje principal sigue la dirección de escritura.

Propiedades del contenedor

Van en el elemento que tiene display: flex:

PropiedadQué hacePor defecto
flex-directionFila o columna, y en qué sentidorow
flex-wrapSi los elementos pasan a una nueva línea cuando se quedan sin espacionowrap
flex-flowAbreviatura de flex-direction y flex-wraprow nowrap
justify-contentColocación y espaciado a lo largo del eje principalnormal (actúa como flex-start)
align-itemsColocación de los elementos a lo largo del eje transversalnormal (actúa como stretch)
align-contentEspaciado entre líneas cuando los elementos pasan a varias líneasnormal
gapEspacio entre elementos (row-gap, column-gap)0

justify-content y align-items tienen su propia página con todos los valores: justify-content y align-items. El salto de línea y la dirección están en la página de flex-wrap.

Propiedades de los elementos: flex-grow, flex-shrink, flex-basis

Van en los hijos y deciden cómo se reparten el ancho del contenedor:

  • flex-basis: el tamaño del que parte un elemento antes de repartir el espacio libre (auto significa "usa mi ancho o mi contenido").
  • flex-grow: cuántas partes del espacio sobrante toma el elemento. 0 significa que nunca crece.
  • flex-shrink: cuánto cede el elemento cuando no hay espacio suficiente. 0 significa que nunca se encoge.

La abreviatura flex define las tres:

EscribesQue significaComportamiento
flex: initial (por defecto)0 1 autoTamaño del contenido, puede encogerse, nunca crece
flex: 11 1 0%Parte de cero y toma una parte igual del espacio
flex: auto1 1 autoTamaño del contenido más una parte del espacio sobrante
flex: none0 0 autoExactamente su contenido o su ancho, nunca crece ni se encoge
flex: 22 1 0%El doble de la parte de un elemento con flex: 1

Cada fila mide 480px de ancho dentro de su padding, y los dos gaps de 8px dejan 464px para los elementos. Los anchos impresos muestran cómo se repartió: unos 155px cada uno en la primera fila, 116 + 232 + 116 en la segunda (el elemento con flex: 2 recibe el doble de la parte de cada vecino) y 100 + 372 en la tercera, donde el elemento con flex: none conserva su ancho y el otro se queda con todo lo demás.

Layouts reales con flexbox

Un encabezado con el logo al inicio y los enlaces al final es el layout flex más común. margin-inline-start: auto en un elemento se come todo el espacio libre que hay antes de él y lo empuja, junto con todo lo que le sigue, hasta el final:

align-items: center alinea el texto más grande del logo con los enlaces, y gap separa los enlaces sin márgenes que haya que deshacer en el último.

Un segundo patrón cotidiano es una fila de medios: un ícono de tamaño fijo y un texto que toma el resto y pasa a varias líneas dentro de su propia columna.

flex: none es la garantía. Los elementos flex se encogen por defecto, así que si se lo quitas al círculo y también quitas flex: 1 del texto, el párrafo aprieta el círculo hasta unos 23px de ancho: un óvalo. Para centrar una cosa en una caja, flexbox son dos líneas (justify-content: center; align-items: center); la página de cómo centrar un div lo compara con las otras formas.

order y accesibilidad

La propiedad order y las direcciones -reverse cambian dónde aparecen los elementos, no dónde están en el HTML. Los lectores de pantalla y la tecla Tab siguen el orden del HTML, así que un usuario de teclado puede saltar del primer enlace en pantalla al último. Úsalos solo como decoración; cuando el orden significa algo, cambia el HTML.

Flexbox o grid

Flexbox trabaja en una dirección a la vez: los elementos de una fila toman su tamaño de su contenido, y una segunda línea (con salto de línea) no se alinea con la primera. Grid trabaja en dos: defines columnas y filas y los elementos encajan en ellas. Una barra de navegación, una barra de herramientas o una fila de formulario es flexbox; una galería o una página con barra lateral es grid.

Errores comunes

  • display: flex en el elemento en lugar del padre. El contenedor recibe display: flex; sus hijos son los elementos.
  • Esperar que align-items mueva los elementos en vertical sin altura. Si el contenedor solo es tan alto como su elemento más alto, no hay espacio para moverlos. Dale una altura al contenedor; si no, está funcionando y simplemente no tiene nada que hacer.
  • Texto que se desborda en lugar de encogerse. Los elementos flex tienen min-width: auto. Agrega min-width: 0 al elemento que debe encogerse.
  • Usar flex: 1 y no entender por qué los anchos son distintos. Los elementos con flex: 1 se reparten el espacio por igual, pero un elemento cuyo contenido no cabe (una URL larga, una imagen) no se encoge por debajo de él. min-width: 0 también lo soluciona.
  • Márgenes entre elementos. Usa gap en el contenedor; solo va entre los elementos.
  • Anidar flex sin necesidad. Solo los hijos directos son elementos flex. Los nietos siguen el layout normal salvo que su propio padre también tenga display: flex.

Preguntas frecuentes

¿Qué hace display: flex?

Convierte un elemento en un contenedor flex. Sus hijos directos pasan a ser elementos flex y se colocan en fila por defecto, uno al lado del otro, estirados a la misma altura, y propiedades como justify-content, align-items y gap controlan cómo comparten el espacio.

¿Qué significa flex: 1?

flex: 1 es la abreviatura de flex: 1 1 0%: el elemento puede crecer (flex-grow: 1), puede encogerse (flex-shrink: 1) y parte de un tamaño cero (flex-basis: 0%). Los elementos que tienen todos flex: 1 se reparten el espacio libre a partes iguales, así que terminan con el mismo ancho salvo que su contenido no quepa.

¿Qué diferencia hay entre justify-content y align-items?

justify-content coloca los elementos a lo largo del eje principal (en horizontal en una fila) y align-items a lo largo del eje transversal (en vertical en una fila). Con flex-direction: column los dos ejes se intercambian, así que justify-content pasa a ser vertical.

¿Uso flexbox o grid?

Usa flexbox para una sola fila o columna cuyos elementos toman su tamaño de su contenido: barras de navegación, grupos de botones, una etiqueta al lado de un input. Usa grid cuando quieres filas y columnas que se alineen entre sí, como una cuadrícula de tarjetas o el layout de una página.

¿Por qué mi elemento flex se desborda de su contenedor?

Un elemento flex tiene min-width: auto por defecto, así que no se encoge por debajo del ancho de su palabra más larga o de su hijo más ancho. Pon min-width: 0 (u overflow: hidden) en el elemento para que pueda encogerse, por ejemplo para que funcione text-overflow: ellipsis.

¿Flexbox funciona con elementos inline como span?

Sí. Cualquier elemento con display: flex es un contenedor flex, y sus hijos pasan a ser elementos flex sea cual sea su propio display, así que los hijos <span> dejan de ser inline y aceptan ancho, alto y margin como bloques.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR