Como ya todos sabreís, hay un antes y un despues, en la maquetación web, desde la aparición con CSS3, de las propiedades display: flex;
y display: grid;
. Propiedades que nos permiten, construir el layout ó estructura completa de páginas web, en una dimensión con flex, ó contruyendo un entramado de rejillas, con grid, con el que además podemos llegar a prescindir de media queries, para hacerlo responsive ó adaptable a cualquier tamaño de pantalla.
Este progreso y evolución del CSS, se hacía necesaria, para poder maquetar web adaptativas ó responsive, para los multiples dispositivos desde los que hoy en dia podemos navegar por la web.
Se quedaban cortos, los valores existentes de display
, el posicionamiento, los float ó el más antiguo usó de tablas, para maquetar páginas web, y conseguir fácilmente la alineación vertical que antes costaba un mundo.
Gracias al modulo de cajas flexibles de CSS ó flexbox
, podemos olvidarnos de las obsoletas formas de maquetar, y emplear flex, para convertir cualquier contenedor html, que englobe, a otros elementos html cualquiera, en un contenedor flexible, con items ó elementos flexibles, los elementos flex tienen la capacidad de redimensionarse y recolocarse dentro de la caja flex con facilidad. También tienen la capacidad de alinearse tanto horizontalmente como verticalmente.
Para entender y utilizar flex, lo primero es definir una serie de elementos y conceptos básicos que componen este sistema de maquetación.
Contenedor-flex:
es el contenedor padre, que albergará a los elementos ó items hijos, como ya mencione, puede tratarse de cualquier etiqueta html que contenga a otras. Sobre este contenedor podremos aplicar una serie de propiedades, para determinar su comportamiento y el de sus items. Las veremos con detalle, a continuación.
item:
cada uno de los elementos hijos del contenedor-flex, a los que igualmente podremos asignarles una seríe de propiedades, para manejar su comportamiento ó colocación.
Eje principal:
por defecto un contenedor flex, tendrá como eje principal, el horizontal, osea en fila, pero podremos cambiarlo.
Eje secundario:
logicamente el eje secundario de un contenedor flex será el perpendicular, al eje principal, osea el vertical, que podremos intercambiarlos.
Una vez definidos los ingredientes básicos, del sistema flexbox, vamos a ir viendo cada una de las propiedades aplicables al contenedor flex y a sus item, desarrollando un ejemplo gráfico, que es como creó, que mejor se entienden las cosas.
Para el ejemplo empleó el siguiente código html:
La representación visual, de este código, es la que podeís observar abajo, el valor de display por defecto de los <div>
es block
. Lo convertimos en un contenedor-flex, variando esta propiedad, en el CSS
. Ves pinchando en las etiquetas del ejemplo, para empezar a ver las modalidades de flex y una breve explicación.
item1
item2
item3
item4
item5
display: flex;
con esta declaración, tendremos un contenedor flex, con item básicos flexibles, que tiene un comportamiento de bloque, ocupa todo el ancho del padre. El resto de propiedades que pueden asignarseles al contenedor y a los items, son las que tienen por defecto, iremos viendolas con detalle.
display: inline-flex;
dandole este valor, nuestro contenedor flex, tiene un comportamiento inline-block, por eso se situa al lado de las etiquetas y ocupará solo su contenido. Igual que antes el resto de propiedades aplicables al contenedor y los items tienen sus valores por defecto, lo único que añado es un poco de hueco, entre los items (sino estarían completamente juntos), con la propiedad gap
que después explico.
Como ya he mencionado, en flexbox, tenemos un eje principal (por defecto es el horizontal) y un eje secundario (vertical), pues con la siguiente propiedad podemos intercambiarlos. En nuestro ejemplo interactivo, ya viene picado, el valor que tienen las propiedades por defecto, puedes ir clicando las etiquetas para observar el resto de valores que podremos darle a la propiedad y sus comportamientos.
item1
item2
item3
item4
item5
flex-direction: row;
valor por defecto de esta propiedad, significa que el contenedor flex tiene de eje principal el horizontal, osea en fila.
flex-direction: row-reverse;
el contenedor sigue teniendo como eje principal el horizontal pero invertido.
flex-direction: column;
con este valor establecemos la dirección del eje principal en vertical.
flex-direction: column-reverse;
Por último también podemos establecer la dirección de nuestro contenedor-flex, en vertical invertido.
Contenedor flex multilinea:
Una vez vistas las diferentes direcciones que podemos asignarle al contenedor flex, hemos de tener claro que, construimos estructuras de una sola dimensión en horizontal ó vertical. Por defecto, los items ó elementos flex, son flexibles y si no caben dentro de su contenedor, se harán más pequeños para ajustarse, pero podemos variar este comportamiento, con la propiedad flex-wrap;
y permitir el desbordamiento de los items, convirtiendo al contenedor, en un contenedor flex multilínea ó multicolumna.
item1
item2
item3
item4
item5
flex-wrap: nowrap;
este es el valor de esta propiedad por defecto, significa que los items se ajustarán al contenedor ó que aunque por sus dimensiones no quepan, desbordaran el contenedor, pero sin poder pasarse a otra línea ó columna.
flex-wrap: wrap;
con este valor, convertimos nuestro contenedor flex, en un contenedor multilínea, que tendrá todos los items que quepán, en la primera línea e ira creando tantas líneas como necesite, hasta acomodar todos los items que tenga.
flex-wrap: wrap-reverse;
este valor tiene el mismo comportamiento del anterior, pero los items estan en orden invertido.
Esta es una propiedad de abreviación (short-hand) de las dos anteriores, ya sabes para escribir menos código y tiene la siguiente síntaxis:
flex-flow:
[flex-direction]
[flex-wrap];
con todos sus posibles valores, abajo podeis observar las opciones:
item1
item2
item3
item4
item5
flex-flow: row nowrap;
como ya habíamos visto estos dos son los valores por defecto de estas propiedades, es decir las que adopta un contenedor flex aunque no declarasemos las propiedades. Y ya sabreís que significa que el contenedor aunque no pueda acoger todos los items, no permite desbordamiento a otras líneas ó columnas.
flex-flow: row wrap;
nuestro contenedor flex, tiene el eje horizontal (row) por defecto, pero puede desbordarse y lo convertimos en multilínea con wrap.
flex-flow: row-reverse wrap;
la misma opción que la anterior, el contenedor tiene de eje principal el horizontal, puede convertirse en multilínea por el wrap, pero tiene el sentido invertido.
flex-flow: column wrap;
con esta propiedad, le damos a nuestro contenedor flex, el eje principal en vertical (column), y dandole una altura (height), que no permita contener todos los items y la posibilidad de desbordamiento (wrap), podremos construir con flex, un layout de columnas.
flex-flow: column-reverse wrap;
con esta propiedad, le damos a nuestro contenedor flex, el eje principal en vertical (column), y dandole una altura (height), que no permita contener todos los items, y la posibilidad de desbordamiento (wrap), podremos construir con flex, un layout de columnas en este caso en sentido inverso.
gap:
con esta propiedad, podremos prescindir en muchas ocasiones de asignarles margin
ó padding
, a los items de un contenedor flex. Cabe mencionar que gap, es la propiedad abreviada, de row-gap:;
y de column-gap:;
. Los gap ó huecos solo tienen efecto entre los items, no entre los items y el contenedor padre.
CONTENEDOR-FLEX
La propiedad align-items
de Flexbox
, es una propiedad del contenedor flex y controla el alineamiento de todos los elementos ó items que contenga dicho contenedor-flex, a lo largo de su eje transversal ó vertical. Esta propiedad como después veremos puede sobreescribirse con la propiedad align-self:;
aplicable a cada item individualmente.
item1
item2
item3
item4
item5
align-items: flex-start;
los elementos se alinean agrupados al principio (start) del eje transversal (vertical).
align-items: flex-end;
los elementos se alinean agrupados al final (end) del eje transversal.
align-items: center;
los elementos se alinean agrupados en el centro (center) de la caja de su eje transversal ó vertical.
align-items: baseline;
los elementos aparecen alineados relativamente a su línea de base (baseline).
align-items: stretch;
(valor por defecto), al aplicar a un contenedor display: flex;
todos sus elementos secundarios se convierten en elementos flexibles (items) organizados en una fila y se estirarán para ser tan altos como el elemento más alto porque el valor por defecto de align-items: stretch, y ese elemento define la altura de los elementos en el eje transversal (vertical). Si tu contenedor flexible tiene una altura establecida, entonces los elementos se extenderán a esa altura, independientemente de la cantidad de contenido en el elemento
La propiedad justify-content
, aplicable al contenedor-flex, controla la alineación de todos los elementos (items) en el eje principal u horizontal.
item1
item2
item3
item4
item5
justify-content: flex-start;
(valor por defecto), los elementos se alinean agrupados al principio (start) del eje principal.
justify-content: flex-end;
los elementos se alinean agrupados al final (end) del eje principal.
justify-content: center;
los elementos se alinean agrupados en el centro (center) del eje principal.
justify-content: space-between;
los elementos aparecen distribuidos uniformemente: al principio, en el centro y al final del contenedor flex.
justify-content: space-around;
los elementos aparecen distribuidos uniformemente, y con un espacio igual entre ellos.
justify-content: space-evenly;
distribuye los elementos de manera uniforme a lo largo del eje principal de su contenedor, los elementos repartirán el espacio sobrante de su contenedor de igual manera a todos sus costados, habrá el mismo espacio al inicio y al final que en el medio de los elementos. En otras palabras, el espacio entre cada par de elementos adyacentes será el mismo, y también será el mismo que el espacio al principio y al final del contenedor
En contenedores-flex multilínea porque tengán establecida la propiedad flex-wrap: wrap;
con align-content
sirve como dice la especificación para “empaquetar líneas flexibles”; controla el espacio entre las líneas de flexión en el eje transversal (vertical).
item1
item2
item3
item4
item5
item6
item7
item8
item9
item10
item11
item12
item13
item14
item15
item16
item17
item18
item19
item20
align-content: flex-start;
alinea las filas o columnas de elementos al inicio del eje transversal (vertical).
align-content: flex-end;
alinea las filas o columnas de elementos al final del eje transversal.
align-content: center;
alinea las filas o columnas de elementos al centro del eje transversal.
align-content: space-between;
distribuye el espacio disponible entre las líneas flexibles, que se colocan al ras con el inicio y el final del contenedor en el eje transversal.
align-content: space-around;
distribuye el espacio disponible alrededor de las líneas flexibles.
align-content: stretch;
estira las líneas flexibles para ocupar el espacio restante del contenedor
Como ya mencione, con la propiedad align-self
aplicable a los items individualmente, controlamos la alineación de un elemento flexible individual en el eje transversal, sobreescribiendo el align-items
del contenedor para ese ó esos elementos.
item1
item2
item3
item4
item5
align-self: auto;
hereda el valor de align-items del padre (si no se ha definido, es stretch).
align-self: flex-start;
alinea el ó los ítems a los que se le aplique al inicio del contenedor.
align-self: flex-end;
alinea el ó los ítems a los que se le aplique al final del contenedor.
align-self: center;
alinea el ó los ítems a los que se le aplique al centro del contenedor.
align-self: baseline;
alinea los ítems a los que se le aplique en el contenedor según la base de los ítems.
align-self: stretch;
alinea el ó los ítems a los que se le aplique, estirándolos al tamaño del contenedor.
Hasta ahora hemos visto todas las propiedades aplicables al contenedor ó a los items flex para colocarlos o alinearlos tanto en su eje principal (horizontal), y el transversal (vertical), ahora veremos las propiedades aplicables a los items, con las que se comprueba verdaderamente su flexibilidad.
La propiedad CSS flex-basis
especifica la base flexible, que es el tamaño inicial de un elemento flexible. Esta propiedad determina el tamaño de una caja de contenidos a no ser que se haya especificado de otra forma usando box-sizing. El valor por defecto de esta propiedad es auto. Los valores negativos no son válidos. También puedes especificar el tamaño usando unidades absolutas (px, mm o pt), relativas (em, rem, etc) o porcentajes (%) del tamaño principal de su contenedor-flex padre, y la palabra clave content.
flex-basis
es el tamaño principal inicial de un item-flex, es la anchura en contenedores horizontales flex-direction: row;
o la altura en contenedores verticales flex-direction: column;
antes de que esten redimensionados con flex-grow
o con flex-shrink
.
La propiedad flex-grow
de CSS especifica el factor de crecimiento de un elemento flexible, en su dirección principal (horizontal o vertical). El factor de crecimiento especifica qué cantidad del espacio restante dentro del contenedor flexible, debería ocupar el item en cuestión. Por defecto, todos los elementos tienen un valor de 0, lo cual determina que no tienen la habilidad de crecer. Si insertamos cualquier otro valor positivo (valen numeros enteros ó decimales) en esta propiedad, el elemento crecerá
Gracias a esta propiedad de los items-flex
, podemos lograr efectos como el que puedes observar en el contenedor de abajo pasandoles el mouse y que se consigue con este sencillo código css.
1
2
3
4
5
La propiedad CSS flex-shrink
especifica el factor de contracción de un item-flex. Los items-flex se encogerán para llenar el contenedor de acuerdo a su número flex-shrink, cuando el tamaño por defecto de los items-flex sea mayor al de su contenedor-flex. Por ejemplo, si tienes un contenedor con cinco elementos y le das la propiedad flex-shrink: 1; a tres de ellos y flex-shrink: 2; a los otros dos, los elementos se encogerán para llenar el contenedor en proporción a su valor flex-shrink. El valor por defecto de esta propiedad es 1. No se aceptan valores negativos.
1
2
3
4
5
La propiedad flex
es una propiedad de atajo de los ítems-flex. Para escribir menos código, CSS nos permite abreviar las tres propiedades: flex-grow, flex-shrink (opcional) y flex-basis (opcional) en una sola: flex. El valor por defecto es flex: 0 1 auto; .
.item {flex: flex-grow [flex-shrink] [flex-basis];}
1
2
Por defecto los elementos flex, como todos los elementos HTML aparecen en el mismo orden que tengan en el código. En las cajas-flex podemos alterar este orden utilizando la propiedad order
, la propiedad order de los ítems-flex es un número entero, positivo o negativo. El valor por defecto de order es 0. Todos los elementos flex con el mismo valor, aparecen en el mismo orden que en el código y podemos aumentar o disminuir su valor según nos interese variar su posición. Con esta propiedad y usando media-querys, podremos construir layout adaptables a cualquier tamaño de pantalla.
1
2
3
4
5
Propiedad
Sintaxis
Descripción
display
display: flex | inline-flex;
.contenedor-flex {display: flex;}
Si su valor es flex o inline-flex, la propiedad display define un contenedor-flex (flexbox).
flex-direction
flex-direction: row | row-reverse | column | column-reverse;
.contenedor-flex {flex-direction: row;}
Establece la dirección del eje principal y por tanto la dirección de los elementos flex. El valor por defecto es row (fila).
flex-wrap
flex-wrap: nowrap | wrap | wrap-reverse;
.contenedor-flex {flex-wrap: wrap;}
Especifica si puede haber un cambio de línea (wrap) o no (nowrap). El valor por defecto es nowrap.
flex-flow
flex-flow: flex-direction [flex-wrap];
.contenedor-flex {flex-flow: column nowrap;}
Es la forma abreviada para las propiedades flex-direction y flex-wrap. El valor por defecto es row nowrap
align-items
align-items: flex-start | flex-end | center | baseline | stretch;
.contenedor-flex {align-items: center;}
Define como se colocan los elementos dentro de una contenedor flexbox relativamente al eje transversal. El valor por defecto es stretch.
justify-content
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
.contenedor-flex {justify-content: end;}
Define como se colocan los elementos dentro de un contenedor flexbox relativamente al eje principal (horizontal), cuando los elementos no ocupan toda la caja. El valor por defecto es flex-start.
align-content
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
.contenedor-flex {align-content: center;}
Alinea los elementos del contenedor-flex cuando el contenedor es multilinea y los elementos no utilizan todo el espacio disponible en el eje transversal. El valor por defecto es stretch.
Propiedad
Sintaxis
Descripción
align-self
align-self: auto | flex-start | flex-end | center | baseline | stretch;
.item-flex {align-self: flex-start;}
Reposiciona elementos individuales relativamente al eje transversal. sobreescribe la propiedad a elementos posicionados con align-items.
flex-grow
flex-grow: número | initial | inherit;
.item-flex {flex-grow: 2;}
Define cuánto puede crecer un elemento flex, si fuera necesario. El valor por defecto es 0.
flex-shrink
flex-shrink: número | initial | inherit;
.item-flex {flex-shrink: 2;}
Define cuánto puede disminuir (contraerse) un elemento flex, si fuera necesario. El valor por defecto es 1.
flex-basis
flex-basis: número | auto | initial | inherit | content;
.item-flex {flex-basis: 200px;}
Especifica el valor inicial del tamaño principal de un elemento flex. El valor por defecto es auto.
flex
flex: none | flex-grow [flex-shrink] [flex-basis];
.item-flex {flex: 1;}
La forma abreviada para flex-grow, flex-shrink y flex-basis juntos. El valor por defecto es 0 1 auto.
order
order: número | initial | inherit;
.item-flex {order: -1;}
Se utiliza para cambiar el orden en el que aparecen los elementos individuales.
Bueno hasta aquí, toda la explicación de la propiedad display flex
que junto con display grid
han llegado para facilitarnos mucho la maquetación web.
Ahora como siempre digo, solo queda prácticar mucho con ella, para aprender a dominarla. Nada más un saludo, gracias por leer y si tienes algún comentario, sugerencia, etc... hazmelo llegar.