Flexbox
¿Qué es Flexbox?
Flexbox (Flexible Box Layout) es un sistema de maquetación unidimensional: organiza elementos en una sola dirección, fila o columna. Es la herramienta adecuada cuando quieres distribuir y alinear un conjunto de elementos a lo largo de una línea.
Se activa en el contenedor, que a partir de ese momento se llama flex container. Sus hijos directos pasan a ser flex items y se comportan según las reglas de flexbox.
.contenedor {
display: flex;
}
Con eso es suficiente para activarlo. Por defecto, los hijos se colocan en fila horizontal, sin saltar de línea, y se encogen si el espacio disponible es insuficiente.
flex-direction: eje principal
Flexbox organiza los elementos a lo largo de un eje principal. flex-direction determina la dirección de ese eje:
.contenedor {
display: flex;
flex-direction: row; /* → fila, de izquierda a derecha (defecto) */
flex-direction: row-reverse; /* ← fila invertida */
flex-direction: column; /* ↓ columna, de arriba a abajo */
flex-direction: column-reverse;/* ↑ columna invertida */
}
El eje cruzado es perpendicular al eje principal: si el eje es horizontal (row), el cruzado es vertical, y viceversa. Esta distinción importa para entender justify-content y align-items.
justify-content: distribución en el eje principal
Controla cómo se distribuye el espacio entre los elementos a lo largo del eje principal:
.contenedor {
display: flex;
justify-content: flex-start; /* al inicio (defecto) */
justify-content: flex-end; /* al final */
justify-content: center; /* centrado */
justify-content: space-between; /* primero y último pegados a los bordes, espacio entre los demás */
justify-content: space-around; /* espacio a ambos lados de cada elemento */
justify-content: space-evenly; /* espacio exactamente igual entre todos */
}
space-between es probablemente el más usado en navegación horizontal: el primer elemento se alinea al inicio y el último al final, con el espacio restante repartido entre los demás.
align-items: alineación en el eje cruzado
Controla cómo se alinean los elementos en el eje cruzado (perpendicular al principal):
.contenedor {
display: flex;
align-items: stretch; /* se estiran para ocupar todo el cruzado (defecto) */
align-items: flex-start; /* alineados al inicio del eje cruzado */
align-items: flex-end; /* alineados al final */
align-items: center; /* centrados en el eje cruzado */
align-items: baseline; /* alineados por la línea de base del texto */
}
La combinación justify-content: center + align-items: center centra los hijos perfectamente en ambas dimensiones dentro del contenedor. Era notoriamente difícil de conseguir antes de flexbox:
.centrado-perfecto {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh; /* el contenedor ocupa al menos toda la pantalla */
}
flex-wrap: salto de línea
Por defecto, los flex items intentan caber en una sola línea, encogiéndose si es necesario (nowrap). flex-wrap: wrap permite que los elementos salten a la línea siguiente cuando no caben:
.tarjetas {
display: flex;
flex-wrap: wrap;
}
.tarjeta {
width: 300px; /* cada tarjeta tiene un ancho mínimo deseado */
}
Con flex-wrap: wrap, si no caben tres tarjetas de 300px, la tercera baja a la siguiente línea. Si hay varias líneas, align-content controla cómo se distribuyen entre sí (como justify-content pero para las líneas).
gap: espacio entre elementos
gap añade espacio entre los flex items sin necesidad de márgenes:
.contenedor {
display: flex;
gap: 1rem; /* mismo espacio horizontal y vertical */
gap: 1rem 2rem; /* vertical | horizontal */
}
La ventaja sobre los márgenes es que gap solo añade espacio entre elementos, nunca en los bordes exteriores del contenedor. No hay que compensar márgenes del primer o último elemento.
Propiedades en los hijos: flex, align-self, order
Las propiedades vistas hasta ahora se aplican al contenedor. Estas se aplican a cada hijo individualmente:
flex es la propiedad abreviada que combina tres valores: flex-grow (capacidad de crecer), flex-shrink (capacidad de encogerse) y flex-basis (tamaño inicial antes de distribuir el espacio sobrante):
/* flex: grow shrink basis */
.item { flex: 0 0 auto; } /* no crece, no encoge, tamaño por su contenido */
.item { flex: 1 1 0; } /* crece y encoge a partes iguales (forma canónica) */
.item { flex: 1; } /* equivale a flex: 1 1 0 (forma corta) */
.item { flex: 2; } /* crece el doble que los items con flex: 1 */
Un caso frecuente: una barra con un logo fijo a la izquierda y el resto del espacio para el menú:
.barra {
display: flex;
align-items: center;
}
.logo { flex: 0 0 auto; } /* tamaño fijo, no crece */
.menu { flex: 1; } /* ocupa todo el espacio restante */
align-self sobreescribe align-items para un hijo concreto:
.contenedor { align-items: center; }
.especial { align-self: flex-end; } /* este hijo va al final del eje cruzado */
order cambia el orden visual de los elementos sin alterar el HTML. El valor por defecto es 0; valores menores van antes, mayores van después:
.primero-visual { order: -1; }
.ultimo-visual { order: 1; }
Patrones frecuentes
Navegación horizontal:
nav ul {
display: flex;
list-style: none;
margin: 0;
padding: 0;
gap: 2rem;
align-items: center;
}
Barra con logo y menú en extremos:
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
Cuadrícula de tarjetas flexible:
.grid-tarjetas {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.tarjeta {
flex: 1 1 280px; /* mínimo 280px, crece si hay espacio */
max-width: 400px; /* pero no demasiado */
}
Footer con columnas:
.footer-contenido {
display: flex;
gap: 2rem;
flex-wrap: wrap;
}
.footer-columna {
flex: 1 1 200px;
}
Recapitulación
display: flexconvierte un elemento en flex container. Sus hijos directos son flex items.flex-directiondefine el eje principal:row(horizontal, defecto) ocolumn(vertical).justify-contentdistribuye el espacio a lo largo del eje principal:flex-start,center,flex-end,space-between,space-around,space-evenly.align-itemsalinea los elementos en el eje cruzado:stretch(defecto),center,flex-start,flex-end,baseline.flex-wrap: wrappermite que los elementos salten a la siguiente línea cuando no caben.gapañade espacio entre elementos sin márgenes externos. Acepta uno o dos valores (vertical, horizontal).- En los hijos:
flex: 1hace que el elemento ocupe espacio proporcional disponible.align-selfsobreescribealign-items.ordercambia el orden visual. - Flexbox es la herramienta para distribución en una dimensión: filas de elementos, barras de navegación, centrado.
Tu proyecto
Reorganiza el <header> con Flexbox para poner el nombre y el nav en la misma línea, y añade una sección de estadísticas rápidas en fila:
header {
display: flex;
justify-content: space-between;
align-items: flex-end;
flex-wrap: wrap;
gap: 1rem;
}
.stats {
display: flex;
gap: 3rem;
margin-top: 2rem;
}
.stat-numero {
font-size: 2.5rem;
font-weight: 600;
line-height: 1;
}
.stat-etiqueta {
font-size: 0.8rem;
color: #888;
margin-top: 0.25rem;
}
<div class="stats">
<div>
<div class="stat-numero">47</div>
<div class="stat-etiqueta">Proyectos completados</div>
</div>
<div>
<div class="stat-numero">15</div>
<div class="stat-etiqueta">Años de experiencia</div>
</div>
</div>
En la próxima lección: CSS Grid: layout bidimensional para crear cuadrículas de proyectos, galerías y estructuras de página complejas.