El modelo de los dos ejes
¿Cuántas veces has peleado para centrar algo verticalmente o repartir bien una fila de elementos? Flexbox existe justo para eso: alinear y distribuir cualquier cosa sin batallas. Y el centrado vertical, el viejo dolor de cabeza, pasa a ser un par de líneas.
Cuando aplicas display: flex a un elemento, este se convierte en un
contenedor flex y sus hijos directos en flex items. Lo que distingue a
flexbox de todo lo anterior es que razona en términos de dos ejes, no de
filas y columnas absolutas:
- Eje principal (main axis): la dirección en la que se colocan los items.
- Eje cruzado (cross axis): el perpendicular al principal.
La clave conceptual: justify-content alinea en el eje principal y
align-items alinea en el eje cruzado. Qué eje es cuál lo decide
flex-direction.
flex-direction: quién es el eje principal
.contenedor {
display: flex;
flex-direction: row; /* por defecto: eje principal horizontal → */
}
Con row el eje principal va de izquierda a derecha, así que
justify-content reparte horizontalmente y align-items alinea
verticalmente. Con column los papeles se intercambian:
.contenedor {
display: flex;
flex-direction: column; /* eje principal vertical ↓ */
}
Ahora justify-content reparte en vertical y align-items en
horizontal. ⚠️ TRAMPA CLÁSICA: confundir los dos ejes es el error número
uno con flexbox. No memorices "justify = horizontal", memoriza "justify = eje
principal" y deja que flex-direction decida cuál es ese eje.
Existen también
row-reverseycolumn-reverse, que invierten el orden visual de los items sin tocar el HTML.
justify-content: repartir el eje principal
justify-content decide qué hacer con el espacio sobrante del eje
principal:
.barra {
display: flex;
justify-content: space-between; /* extremos pegados, hueco en medio */
}
| Valor | Efecto |
|---|---|
flex-start |
Items al inicio (por defecto). |
center |
Items agrupados en el centro. |
flex-end |
Items al final. |
space-between |
Primero y último pegados a los bordes; huecos iguales. |
space-around |
Hueco igual alrededor de cada item (medio en los bordes). |
space-evenly |
Huecos exactamente iguales, también en los bordes. |
align-items: alinear el eje cruzado
.contenedor {
display: flex;
align-items: center; /* centra los items en el eje cruzado */
}
Su valor por defecto es stretch: los items se estiran para ocupar todo
el alto del contenedor (en una fila). Por eso, si pones display: flex en una
fila de tarjetas con distinto contenido, todas acaban con la misma altura
"gratis", sin que tengas que igualarlas a mano. Otros valores: flex-start,
flex-end, baseline.
flex-wrap: permitir varias líneas
Por defecto los items no saltan de línea: se encogen hasta caber. Con
flex-wrap: wrap permites que pasen a una nueva línea cuando no quepan:
.galeria {
display: flex;
flex-wrap: wrap; /* nowrap (por defecto) | wrap | wrap-reverse */
}
gap: separación sin márgenes
gap define el espacio entre items sin añadirlo en los bordes, evitando
los antiguos hacks de margin con "el último sin margen":
.contenedor {
display: flex;
gap: 16px; /* mismo hueco horizontal y vertical */
gap: 8px 24px; /* fila columna: 8px entre filas, 24px entre columnas */
}
Con estas seis propiedades del contenedor ya resuelves la mayoría de los layouts del día a día. El control fino vive en los items, y es justo lo que viene ahora.