Flexbox es una herramienta de maquetación my poderosa. Cuando realmente comprendemos cómo funciona, podemos crear diseños responsivos, es decir, se reorganizan según sea necesario.
Por ejemplo:
En pantallas con un ancho menor a 680px vas a tener algunos problemas apreciando todas las posibilidades de este diseño.
Esta demostración está fuertemente inspirada en el increíble codepen "4 diseños por el precio de 1" de Adam Argyle . No utiliza media queries o container queries. En lugar de establecer puntos de interrupción arbitrarios, utiliza flexbox para crear un diseño responsivo sin problemas.
Este es el CSS importante de éste formulario:
#flex-form
{
display:
flex
;
align-items:
flex-end
;
flex-wrap:
wrap
;
gap:
16
px
;
}
label[for='name']
{
flex-grow:
1
;
flex-basis:
160
px
;
}
label[for='email']
{
flex-grow:
3
;
flex-basis:
200
px
;
}
button
{
flex-grow:
1
;
flex-basis:
80
px
;
}
Introducción a Flexbox
CSS se compone de muchos algoritmos de diseño diferentes, conocidos oficialmente como "layout
modes". Cada modo de diseño es su propio sub-lenguaje dentro de CSS. El modo de diseño
predeterminado es “flow”, pero podemos optar por Flexbox cambiando la propiedad display
en
el
contenedor padre:
Cuando cambiamos el display
a flex
, creamos un
Cada algoritmo de diseño está diseñado para resolver un problema específico. El diseño predeterminado de "flow" está destinado a crear documentos digitales; es esencialmente el algoritmo de diseño de Microsoft Word . Los encabezados y los párrafos se apilan verticalmente como bloques, mientras que elementos como el texto, los enlaces y las imágenes se ubican discretamente dentro de estos bloques.
Entonces, ¿qué problema resuelve Flexbox? Flexbox se trata de organizar un grupo de elementos en una fila o columna, y nos brinda una cantidad ridícula de control sobre la distribución y alineación de esos elementos. Como sugiere el nombre, Flexbox tiene que ver con la flexibilidad. Podemos controlar si los artículos crecen o se encogen, cómo se distribuye el espacio adicional y más.
Flex Direction
Flexbox trata de controlar la distribución de elementos en una fila o columna.
De forma predeterminada, los elementos se acomodarán uno al lado del otro en una fila, pero podemos
pasar a
una columna con la propiedad
flex-direction
:
Con flex-direction: row
, el eje principal es horizontal, de izquierda a
derecha. Cuando cambiamos a flex-direction: column
, el eje principal es
vertical, de arriba a abajo.
¿Pero flex-direction: column
es lo mismo que tener los elementos con
display: block
? De manera visual: sí!
Y entonces para qué utilizo flex-direction: column
?
Ahhh... Excelente pregunta mi querido padawan. En Flexbox, todo se basa en el eje principal y al algoritmo no le importa si es vertical u horizontal, todas las reglas se estructuran en torno a este eje principal, y el eje secundario (secondary/cross axis) que se coloca de manera perpendicular al eje principal.
Y esto está muy cool! Porque cuando aprendemos las reglas de Flexbox, podemos cambiar sin problemas de diseños horizontales a verticales.
Todas las reglas se adaptan automáticamente. De hecho, esta función es exclusiva del modo de diseño Flexbox.
Los hijos se posicionan de acuerdo a 2 reglas:
- Eje principal: Los hijos se agruparán al inicio del contenedor.
- Eje secundario: Los hijos se estiran para llenar todo el contenedor.

Alineación
Es posible cambiar como es que los hijos se distribuyen sobre el eje principal utilizando la propiedad
justify-content
:
Cuando se trata del eje primario, no pensamos en términos de alinear a un solo hijo. En cambio, se trata de la distribución del grupo.
Podemos agrupar todos los elementos en un lugar particular (con flex-start
,
center
y flex-end
), o podemos separarlos (con space-between
,
space-around
y
space-evenly
).
Para el eje secundario, las cosas son un poco diferentes. Aquí usamos la propiedad
align-items
:
Interesante... Con align-items
, tenemos algunas de las mismas opciones que con
justify-content
, pero no exactamente las mismas.
justify-content
space-between
space-around
space-evenly
align-items
stretch
baseline
flex-start
center
flex-end
Align Self
A diferencia de justify-content
y align-items
, align-self
se
aplica a
los hijos, no al contenedor padre.
align-self
nos permite cambiar la alineación de un elemento específico a lo largo del eje
secundario:
align-self
tiene todos los mismos valores que align-items
. De hecho, cambian
exactamente lo mismo.
align-items
es syntctic sugar(?). Esta propiedad establece automáticamente la
alineación en todos los hijos a la vez.
Pero ojo 👀, no existe justify-self
, bueno, al menos no en Flexbox
Content .vs. items
Hasta el momento, Flexbox parece ser my arbitrario. ¿Porqué es justify-content
y
align-items
y no justify-items
o align-content
?
Y más aún, ¿porqué existe un align-self
y no justify-self
?
Esta es una de las cosas más importantes y menos comprendidas de Flexbox.
En Flexbox, los elementos se distribuyen la lo largo del eje principal.
De forma predeterminada, los elementos flexibles están alineados uno a lado del otro sobre el eje principal; y podemos dibujar una recta horizontal que atraviese a todos los elementos flexibles:
Primary Axis
En el eje secundario es diferente. Una linea cruza cada uno de los elementos flexibles:
Secondary Axis
Secondary Axis
Secondary Axis
De esta forma, es posible controlar cada uno de los elementos flexibles de manera independiente, al contrario del eje principal, en donde se mueven de manera conjunta.
Esta es la principal diferencia entre el eje principal y el eje secundario. Cuando hablamos del eje principal, los elementos se mueven en conjunto. En el eje secundario podemos controlarlos de manera individual.
Es por eso que no existe la propiedad justify-self
. ¿Qué haríamos si es que un elemento
tiene
la propiedad justify-self: center
? ¿Para dónde se mueve si hay elementos a su al rededor?
Con esto dicho, definamos los 4 términos:
justify:
para posicionar elementos a través del eje principal.align:
para posicionar los elementos a través del eje secundario.content:
un grupo de elementos por distribuir.items:
un solo elemento que se puede posicionar de manera individual.
No existe la propiedadjustify-items
por lo mismo que no existe justify-self
;
cuando hablamos del eje principal, pensamos a los elementos como un grupo y no de manera individual.
Tamaño hipotético
Supongamos que tenemos el siguiente codigo CSS:
.item
{
width
:
500
px
;
}
Una persona razonable diría que el elemento con la clase item
tiene un ancho de 500px.
Pero, lamento informarte, que no siempre es así...
<style>
.flex-wrapper
{
display
:
flex
;
}
.item
{
width
:
500
px
;
}
</style>
<div class="item"></div>
<div class="flex-wrapper">
<div class="item"></div>
</div>
Resultado:
.item
.item
Interesante, no?
Ambos tienen la misma medida aplicada. Ambos .item
tienen la propiedad
width: 500px
. Y aún así, el primer .item
es mucho más grande que el segundo!
La diferencia es el modo de diseño. El primer .item
está usando el modo de
flow, en el cual, el width
en una restricción estricta. Cuando establecemos
width: 500px
, obtendremos un elemento de 500 píxeles de ancho, incluso si tiene que salirse
de
nuestra pantalla.
En Flexbox, la propiedad width
es más una sugerencia que una restricción.
Y
por eso tenemos un nombre para esto: tamaño hipotético. Este es el tamaño que un
elemento
tendrá en un mundo perfecto y si nada se opone en su camino.
En ejemplo anterior, el contenedor padre no tenía el espacio suficiente para contener un
div
de
500px de ancho. Y por tanto, el hijo (flex item) se ajusta a su contenedor padre(flex
container).
Esta es una parte fundamental de la filosofía de Flexbox. Los elementos son fluidos y flexibles, y pueden ajustarse a las limitaciones del mundo.
Creciendo y encogiéndose
Entonces, hemos visto que el algoritmo Flexbox tiene cierta flexibilidad incorporada, con tamaños hipotéticos.
Pero para ver realmente cuán fluido puede ser Flexbox, necesitamos hablar sobre 3 propiedades:
flex-grow
, flex-shrink
y flex-basis
.
Estas propiedades se aplican a los elementos flexibles.
Flex basis
En una fila flex, flex-basis
hace lo mismo que width. En una columna flex,
flex-basis
hace lo mismo que height.
Los autores de Flexbox crearon una propiedad genérica de "tamaño" llamada flex-basis
. Es
como
width o height, pero vinculado al eje primario, como todo lo demás.
flex-basis
nos permite establecer el tamaño hipotético de un elemento sobre el eje
principal
, independientemente de si es horizontal o vertical.
El elemento seleccionado tiene asignada la propiedad de flex-basis: 50px;
por defecto,
intenta
cambiarla y averiguar qué sucederá.
flex-basis
es más una sugerencia que una restricción estricta. En cierto punto, simplemente
no
hay suficiente espacio para que todos los elementos se asienten en su tamaño asignado, por lo que tienen
que
comprometerse para evitar un desbordamiento.
Flex grow
Por defecto, los elementos en un contexto flex se reducirán a su tamaño mínimo cómodo a lo largo del eje principal. Esto a menudo crea espacio adicional.
Lo que nos da chance de especificar cómo se debe consumir ese espacio con la propiedad
flex-grow
:
El espacio que sobra dentro del contenedor se agrega directamente al elemento que tiene definida la
propiedad flex-grow
con el valor de 1
.

El valor por defecto para flex-grow
es 0
, lo que significa que el crecimiento
es
opcional. Si queremos que un elemento flex ocupe cualquier espacio adicional en el contenedor, debemos
decírselo explícitamente.
¿Y qué pasa si se establezco varios elementos flex con la propiedad
flex-grow
?
En este caso, mi querida tortuga ninja, el espacio extra se reparte entre los elementos,
proporcionalmente
en función de su valor flex-grow
.
Expliquémoslo de manera visual. Intenta incrementar/decrementar cada elemento flex:
El primer elemento quiere 1 unidad de espacio adicional, mientras que el segundo elemento quiere 1 unidad. Eso significa que el número total de unidades es 2 ( 1 + 1 ). Cada elemento recibe una parte proporcional de ese espacio extra.
Flex shrink
En los ejemplos que hemos visto hasta ahora, hemos tenido espacio adicional para trabajar. Pero, ¿y si nuestros elemento son demasiado grandes para su contenedor?
Intenta encoger el contenedor para ver qué sucede:
Interesante, ¿verdad? Ambos elementos se encogen, pero se encogen proporcionalmente. El primer elemento siempre mide 2 veces el ancho del segundo elemento.
Como recordatorio, flex-basis
tiene el mismo propósito que width
. Estamos
usando
flex-basis
porque es lo convencional al usar el modo de diseño Flexbox, ¡pero obtendríamos
exactamente el mismo resultado si usáramos width
!
flex-basis
y width
establecen el tamaño hipotético de los elementos. El
algoritmo
Flexbox puede reducir los elementos por debajo del tamaño deseado, pero de forma predeterminada. Siempre
se
escalarán juntos, preservando la proporción entre ambos elementos.
Ahora, ¿qué pasa si no queremos que nuestros elementos se reduzcan proporcionalmente? Ahí es donde entra
la
propiedad flex-shrink
.
Tómate un par de minutos, a ver si puedes averiguar qué está pasando aquí:
Tenemos dos elementos, cada uno con un tamaño hipotético de 200px
. El contenedor debe tener
al
menos 400px
de ancho para contener a estos elementos en su tamaño hipotético.
Supongamos que encogemos el contenedor a 300px
. Bueno, ¡no podemos meter 400px
de
contenido en un contenedor de 300px
! Tenemos un déficit de 100px
. Nuestros
elementos deberán ceder 100px
en total para que encajen.
La propiedad flex-shrink
nos permite decidir como se paga este déficit/deuda.
De la misma manera que flex-grow
, es una proporción. El valor por defecto de esta propiedad
es
flex-shrink: 1
, por lo que cada elemento paga la mitad de la deuda. Cada uno pierde
50px
y su tamaño real se reduce de 200px
a 150px
.
Ahora, supongamos que elevamos la propiedad flex-shrink
a 3
en el primer
elemento
flexible:

Tenemos un déficit total de 100px
. Normalmente, cada elemento pagaría ½, pero debido a que
hemos jugado con el flex-shrink
, el primer elemento termina pagando ¾ partes de
100px
(75px
) y el segundo elemento paga ¼ partes de 100px
(25px
).
Tengamos en cuenta que los valores absolutos no importan, se trata de la proporción. Si ambos elementos
tienen flex-shrink: 1
, cada elemento pagará la mitad del déficit total. Si ambos elementos
se
elevan a flex-shrink: 1000
, cada elemento pagará 1000/2000 del déficit total. Siempre
funciona
igual.
Podemos pensar en que flex-shrink
es el "inverso" de flex-grow
. Son dos caras
de
la misma moneda:
flex-grow:
controla cómo se distribuye el espacio adicional cuando los elementos son más pequeños que su contenedor.flex-shrink:
controla cómo se elimina el espacio cuando los elementos son más grandes que su contenedor.
Esto significa que solo una de estas propiedades puede estar "activa" a la vez. Si hay espacio extra,
flex-shrink
no tiene efecto, ya que los elementos no necesitan encogerse. Y si los
elementos
son demasiado grandes para su contenedor, flex-grow
no tiene efecto, porque no hay espacio
extra para repartir.
Gap
Una de las mayores mejoras que tuvo Flexbox en los últimos años ha sido la propiedad gap
:
gap
nos permite crear un espacio entre cada elemento Flex. Esto es genial para cosas como
las
barras de navegación:
gap
es una adición relativamente nueva al lenguaje Flexbox, se implementó en todos los
navegadores modernos desde principios del 2021.
Así es... Flexbox se tomó muy en serio la sana distancia.
Auto margin
Hay otro truco relacionado con el espacio que quiero compartir. Ha existido desde los primeros días de Flexbox, pero es relativamente oscuro y alucinante.
La propiedad margin
se utiliza para agregar espacio alrededor de un elemento específico. De
hecho, en algunos modos de diseño, como flow y positioning, se puede usar para centrar un elemento, con
margin: auto
.
Los márgenes automáticos son mucho más interesantes en Flexbox:
Los márgenes automáticos se comerán el espacio adicional y lo aplican al margen del elemento. Nos da un
control preciso sobre dónde distribuir el espacio extra sin estirar al elemento como
flex-grow
lo hace.
Wrapping
¡Uf! Hemos cubierto muchas cosas hasta ahora. Pero hay una ultima propiedad que me gustaría cubrir.
Hasta ahora, todos nuestros elementos se han posicionado lado a lado, en una sola fila o columna. La
propiedad flex-wrap
nos permite cambiar eso.
La mayoría de las veces, cuando trabajamos en dos dimensiones, preferimos usar CSS
Grid,
¡pero Flexbox + flex-wrap
definitivamente tiene sus usos!
Este ejemplo en particular muestra el diseño de "panqueque deconstruido", donde los elementos se apilan en una pirámide invertida en pantallas de tamaño mediano.
Cuando establecemos la propiedad flex-wrap
con el valor wrap
, los elementos
flexibles no se encogen más allá de su tamaño ideal (flex-basis
). Bueno, al menos, no
mientras
pasarse a la siguiente fila o columna sea una opción.
Oyeee! ‘Perate, ‘perate! ¿Qué pasa con lo que habíamos dicho de que existía un solo eje primario?
Con flex-wrap: wrap
, ya no vamos a tener un solo eje primario. Efectivamente, cada renglón
(o
columna) se comportará como un mini-contenedor flexible y por ende, cada uno tendrá su propio eje
principal.
Afortunadamente, todas la reglas que hemos visto hasta ahora siguen aplicando de la misma manera
Pero, ¿como va a funcionar la propiedad align-items
ahora que tenemos multiples renglones?
El
eje secundario ahora puede cruzar a varios elementos!
Toma un momento para considerar esto. ¿Qué crees que sucederá cuando cambiemos la
propiedad
de align-items
a los valores que ya conocemos?
En pantallas con un ancho menor a 740px no podemos apreciar el efecto que
tiene flex-wrap
Cada uno de los renglones es su propio mini-contenedor flexible. align-item
mueve a cada
elemento flexible hacia arriba o hacia abajo dentro de la caja invisible que envuelve a cada uno de los
renglones.
¿Y si ahora quiero alinear a los renglones de manera diferente? Eso lo podemos hacer con la propiedad
align-content
:
En pantallas con un ancho menor a 740px no podemos apreciar el efecto que
tiene flex-wrap
Cabe aclarar que los elementos flexibles necesitan espacio para moverse. Si no lo tienen disponible, no veremos grandes cambios.
Para resumir:
-
flex-wrap: wrap
deja que los elemento se acomoden en dos o más renglones. -
En cada renglón,
align-items
nos deja mover los elementos hacia arriba y abajo (sobre el eje secundario) dentro de las cajas invisibles determinadas por cada renglón. - ¡Ahora tenemos dos o más renglones en un solo contenedor! Y el eje secundario interseca a más de un elemento, por lo que ahora es posible mover los renglones como un grupo.
-
Usando las definiciones anteriores, estamos hablando del contenedor completo, no de los elementos
flexibles. Pero seguimos hablando del eje secundario. Por tanto la propiedad que estamos buscando es
align-content
.
Y ya 💁♀️
Estuvo tranqui, ¿no?
Claramente hay mucha información que procesar y, es que, analizamos cada una de las propiedades de manera exhaustiva.
En el día a día, no es necesario comprender en dónde queda cada uno de los pixeles, pero es bastante útil tener una guía cuando las cosas no funcionan como esperábamos.
Así que no pretendo que memorices toda la información que hay aquí, ¡si no que la utilices como apoyo para tus siguientes proyectos! Tus rueditas traseras de bicicleta, por decirlo de alguna manera.