Flexbox en CSS
Aprende a utilizar Flexbox para crear diseños web flexibles, responsivos y alineados con facilidad.
Cristian Escalante
Última actualización: 9 de abril de 2025
Flexbox en CSS
Flexbox (Flexible Box Layout) es un modelo de diseño unidimensional que permite crear diseños flexibles y eficientes. Proporciona una manera más eficiente de distribuir el espacio y alinear elementos, incluso cuando su tamaño es desconocido o dinámico.
Conceptos básicos de Flexbox
Flexbox se basa en dos tipos de elementos:
- Contenedor Flex (Flex Container): El elemento padre que tiene
display: flex
odisplay: inline-flex
. - Elementos Flex (Flex Items): Los hijos directos del contenedor flex.
<div class="contenedor-flex">
<div class="elemento">1</div>
<div class="elemento">2</div>
<div class="elemento">3</div>
</div>
.contenedor-flex {
display: flex;
}
Ejes de Flexbox
Flexbox trabaja con dos ejes:
- Eje principal (Main Axis): Por defecto, va de izquierda a derecha.
- Eje transversal (Cross Axis): Por defecto, va de arriba hacia abajo.
La dirección de estos ejes puede cambiar según la propiedad flex-direction
.
Propiedades del Contenedor Flex
display
Define un contenedor flex:
.contenedor {
display: flex; /* o inline-flex */
}
flex-direction
Define la dirección del eje principal:
.contenedor {
flex-direction: row; /* Predeterminado: izquierda a derecha */
/* Otras opciones: */
/* flex-direction: row-reverse; */ /* derecha a izquierda */
/* flex-direction: column; */ /* arriba hacia abajo */
/* flex-direction: column-reverse; */ /* abajo hacia arriba */
}
flex-wrap
Controla si los elementos flex deben ajustarse en una sola línea o pueden fluir en varias líneas:
.contenedor {
flex-wrap: nowrap; /* Predeterminado: una sola línea */
/* Otras opciones: */
/* flex-wrap: wrap; */ /* Múltiples líneas, de arriba hacia abajo */
/* flex-wrap: wrap-reverse; */ /* Múltiples líneas, de abajo hacia arriba */
}
flex-flow
Abreviatura para flex-direction
y flex-wrap
:
.contenedor {
flex-flow: row wrap; /* dirección: row, wrap: wrap */
}
justify-content
Alinea los elementos flex a lo largo del eje principal:
.contenedor {
justify-content: flex-start; /* Predeterminado: al inicio del eje principal */
/* Otras opciones: */
/* justify-content: flex-end; */ /* Al final del eje principal */
/* justify-content: center; */ /* Centrado en el eje principal */
/* justify-content: space-between; */ /* Espacio entre elementos */
/* justify-content: space-around; */ /* Espacio alrededor de elementos */
/* justify-content: space-evenly; */ /* Espacio igual entre y alrededor */
}
align-items
Alinea los elementos flex a lo largo del eje transversal:
.contenedor {
align-items: stretch; /* Predeterminado: estira los elementos */
/* Otras opciones: */
/* align-items: flex-start; */ /* Al inicio del eje transversal */
/* align-items: flex-end; */ /* Al final del eje transversal */
/* align-items: center; */ /* Centrado en el eje transversal */
/* align-items: baseline; */ /* Alineado por la línea base del texto */
}
align-content
Alinea las líneas de elementos flex cuando hay espacio adicional en el eje transversal (solo funciona cuando hay múltiples líneas):
.contenedor {
flex-wrap: wrap; /* Necesario para que align-content funcione */
align-content: stretch; /* Predeterminado: estira las líneas */
/* Otras opciones: */
/* align-content: flex-start; */ /* Líneas al inicio */
/* align-content: flex-end; */ /* Líneas al final */
/* align-content: center; */ /* Líneas centradas */
/* align-content: space-between; */ /* Espacio entre líneas */
/* align-content: space-around; */ /* Espacio alrededor de líneas */
}
Propiedades de los Elementos Flex
order
Controla el orden de los elementos flex:
.elemento1 {
order: 2; /* Predeterminado: 0 */
}
.elemento2 {
order: 1; /* Aparecerá antes que elemento1 */
}
.elemento3 {
order: 3; /* Aparecerá después de elemento1 */
}
flex-grow
Define la capacidad de un elemento flex para crecer si es necesario:
.elemento {
flex-grow: 0; /* Predeterminado: no crece */
}
.elemento-creciente {
flex-grow: 1; /* Puede crecer */
}
.elemento-muy-creciente {
flex-grow: 2; /* Crece el doble que elemento-creciente */
}
flex-shrink
Define la capacidad de un elemento flex para encogerse si es necesario:
.elemento {
flex-shrink: 1; /* Predeterminado: puede encogerse */
}
.elemento-no-encogible {
flex-shrink: 0; /* No se encoge */
}
.elemento-muy-encogible {
flex-shrink: 2; /* Se encoge el doble que los elementos normales */
}
flex-basis
Define el tamaño predeterminado de un elemento antes de que se distribuya el espacio restante:
.elemento {
flex-basis: auto; /* Predeterminado: basado en el contenido */
/* Otras opciones: */
/* flex-basis: 0; */ /* Tamaño inicial de 0 */
/* flex-basis: 25%; */ /* Tamaño inicial del 25% */
/* flex-basis: 200px; */ /* Tamaño inicial de 200px */
}
flex
Abreviatura para flex-grow
, flex-shrink
y flex-basis
:
.elemento {
flex: 0 1 auto; /* flex-grow: 0, flex-shrink: 1, flex-basis: auto */
}
.elemento-flexible {
flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
}
Valores comunes:
flex: 1
: Elemento flexible que puede crecer y encogerseflex: auto
: Equivalente aflex: 1 1 auto
flex: none
: Equivalente aflex: 0 0 auto
(no flexible)flex: initial
: Equivalente aflex: 0 1 auto
(valor inicial)
align-self
Permite sobrescribir la alineación especificada por align-items
para elementos individuales:
.elemento-especial {
align-self: flex-end; /* Sobrescribe align-items para este elemento */
/* Otras opciones: las mismas que align-items */
}
Ejemplos prácticos de Flexbox
Centrado perfecto (horizontal y vertical)
<div class="contenedor-centrado">
<div class="elemento-centrado">Centrado perfecto</div>
</div>
.contenedor-centrado {
display: flex;
justify-content: center; /* Centrado horizontal */
align-items: center; /* Centrado vertical */
height: 300px; /* Altura del contenedor */
border: 1px solid #ccc;
}
Navegación responsive
<nav class="navegacion">
<div class="logo">Logo</div>
<ul class="menu">
<li><a href="#">Inicio</a></li>
<li><a href="#">Productos</a></li>
<li><a href="#">Servicios</a></li>
<li><a href="#">Contacto</a></li>
</ul>
</nav>
.navegacion {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background-color: #f8f9fa;
}
.menu {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
margin-left: 1rem;
}
/* Responsive */
@media (max-width: 768px) {
.navegacion {
flex-direction: column;
}
.menu {
margin-top: 1rem;
width: 100%;
justify-content: space-between;
}
.menu li {
margin-left: 0;
}
}
Tarjetas de igual altura
<div class="contenedor-tarjetas">
<div class="tarjeta">
<h3>Tarjeta 1</h3>
<p>Contenido corto.</p>
<button>Acción</button>
</div>
<div class="tarjeta">
<h3>Tarjeta 2</h3>
<p>Contenido más largo que ocupa más espacio en esta tarjeta.</p>
<button>Acción</button>
</div>
<div class="tarjeta">
<h3>Tarjeta 3</h3>
<p>Contenido de longitud media.</p>
<button>Acción</button>
</div>
</div>
.contenedor-tarjetas {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.tarjeta {
flex: 1 1 300px; /* Crece, encoge, base de 300px */
display: flex;
flex-direction: column;
padding: 20px;
border: 1px solid #ddd;
border-radius: 4px;
}
.tarjeta h3 {
margin-top: 0;
}
/* El botón siempre al final */
.tarjeta button {
margin-top: auto;
align-self: flex-start;
}
Diseño Holy Grail con Flexbox
El diseño "Holy Grail" (Santo Grial) es un patrón común con cabecera, pie de página, contenido principal y barras laterales:
<div class="holy-grail">
<header>Cabecera</header>
<div class="contenido">
<nav>Navegación</nav>
<main>Contenido Principal</main>
<aside>Barra lateral</aside>
</div>
<footer>Pie de página</footer>
</div>
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
header, footer {
background-color: #f8f9fa;
padding: 1rem;
}
.contenido {
display: flex;
flex: 1;
}
nav, aside {
background-color: #e9ecef;
padding: 1rem;
}
nav {
flex: 0 0 200px; /* No crece, no encoge, ancho de 200px */
order: -1; /* Aparece primero */
}
main {
flex: 1; /* Toma todo el espacio disponible */
padding: 1rem;
}
aside {
flex: 0 0 200px; /* No crece, no encoge, ancho de 200px */
}
/* Responsive */
@media (max-width: 768px) {
.contenido {
flex-direction: column;
}
nav, aside, main {
flex-basis: auto;
}
}
Ventajas de Flexbox
- Alineación simplificada: Facilita el centrado vertical y horizontal.
- Orden flexible: Permite cambiar el orden visual sin modificar el HTML.
- Distribución de espacio: Gestiona eficientemente el espacio disponible.
- Diseño responsive: Facilita la creación de diseños que se adaptan a diferentes tamaños de pantalla.
- Tamaños dinámicos: Maneja elementos con tamaños desconocidos o variables.
Limitaciones de Flexbox
- Diseño unidimensional: Está diseñado para trabajar en una sola dimensión (filas O columnas).
- Diseños complejos: Para diseños de cuadrícula bidimensionales, CSS Grid puede ser más apropiado.
- Soporte en navegadores antiguos: Aunque la mayoría de los navegadores modernos lo soportan, puede haber problemas con versiones muy antiguas.
Flexbox vs. Grid
- Flexbox es ideal para:
- Diseños unidimensionales (filas o columnas)
- Componentes de interfaz pequeños
- Alineación de elementos
- Grid es ideal para:
- Diseños bidimensionales (filas y columnas simultáneamente)
- Diseños de página completos
- Posicionamiento preciso de elementos
En muchos casos, lo mejor es usar ambos: Grid para el diseño general de la página y Flexbox para componentes individuales.