css-que-es-flexbox

Qué es Flexbox en CSS y cómo organizar layouts

  • 5 min

El módulo Flexbox (Flexible Box Layout) es un sistema de maquetación unidireccional de CSS para organizar, alinear y distribuir elementos.

La llegada de este estándar supuso un antes y un después en el desarrollo frontend, ya que dejó atrás muchos trucos raros y frustraciones matemáticas a la hora de estructurar el diseño de nuestras páginas.

Para que os hagáis una idea del trauma colectivo que teníamos los programadores web antes de que esto existiera, os pongo un ejemplo.

Durante años, la pregunta más buscada y votada en foros como StackOverflow era: “¿Cómo demonios centro un div horizontal y verticalmente en la pantalla?”.

Con las herramientas clásicas (como los floats o el posicionamiento absoluto) hacer una simple cuadrícula de tres columnas que midieran lo mismo era un pequeño infierno de mantenimiento.

Afortunadamente, unas personas muy inteligentes se pusieron a pensar (y a inspirarse en cosas que había en otros lenguajes 😎), crearon Flexbox, y todos respiramos aliviados.

Cuándo usar Flexbox

Flexbox es adecuado cuando tenemos que alinear elementos en una sola dirección. Menús, barras de botones, tarjetas en una fila, formularios con etiqueta y campo, cabeceras con logo a un lado y navegación al otro… ese es su terreno natural.

Si os descubrís intentando controlar filas y columnas a la vez con muchos contenedores flex anidados, quizá el problema ya no es de Flexbox. Probablemente estáis entrando en territorio de CSS Grid (el hermano de Flex que veremos en su propio artículo).

El concepto: El Contenedor y los Hijos

Flexbox no es una sola propiedad de CSS, sino un conjunto de reglas que interactúan entre sí. Para entenderlo, necesitamos dividir el mundo en dos bandos: el contenedor padre y los elementos hijos.

Para activar Flexbox, solo tenéis que ir al elemento padre y aplicarle la regla principal: display: flex;.

En ese preciso instante, la caja normal se transforma en un contenedor elástico, y todos los elementos que estén inmediatamente dentro de ella empiezan a moverse, estirarse o encogerse según las nuevas normas que dictemos.

.contenedor-padre {
    /* A partir de aquí mandan las reglas de Flexbox */
    display: flex; 
    background-color: lightgray;
}

.hijo {
    /* Estos elementos ahora son flexibles automáticamente */
    background-color: orange;
    padding: 20px;
    margin: 5px;
}
Copied!

Flexbox solo afecta a los hijos directos del contenedor. Si uno de esos “hijos” tiene dentro un párrafo, ese párrafo no sabrá nada de Flexbox (a menos que convirtáis al propio hijo en otro contenedor elástico).

Qué cambia al activar Flexbox

Cuando aplicamos display: flex, no solo estamos diciendo “ponme las cosas en fila”. Estamos cambiando el algoritmo que usa el navegador para colocar a los hijos directos.

.contenedor-padre {
    display: flex;
}
Copied!

A partir de ese momento, esos hijos pasan a llamarse flex items. El contenedor padre decide cómo se distribuyen, y los hijos pueden recibir propiedades especiales para crecer, encogerse o cambiar su orden.

El HTML no cambia. Lo que cambia es la forma en la que CSS interpreta la distribución de esas cajas.

Los dos ejes de Flexbox

Flexbox es un sistema unidireccional, lo que significa que solo sabe colocar las cosas en una única línea a la vez (ya sea una fila horizontal o una columna vertical).

Para ordenar este espacio, Flexbox define dos ejes imaginarios: el Eje Principal y el Eje Cruzado.

Es la dirección principal en la que se van a colocar los elementos hijos. Por defecto, cuando ponéis display: flex, el navegador establece que el eje principal va de izquierda a derecha (en horizontal).

Por lo tanto, si tenéis tres cajas <div> (que normalmente se apilarían una debajo de otra), al aplicarles Flexbox se pondrán automáticamente una al lado de la otra formando una fila perfecta.

Podemos cambiar la dirección de esta “vía del tren” usando la propiedad flex-direction.

.contenedor {
    display: flex;
    /* Cambiamos la vía para que los elementos caigan de arriba a abajo */
    flex-direction: column; 
}
Copied!

Si cambiáis flex-direction a column, recordad que también cambian los ejes. justify-content dejará de actuar en horizontal y pasará a actuar en vertical. Este detalle es el origen de muchísimas caras de “¿por qué no se centra esto?”.

El eje cruzado es siempre la línea perpendicular al eje principal.

  • Si vuestro eje principal es horizontal (una fila), el eje cruzado será vertical (de arriba a abajo).
  • Si habéis cambiado el eje principal a vertical (una columna), el eje cruzado pasará a ser horizontal (de izquierda a derecha).

El fin del sufrimiento

Volvamos al chiste recurrente de los programadores. ¿Cómo centramos ahora un triste cuadradito perfectamente en medio de la pantalla sin morir en el intento?

Gracias a los dos ejes, la respuesta es muy sencilla. Solo le decimos al contenedor elástico: “Oye, alinea a tu hijo en el centro de tu eje principal, y luego alinéalo en el centro de tu eje cruzado”.

body {
    display: flex; /* Convertimos toda la página en un contenedor elástico */
    height: 100vh; /* Hacemos que ocupe todo el alto de la pantalla */
    
    /* Centramos en los dos ejes */
    justify-content: center; /* Lo centra en el eje principal (horizontal por defecto) */
    align-items: center;     /* Lo centra en el eje cruzado (vertical por defecto) */
}
Copied!

Y ya está. Ni matemáticas, ni coordenadas, ni márgenes negativos. El navegador calcula automáticamente los espacios y mantiene la caja en el centro absoluto, incluso si redimensionamos la ventana.

Por supuesto, hemos soltado un par de propiedades importantes (justify-content y align-items) sin explicarlas a fondo.

No os preocupéis, en la próxima entrada vamos a ver en detalle las propiedades de alineación de Flexbox para que podáis construir interfaces con bastante más control.