📦 ¿Qué es Flexbox?
Flexbox es un módulo de diseño en CSS3 que proporciona una forma eficiente de distribuir espacio y alinear elementos dentro de un contenedor, incluso cuando sus tamaños son desconocidos o dinámicos. Antes de Flexbox, centrar elementos verticalmente o crear diseños complejos requería trucos complicados y código excesivo.
La magia de Flexbox radica en su capacidad para trabajar con una dimensión (fila o columna) mientras mantiene el control sobre la distribución del espacio restante. Esto lo convierte en la herramienta perfecta para:
- Crear barras de navegación responsivas
- Centrar elementos horizontal y verticalmente
- Crear tarjetas que se adapten al ancho disponible
- Diseñar layouts de formularios flexibles
- Implementar menús que se redistribuyen automáticamente
🏗️ Estructura Básica: Contenedor e Hijos
Para usar Flexbox necesitas entender dos componentes fundamentales:
- Contenedor padre (flex container): El elemento que tiene la propiedad
display: flex. Este elemento controla cómo se distribuyen sus hijos. - Elementos hijos (flex items): Los elementos directos dentro del contenedor. Estos heredan el comportamiento flexible y pueden tener sus propias propiedades.
Ejemplo básico:
.contenedor {
display: flex;
/* Ahora todos los .hijo son flex-items */
}
.hijo {
/* Cada hijo se comporta como flex-item */
padding: 20px;
background: #3498db;
color: white;
margin: 5px;
}📐 Propiedades del Contenedor (Padre)
El contenedor flexible tiene propiedades que controlan la dirección, wrap, flujo y alineación de todos sus hijos.
1. flex-direction - Dirección principal
Define hacia qué dirección fluyen los elementos:
.contenedor {
flex-direction: row; /* Horizontal (izquierda a derecha) */
flex-direction: row-reverse; /* Horizontal (derecha a izquierda) */
flex-direction: column; /* Vertical (arriba a abajo) */
flex-direction: column-reverse; /* Vertical (abajo a arriba) */
}2. justify-content - Alineación en el eje principal
Alinea los elementos a lo largo del eje principal (horizontal si direction es row):
.contenedor {
justify-content: flex-start; /* Izquierda */
justify-content: flex-end; /* Derecha */
justify-content: center; /* Centrado */
justify-content: space-between; /* Espacio igual entre elementos */
justify-content: space-around; /* Espacio igual alrededor */
justify-content: space-evenly; /* Espacio exactamente igual */
}3. align-items - Alineación en el eje cruzado
Alinea los elementos a lo largo del eje perpendicular (vertical si direction es row):
.contenedor {
align-items: stretch; /* Estirar (por defecto) */
align-items: flex-start; /* Arriba */
align-items: flex-end; /* Abajo */
align-items: center; /* Centrado vertical */
align-items: baseline; /* Alinear por línea base del texto */
}4. flex-wrap - Envolvimiento
.contenedor {
flex-wrap: nowrap; /* No envolver (por defecto, todo en una línea) */
flex-wrap: wrap; /* Envolver a siguiente línea si no cabe */
flex-wrap: wrap-reverse; /* Envolver invertiendo líneas */
}5. align-content - Distribuir líneas (solo con flex-wrap: wrap)
.contenedor {
align-content: flex-start;
align-content: flex-end;
align-content: center;
align-content: space-between;
align-content: space-around;
align-content: stretch;
}6. gap - Espacio entre elementos
.contenedor {
gap: 10px; /* Espacio igual en ambos ejes */
gap: 10px 20px; /* 10px entre filas, 20px entre columnas */
row-gap: 10px; /* Solo entre filas */
column-gap: 20px; /* Solo entre columnas */
}gap no agrega espacio en los bordes externos del contenedor. Es decir, el primer y último elemento no tendrán margen adicional en los extremos.🎯 Propiedades de los Elementos Hijos
Los elementos hijos pueden controlar su propio tamaño y comportamiento dentro del espacio disponible.
| Propiedad | Descripción | Valores |
|---|---|---|
flex-grow | Factor de crecimiento (cómo ocupan espacio extra) | Número (0 = no crece) |
flex-shrink | Factor de encogimiento (cómo se reducen) | Número (1 = se encoge normalmente) |
flex-basis | Tamaño inicial antes de crecer/contraerse | auto, px, %, rem |
flex | Atajo para grow, shrink y basis | Combinación |
align-self | Sobre escribir align-items para este elemento | auto, flex-start, flex-end, center, stretch |
order | Orden de visualización (independiente del HTML) | Número entero |
La propiedad flex shorthand:
.elemento {
flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
flex: auto; /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
flex: 2 1 200px; /* grow: 2, shrink: 1, basis: 200px */
}flex: 1 en elementos hijos hace que todos tengan el mismo tamaño y ocupen todo el espacio disponible. Es útil para crear columnas flexibles de igual ancho.🎨 Ejemplos Prácticos Paso a Paso
Ejemplo 1: Centrar elemento perfectamente
Uno de los casos más comunes donde Flexbox brilla es el centrado tanto horizontal como vertical:
.centrado-perfecto {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh; /* Ocupa toda la altura de la ventana */
}Ver más: Explicación detalladaEste código hace magia: justify-content: center centra horizontalmente y align-items: center centra verticalmente. Con min-height: 100vh el contenedor ocupa toda la altura de la ventana del navegador.
Ejemplo 2: Navegación responsiva
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #2c3e50;
}
.nav-links {
display: flex;
gap: 20px;
}
.nav-links a {
color: white;
text-decoration: none;
}
/* En móvil: apilar verticalmente */
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 1rem;
}
}Ejemplo 3: Tarjetas de igual altura
.tarjetas {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.tarjeta {
flex: 1 1 300px; /* Crece, se encoge, mínimo 300px */
padding: 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}flex: 1 1 300px es extremadamente útil. Significa: "crece si hay espacio, encógeme si es necesario, pero no seas menor a 300px". Esto crea automáticamente columnas que se redistribuyen.Ejemplo 4: Formulario alineado
.form-row {
display: flex;
gap: 15px;
margin-bottom: 15px;
align-items: center;
}
.form-row label {
flex: 0 0 120px; /* Ancho fijo de 120px */
text-align: right;
}
.form-row input {
flex: 1; /* Ocupa todo el espacio restante */
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}🔄 Casos de Uso Comunes
Aquí tienes una tabla rápida de problemas comunes y su solución con Flexbox:
| Problema | Solución Flexbox |
|---|---|
| Centrar contenido | justify-content: center; align-items: center; |
| Elementos en esquinas opuestas | justify-content: space-between; |
| Botón pegado a la derecha | Contenedor con display: flex, botón con margin-left: auto |
| Footer siempre abajo | Body display: flex; flex-direction: column, main con flex: 1 |
| Ícono alineado con texto | align-items: center en el contenedor |
| Último elemento a la derecha | margin-left: auto en el último hijo |
"Flexbox no es la respuesta a todo, pero es definitivamente la respuesta correcta para casi todo lo relacionado con componentes de interfaz de usuario." - comunidad de desarrolladores CSS
🎮 Práctica Guiada
Vamos a construir una barra de navegación profesional paso a paso:
- Crea un contenedor
<nav>con la clase.navbar - Aplica
display: flex; justify-content: space-between - Agrega un logo a la izquierda y enlaces a la derecha
- Usa
align-items: centerpara alinear verticalmente - Añade
gap: 30pxentre los enlaces - En móviles (
@media), cambia aflex-direction: column
<nav class="navbar">
<div class="logo">MiLogo</div>
<ul class="nav-links">
<li><a href="#">Inicio</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Contacto</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
margin: 0;
padding: 0;
}
.nav-links a {
color: white;
text-decoration: none;
font-weight: 500;
transition: opacity 0.3s;
}
.nav-links a:hover {
opacity: 0.8;
}
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 1rem;
}
.nav-links {
flex-direction: column;
align-items: center;
gap: 1rem;
}
}🔧 Debugging: Errores Comunes
Error 1: Los elementos no se centran verticalmenteProblema: El contenedor no tiene altura definida.
Solución: Asegúrate de que el contenedor tenga height o min-height definido. Sin altura, align-items: center no tiene efecto visible.
Problema: Falta flex-wrap: wrap.
Solución: Por defecto Flexbox intenta que todo esté en una línea. Agrega flex-wrap: wrap para permitir que los elementos pasen a la siguiente línea.
Problema: Contenido variable causa tamaños diferentes.
Solución: Agrega align-items: stretch al contenedor o flex: 1 a los elementos hijos con display: flex internamente.
📊 Resumen Rápido
| Concepto | Propiedad | Valores principales |
|---|---|---|
| Activar Flexbox | display | flex | inline-flex |
| Dirección | flex-direction | row | column | row-reverse | column-reverse |
| Eje principal | justify-content | flex-start | center | flex-end | space-between | space-around | space-evenly |
| Eje cruzado | align-items | stretch | flex-start | flex-end | center | baseline |
| Envolvimiento | flex-wrap | nowrap | wrap | wrap-reverse |
| Tamaño flexible | flex | 1 | auto | none | grow shrink basis |
justify-content trabaja en el eje principal, align-items trabaja en el eje cruzado. Una vez que comprendas esto, Flexbox se vuelve intuitivo.¿Qué combinación de propiedades usarías para centrar PERFECTAMENTE un elemento tanto horizontal como verticalmente en su contenedor?
- A) justify-content: center; vertical-align: middle;
- B) justify-content: center; align-items: center;
- C) text-align: center; align-content: center;
- D) display: flex; margin: auto;
justify-content: center; align-items: center;. justify-content centra en el eje principal (horizontal por defecto) y align-items centra en el eje cruzado (vertical por defecto). Esta es una de las técnicas más elegantes que Flexbox ofrece.Flexbox ha revolucionado la forma en que construimos interfaces web. Con estas herramientas, podrás crear diseños que antes requerían hacks complicados o JavaScript. En la próxima lección exploraremos cómo combinar Flexbox con CSS Grid para crear layouts aún más potentes y sofisticados.