Flexbox

Flexbox es un componente de CSS que busca proporcionar una manera más eficiente de colocar, alinear y distribuir el espacio entre los elementos de un contenedor, incluso cuando el tamaño no se conozca con seguridad, o bien sea dinámico (de ahí­ el nombre "flex").

El objetivo es que un contenedor pueda alterar la anchura y altura de sus elementos para ajustarse del mejor modo posible. De este modo se cubre el espectro de tamaños de pantalla.

Contenedores y elementos

En flexbox tenemos contenedores flex y elementos flex:

  • Un contenedor flex es aquel que tiene definida la propiedad display a flex o a inline-flex.
  • Un elemento flex está dentro de un contenedor flex. Dicho elemento puede ser a su vez un contenedor flex o no

Hacer que un contenedor sea flex

Para dotar de flex a un contenedor, usamos la propiedad display, con valor flex (para comportarse como un elemento de bloque) o inline-flex (para comportarse como un elemento en lí­nea).

.contenedor-flex { display: flex; }

Todo fuera de un contenedor flex (y dentro de un elemento flex) se renderiza del modo tradicional.

Dirección flex

La propiedad flex-direction establece el eje principal en el que se apilan los contenedores flex.

Dirección de apilado de los contenedores flex según el valor de la propiedad flex-direction. En la imagen se muestra la dirección al aplicar los valores column-reverse (de abajo hacia arriba), column (de arriba hacia abajo), row (de derecha a izquierda) y row-reverse (de izquierda a derecha).

Cómo se ajustan los elementos flex

Por defecto, los items flex tratan de colocarse en una única lí­nea. Los que no llegan a caber, se desplazan hasta la lí­nea siguiente. Con la propiedad flex-wrap podemos cambiar este comportamiento por defecto

Cuando la propiedad flex-wrap tiene el valor nowrap (que es el comportamiento por defecto) el contenedor flex intenta ajustar todos los elementos en una sola lí­nea, y reajusta los tamaños de los elementos si es necesario.
Con flex-wrap a wrap, se desplazan a la lí­nea siguiente los elementos que no caben en una sola linea.
Con flex-wrap a wrap-reverse, se desplazan a la lí­nea siguiente los elementos que no caben en una sola linea. La diferencia está en que el borde del contenedor al que se adhieren es el opuesto a flex-wrap.

La propiedad flex-flow es un atajo de las propiedades flex-direction y flex-wrap. Por defecto, tiene el valor row nowrap

Prueba a jugar con los valores de las propiedades flex en el siguiente ejemplo.

<!DOCTYPE html> <html> <head> <title>Flexbox</title> <style> .flex-container{ display:flex; flex-direction:row; flex-wrap: wrap-reverse; width: 400px; height: 250px; background-color: beige; } .flex-item{ width:100px; height:100px; margin:10px; background-color: darkgrey; } </style> </head> <meta charset="utf-8"/> <body> <div class="flex-container"> <div class="flex-item">Item 1</div> <div class="flex-item">Item 2</div> <div class="flex-item">Item 3</div> <div class="flex-item">Item 3</div> </div> <div class="flex-item"></div> </body> </html>

Alineación de los elementos

La forma en que los elementos se alinean en la dirección del eje principal se modifica con la propiedad justify-content.

Los elementos se alinean según el valor asignado a justify-content

El valor por defecto de justify-content es flex-start. Los valores que más pueden llevar a confusión son space-between y space-around:

  • space-between: los elementos se distribuyen uniformemente en la lí­nea, estando el primer y último elemento alineados al principio y al final.
  • space-around: los elementos se distribuyen uniformemente con la misma cantidad de espacio a su alrededor.

La alineación perpendicular a la dirección del eje principal viene determinada por la propiedad align-items. La siguiente imagen muestra el comportamiento de esta propiedad.

Alineación según el valor de align-items

Para distribuir las lí­neas de elementos dentro del contenedor, utilizamos la propiedad align-content. Su comportamiento es similar a justify-content, pero utilizando el eje perpendicular al principal.

Alineación de las lí­neas según el valor de align-content. Esta propiedad no tiene efecto cuando hay solamente una lí­nea de elementos.

Orden de los elementos flex

Los elementos son colocados según el orden en que van apareciendo. Sin embargo, tenemos la propiedad order, que permite alterarlo. Por ejemplo, observa el siguiente código:

<!DOCTYPE html> <html> <head> <title>Flexbox</title> <style> .flex-container{ display:flex; flex-direction:row; flex-wrap: wrap-reverse; justify-content: space-around; align-items: center; width: 400px; height: 50px; background-color: beige; } .flex-item{ height:40px; margin:10px; background-color: darkgrey; } #item1{ width:60px; order:20; } #item2{ width:100px; order:1; } #item3{ width:40px; order:10; } </style> </head> <meta charset="utf-8"/> <body> <div class="flex-container"> <div id="item1" class="flex-item">Item 1</div> <div id="item2" class="flex-item">Item 2</div> <div id="item3" class="flex-item">Item 3</div> </div> </body> </html>

Regular el tamaño de los elementos en proporción a los demás

Podemos permitir que un elemento crezca en proporción a los demás, utilizando la propiedad flex-grow. Así­, un elemento con la regla flex-grow:2 tendrá un tamaño del doble que otro con flex-grow:1

Si utilizamos la propiedad flex-grow, podemos definir el tamaño de los elementos de una manera flexible, manteniendo unas ciertas proporciones.

Alinear un elemento al margen de los demás

Si un elemento debe alinearse de manera independiente a como lo hace el resto de elementos mediante la propiedad align-items, podemos utilizar la propiedad align-self. Los valores que puede tomar esta propiedad son similares a los que toma align-items, es decir flex-start, flex-end, center, baseline y stretch.

Flex-grow, flex-shrink y flex-basis todo en uno

flex-shrink indica lo contrario que flex-grow, es decir, a qué ritmo encoge un elemento respecto a los demás.

flex-basis indica el tamaño idóneo de un elemento. Cuando eso no sea posible, se aplicarán flex-grow si el espacio disponible crece, o flex-shrink en cado de que decrezca.

Existe un atajo para indicar estas tres propiedades simultáneamente: flex. Se indica en el elemento flex. Su sintaxis es la siguiente:

flex: flex-grow flex-shrink flex-basis|auto|initial|inherit;

En las propiedades anteriores:

  • auto es equivalente a 1 1 auto
  • initial es equivalente a 0 1 auto
  • none es equivalente a 0 0 auto

Por ejemplo, observa el siguiente ejemplo, y redimensiona el ancho de la ventana, comprobando como cambia el tamaño relativo de las cajas:

<!DOCTYPE html> <html> <head> <title>Usando flex</title> <style> .contenedor{ width:80%; height:300px; display:flex; margin:auto; border:1px solid black; } .caja{ align-items:stretch; } .d1{ background-color:red; flex: 10 10 200px; } .d2{ background-color:blue; flex: 5 5 200px; } .d3{ background-color:yellow; flex: 1 1 200px; } </style> </head> <body> <div class="contenedor"> <div class="caja d1">1.</div> <div class="caja d2">2.</div> <div class="caja d3">3.</div> </div> </body> </html>