Flexbox
Antes de flexbox, colocar elementos en horizontal era un infierno de floats, clearfixes y hacks. Hoy, poner 3 cards en fila, centrar un elemento vertical y horizontalmente, o crear una barra de navegación es cuestión de unas pocas líneas. Flexbox cambió CSS para siempre.
El concepto: contenedor y elementos
Flexbox funciona con dos roles:
- Flex container: el padre al que le pones
display: flex. - Flex items: los hijos directos del contenedor. Se alinean automáticamente.
<nav class="navbar">
<a href="/" class="logo">Vinyl Paradise</a>
<ul class="nav-links">
<li><a href="#catalogo">Catálogo</a></li>
<li><a href="#novedades">Novedades</a></li>
<li><a href="#contacto">Contacto</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between; /* Logo a la izda, links a la dcha */
align-items: center; /* Centrado vertical */
padding: 1rem 2rem;
background: #141414;
}
.nav-links {
display: flex;
gap: 2rem; /* Espacio entre los enlaces */
list-style: none;
}
Con 5 líneas tienes una barra de navegación que antes requería 20+ líneas de CSS con floats.
Dirección: row vs column
.container {
display: flex;
/* En fila — por defecto */
flex-direction: row;
/* En columna — los elementos se apilan verticalmente */
flex-direction: column;
/* Invertidos */
flex-direction: row-reverse;
flex-direction: column-reverse;
}
Cuando usas flex-direction: column, los ejes se intercambian: justify-content afecta al eje vertical y align-items al horizontal.
Justify-content: distribuir en el eje principal
.container {
display: flex;
/* Todos al inicio (por defecto) */
justify-content: flex-start;
/* Todos al final */
justify-content: flex-end;
/* Centrados */
justify-content: center;
/* Espacio entre elementos (primero y último pegados a los bordes) */
justify-content: space-between;
/* Espacio alrededor de cada elemento */
justify-content: space-around;
/* Espacio igual entre y alrededor */
justify-content: space-evenly;
}
Align-items: alinear en el eje cruzado
.container {
display: flex;
min-height: 200px;
/* Estirar para llenar el contenedor (por defecto) */
align-items: stretch;
/* Arriba */
align-items: flex-start;
/* Abajo */
align-items: flex-end;
/* Centrado vertical */
align-items: center;
/* Alinear por la línea base del texto */
align-items: baseline;
}
El truco del centrado perfecto
/* Centrar cualquier cosa vertical y horizontalmente */
.centered {
display: flex;
justify-content: center;
align-items: center;
min-height: 100dvh;
}
/* O más corto con place-items (grid es mejor para esto, pero funciona) */
.centered-alt {
display: grid;
place-items: center;
min-height: 100dvh;
}
Gap: espacio entre elementos
.card-grid {
display: flex;
gap: 1.5rem; /* Espacio uniforme */
gap: 1rem 2rem; /* row-gap | column-gap */
}
Usa gap en lugar de márgenes en los hijos. No tiene problemas de colapso de márgenes y no necesitas hack de "último elemento sin margen".
Flex-wrap: envolver elementos
Por defecto, flex comprime los elementos para que quepan en una línea. Con flex-wrap: wrap permite que salten a la siguiente línea:
.tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag {
padding: 0.25rem 0.75rem;
background: #222;
border-radius: 999px;
font-size: 0.85rem;
}
<div class="tags">
<span class="tag">Rock</span>
<span class="tag">Jazz</span>
<span class="tag">Electrónica</span>
<span class="tag">Hip Hop</span>
<span class="tag">Indie</span>
<span class="tag">Clásica</span>
<span class="tag">Funk</span>
<span class="tag">Soul</span>
</div>
Flex-grow, flex-shrink y flex-basis
Estas propiedades van en los hijos (flex items), no en el contenedor:
.sidebar {
flex-basis: 280px; /* Ancho inicial */
flex-shrink: 0; /* No se encoge */
}
.main-content {
flex-grow: 1; /* Ocupa todo el espacio sobrante */
}
/* Shorthand: flex: grow shrink basis */
.sidebar {
flex: 0 0 280px; /* No crece, no encoge, base 280px */
}
.main-content {
flex: 1; /* Crece para llenar. Equivale a flex: 1 1 0% */
}
Layout típico: sidebar + contenido
.app-layout {
display: flex;
min-height: 100dvh;
}
.sidebar {
flex: 0 0 280px;
background: #141414;
padding: 2rem;
}
.content {
flex: 1;
padding: 2rem;
}
/* En móvil: apilar verticalmente */
@media (max-width: 768px) {
.app-layout {
flex-direction: column;
}
.sidebar {
flex-basis: auto;
}
}
Order: cambiar el orden visual
/* Mover un elemento al principio sin cambiar el HTML */
.featured-card {
order: -1; /* Por defecto todos tienen order: 0 */
}
/* Mover al final */
.newsletter-cta {
order: 99;
}
Usa
ordercon moderación. Cambiar el orden visual sin cambiar el HTML puede confundir a usuarios de lectores de pantalla, que siguen el orden del DOM.
Align-self: alineación individual
.flex-container {
display: flex;
align-items: flex-start; /* Todos arriba */
}
.special-item {
align-self: center; /* Este en concreto, centrado */
}
.push-to-bottom {
align-self: flex-end; /* Este, abajo */
}
Patrones comunes con flexbox
Card con footer pegado abajo
.card {
display: flex;
flex-direction: column;
min-height: 300px;
}
.card-body {
flex: 1; /* Ocupa todo el espacio disponible */
}
.card-footer {
/* Se queda abajo automáticamente */
padding-block-start: 1rem;
border-top: 1px solid #222;
}
Lista de acciones alineada a la derecha
.toolbar {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* Empujar los botones de acción a la derecha */
.toolbar-actions {
margin-inline-start: auto;
}
Maqueta el catálogo de Vinyl Paradise
Construye la página del catálogo de la tienda de vinilos con flexbox:
- Una
.navbarcon logo a la izquierda, enlaces centrados y un botón de carrito a la derecha (justify-content: space-between) - Un contenedor de tags de género musical con
flex-wrap: wrapygap - Una grid de cards de discos (3 por fila) usando
flex-wrap: wrapyflex-basis: calc(33.33% - 1rem) - Cada card con
flex-direction: columny el precio pegado abajo conflex: 1en el body - Un
.toolbarcon filtros a la izquierda y un botón "Ordenar por" a la derecha conmargin-inline-start: auto
No te preocupes por responsive todavía — eso viene en la lección 07.
lightbulb Pistas
Para las cards de 3 en fila, combina flex-wrap: wrap con gap: 1.5rem y dale a cada card flex: 0 0 calc(33.33% - 1rem). En la siguiente lección verás Grid, que es mejor para esto. Pero dominar flexbox primero es fundamental.