Flex (también llamado flexbox) es un sistema de elementos flexibles que llega con la idea de olvidar mecanismos anticuados y acostumbrarnos a una mecánica más potente, limpia y personalizable, en la que los elementos HTML se adaptan y colocan automáticamente y es mucho más fácil personalizar los diseños de una página web.
Flex está especialmente diseñado para los siguientes escenarios:
- Crear estructuras simples de una sóla dimensión (no está limitado sólo a eso).
- Estructuras flexibles que no queremos que sean de un tamaño específico (adaptables).
- Crear diseños complejos enfocándote específicamente sólo en la estructura "actual".
Conceptos
Antes de utilizar flex lo primero que debemos hacer es conocer algunos de los conceptos básicos de este nuevo esquema, que son los siguientes:
Contenedor: Es el elemento padre que tendrá en su interior cada uno de los ítems flexibles. Observa que al contrario que muchas otras estructuras CSS, por norma general, en Flex establecemos las propiedades al elemento padre.
Eje principal: Los contenedores flexibles tendrán una orientación principal específica. Por defecto, el eje principal del contenedor flex es en horizontal (en fila).
Eje secundario: De la misma forma, los contenedores flexibles tendrán una orientación secundaria, perpendicular a la principal. Si la principal es en horizontal, la secundaria será en vertical (y viceversa).
Ítem: Cada uno de los hijos que tendrá el contenedor en su interior.
Modalidades de flex
Una vez tenemos claro esto, imaginemos el siguiente escenario:
<div class="container"> <!-- Flex container -->
<div class="item item-1">1</div> <!-- Flex items -->
<div class="item item-2">2</div>
<div class="item item-3">3</div>
</div>
Para activar el modo flex, utilizaremos sobre el elemento contenedor la propiedad display, y especificaremos el valor flex
o inline-flex
(dependiendo de como queramos que se comporte el contenedor):
Tipo de elemento | Descripción |
---|---|
inline-flex | Contenedor en línea, similar a inline-block (ocupa solo el contenido). |
flex | Contenedor en bloque, similar a block (ocupa todo el ancho del padre). |
Por defecto, y sólo con esto, observaremos que los elementos se disponen todos sobre una misma línea. Esto ocurre porque estamos utilizando el modo flex y estaremos trabajando con ítems flexibles básicos, garantizando que no se desbordarán ni mostrarán los problemas que, por ejemplo, tienen los porcentajes sobre elementos que no utilizan flex.
Dirección
Existen dos propiedades principales para manipular la dirección y comportamiento de los ítems a lo largo del eje principal del contenedor. Son las que veremos a continuación:
Propiedad | Valor | Significado |
---|---|---|
flex-direction | row | row-reverse | column | column-reverse | Cambia la orientación del eje principal. |
Mediante la propiedad flex-direction
podemos modificar la dirección del eje principal del contenedor para que se oriente en horizontal (valor por defecto) o en vertical. Además, también podemos incluir el sufijo -reverse
para indicar que coloque los ítems en orden inverso.
Valor | Descripción |
---|---|
row | Eje principal en dirección horizontal. |
row-reverse | Eje principal en dirección horizontal invertida. |
column | Eje principal en dirección vertical. |
column-reverse | Eje principal en dirección vertical invertida. |
Esto nos permite tener un control muy alto sobre el orden de los elementos en una página. Veamos la aplicación de estas propiedades sobre el ejemplo anterior, para modificar el flujo del eje principal del contenedor:
.container {
display: flex;
flex-direction: column;
background: darkgrey;
}
.item {
background: indigo;
}
A continuación podemos ver un ejemplo interactivo:
Desborde multilinea (wrap)
En general, flex se suele utilizar para estructuras de una sola dimensión, es decir, contenedores que sólo van en una dirección. Sin embargo, existe una propiedad denominada flex-wrap
con la que podemos especificar un comportamiento especial de nuestro contenedor padre.
Si un elemento no cabe dentro de nuestro contenedor flex, por defecto, los elementos se harán más pequeños (son flexibles) para ajustarse al contenedor. Este es el comportamiento por defecto de un contenedor flex. Sin embargo, con la propiedad flex-wrap
podemos cambiar este comportamiento y permitir que nuestro contenedor flex se desborde, convirtiéndose en un contenedor flex multilínea.
Propiedad | Valor | Significado |
---|---|---|
flex-wrap | nowrap | wrap | wrap-reverse | Evita o permite el desbordamiento (multilinea). |
Los valores que puede tomar esta propiedad, son las siguientes:
Valor | Descripción |
---|---|
nowrap | Los ítems se ajustan para ocupar el tamaño del contenedor (no permite desbordamiento en múltiples líneas). |
wrap | Establece los ítems en modo multilínea (permite que se desborde el contenedor). |
wrap-reverse | Establece los ítems en modo multilínea, pero en dirección inversa. |
Teniendo en cuenta estos valores de la propiedad flex-wrap
, podemos conseguir cosas como la siguiente:
.container {
display: flex;
flex-wrap: wrap;
background: darkgrey;
}
.item {
background: indigo;
}
Imagina ahora, que en nuestro contenedor flex tenemos muchos elementos, por ejemplo, 15 elementos hijos que no caben en el ancho del contenedor padre. Por defecto y siempre que pueda, flex hará más pequeños los elementos hijos para que quepan.
Sin embargo, si especificamos wrap
en la propiedad flex-wrap
, lo que permitimos es que el contenedor pueda tener múltiples lineas, mostrando los ítems que quepan en la primera linea, y el resto reubicándose en las siguientes líneas, sin ajustar su tamaño. El valor wrap-reverse
haría exactamente lo mismo, pero con el orden inverso.
La propiedad de atajo flex-flow
Recuerda que existe una propiedad de atajo (short-hand) llamada flex-flow
, con la que podemos resumir los valores de las propiedades flex-direction
y flex-wrap
, especificándolas en una sola propiedad y ahorrándonos utilizar las propiedades concretas:
.container {
/* flex-flow: <flex-direction> <flex-wrap>; */
flex-flow: row wrap;
}
Huecos (gaps)
Existen dos propiedades muy interesantes llamadas: row-gap
y column-gap
. Dichas propiedades, permiten establecer el tamaño de los «huecos» entre ítems de un contenedor flex. Esto evita la necesidad de estar utilizando padding
o margin
en los elementos hijos, que suele traer muchas complicaciones.
Propiedad | Valor | Descripción |
---|---|---|
row-gap | normal | | Espacio entre filas (sólo funciona con flex-direction: column ) |
column-gap | normal | | Espacio entre columnas (sólo funciona con flex-direction: row ) |
Como flex es un sistema que trabaja en una sola dimensión, sólo una de las dos propiedades tendrá efecto:
- Si
flex-direction: column
, podrás utilizarrow-gap
. - Si
flex-direction: row
, podrás utilizarcolumn-gap
.
Eso sí, es posible usar ambas si tenemos la propiedad flex-wrap
definida a wrap
y, por lo tanto, disponemos de multicolumnas flexbox, ya que en este caso si podemos separar elementos por filas y por columnas.
Ten en cuenta que los huecos sólo se aplican entre elementos, y no entre un elemento hijo y su contenedor padre.
La propiedad de atajo gap
En Flex CSS existe una propiedad de atajo para los huecos, denominada gap
. Con esta propiedad podemos indicar de una sola vez valores para row-gap
y column-gap
. Escribimos menos y es más cómodo:
Propiedad | Valor | Descripción |
---|---|---|
gap | 0 | | Aplica el tamaño del hueco en ambos ejes. |
gap | 0 0 | | Aplica los tamaños para el hueco del eje X y el eje Y. |
Como se puede ver, por defecto, el tamaño de los huecos es de 0, sin embargo, podemos utilizar tanto las propiedades individuales como la propiedad de atajo gap
para modificar estos tamaños.
A continuación, podemos ver un ejemplo de su utilización en este fragmento de código:
.container {
/* 2 parámetros: <row> <column> */
gap: 4px 8px;
/* Equivalente a */
row-gap: 4px;
column-gap: 8px;
/* 1 parámetro: usa el mismo para ambos */
gap: 4px;
/* Equivalente a */
row-gap: 4px;
column-gap: 4px;
}