Esenciales de Flexbox
Flexbox es un conjunto de propiedades CSS que nos ayudan a crear layouts de nuestras páginas web de una manera más sencilla y fácil de entender sin necesidad de utilizar floats o elementos inline-block. Con pocas líneas de código podemos decidir el comportamiento de nuestros elementos (columnas, filas, dirección, alineación, tamaño, orden, etc). A continuación estudiaremos las principales propiedades de Flexbox.
Contenedores Flexbox
Para empezar a trabajar con Flexbox necesitamos crear un contenedor con la propiedad display: flex
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<div class="container__item bg--blue">Uno</div>
<div class="container__item bg--red">Dos</div>
<div class="container__item bg--purple">Tres</div>
<div class="container__item bg--yellow">Cuatro</div>
</div>
</body>
</html>
.container {
background: #ecf0f1;
display: flex;
height: 400px;
margin-left: auto;
margin-right: auto;
width: 800px;
}
.bg--blue {
background: #3498db;
}
.bg--red {
background: #c0392b;
}
.bg--purple {
background: #9b59b6;
}
.bg--yellow {
background: #f1c40f;
}
Tradicionalmente sabemos que los elementos div
de nuestra página tienen un display block por lo cual se acomodan uno debajo del otro. Pero cuando nuestro contenedor tiene la propiedad display: flex
sus hijos directos obtienen propiedades de Flexbox y el primer comportamiento que notarás es que estos se convierten en columnas, que ocupan el ancho de acuerdo a su contenido dentro de ellos y que además ocupan todo el alto disponible de su contenedor.
Ancho de columnas
Sabemos que los hijos directos de un contenedor con display: flex
por defecto se acomodarán en forma de columnas uno después de otro y que su ancho queda definido por su contenido dentro de ellos. Ahora veremos como establecer el ancho de esos elementos con otras propiedades de Flexbox.
flex-basis
Con la propiedad flex-basis
podemos establecer el ancho inicial de los elementos de un contenedor flex.
.container__item {
flex-basis: 150px;
}
Nuestro layout se ve algo así:
flex-grow
Ahora veremos como hacer crecer el ancho de nuestras columnas con la propiedad flex-grow
para que puedan llenar todo el ancho de su contenedor:
.container__item {
flex-basis: 150px;
flex-grow: 1;
}
Lo que hizo flex-grow: 1;
es hacer crecer todos los elementos de la misma manera para que puedan llenar el espacio de su contenedor.
Veamos que pasa cuando queremos hacer crecer uno de los elementos 2 veces para entender como funciona flex-grow.
.container__item:nth-child(2) {
flex-grow: 2;
}
Hacer crecer un elemento 2 veces con flex-grow
no quiere decir que este elemento va tener el doble de tamaño que sus hermanos. Lo que quiere decir es que va tener 2 veces el crecimiento que tuvieron sus hermanos en relación al ancho inicial que definimos anteriormente con flex-basis
.
Los elementos que hicimos crecer 1 vez con flex-grow: 1;
tuvieron un crecimiento de +40px cuando el ancho inicial con flex-basis
fue de 150px, dando un total de 190px.
El elemento que hicimos crecer 2 veces con flex-grow: 2;
entonces creció dos veces más que sus hermanos +80px, dando un total de 230px.
flex-shrink
Con esta propiedad podemos encoger el ancho de nuestras columnas, justo lo opuesto de flex-grow aunque funcionan de manera similar:
.container__item {
flex-basis: 400px;
flex-shrink: 1;
}
.container__item:nth-child(2) {
flex-shrink: 2;
}
Todos los elementos tienen un ancho inicial de 400px establecido con flex-basis
. Los elementos que se encogieron 1 vez con flex-shrink: 1;
redujeron su tamaño -160px, dando un total de 240px.
El segundo elemento que hicimos encoger su ancho 2 veces más que sus hermanos entonces se redujo -320px, dando un ancho total de 80px.
flex
La propiedad flex es un shorthand para establecer los siguientes valores.
- flex-grow
- flex-shrink
- flex-basis
.container__item {
flex: 1 1 400px;
}
.container__item:nth-child(2) {
flex: 1 2 400px;
}
Si queremos podemos pasar únicamente el primer valor, y veamos que es lo que pasa:
.container__item {
flex: 1;
}
.container__item:nth-child(2) {
flex: 2;
}
Como podemos observar pasando solo el primer valor podemos hacer fácilmente que uno de los elementos sea del doble de ancho que sus hermanos.
Filas o Columnas
Anteriormente vimos que por defecto los elementos dentro de nuestro contenedor flex se acomodaban de manera horizontal uno después del otro. Pero podemos decidir ese comportamiento con la propiedad flex-direction
.
flex-direction
Esta propiedad la escribiremos en nuestro contenedor flex. El valor por defecto que este tiene es flex-direction: row;
.
.container {
background: #ecf0f1;
display: flex;
flex-direction: row;
height: 400px;
margin-left: auto;
margin-right: auto;
width: 800px;
}
Podemos hacer que los elementos se acomoden de manera vertical uno debajo de otro con flex-direction: column;
.
También podemos hacer que los elementos se acomoden al revés con los siguientes valores:
flex-direction: row-reverse;
flex-direction: column-reverse;
Orden de los elementos
Con Flexbox podemos establecer el orden de los elementos de un contenedor flex. Para ello utilizamos la propiedad order
en cada uno de los elementos.
order
Establece el orden del elemento dentro de el contenedor flex.
.container {
background: #ecf0f1;
display: flex;
flex-direction: row;
height: 400px;
margin-left: auto;
margin-right: auto;
width: 800px;
}
.container__item {
flex: 1;
}
.container__item:nth-child(2) {
order: 1;
}
.container__item:first-child {
order: 2;
}
.container__item:nth-child(3) {
order: 4;
}
.container__item:last-child {
order: 3;
}
Ajuste de elementos
Para ver otras propiedades de Flexbox vamos a actualizar un poco el contenido de nuestro documento HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<div class="container__item bg--blue">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.</p>
</div>
<div class="container__item bg--red">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
<div class="container__item bg--purple">
<p>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.</p>
</div>
<div class="container__item bg--yellow">
<p>Integer vitae libero ac risus egestas placerat.</p>
</div>
</div>
</body>
</html>
Asignamos un ancho máximo a nuestro contenedor de 800px y eliminamos el alto.
.container {
background: #ecf0f1;
display: flex;
flex-direction: row;
margin-left: auto;
margin-right: auto;
max-width: 800px;
}
.container__item {
flex: 1;
}
Entonces si redimensionamos nuestro navegador veremos que tenemos elementos que se ajustan de manera automática al ancho que llegue a tener su contenedor.
Pero nosotros queremos establecer un ancho mínimo pues no queremos que todo quede tan apretado.
.container__item {
flex: 1;
min-width: 150px;
}
Entonces para evitar que se salgan los elementos del contenedor usaremos la propiedad flex-wrap
.
flex-wrap
Con esta propiedad podemos hacer que los elementos del contenedor flex se ajusten de diferentes maneras. Por defecto nowrap.
- nowrap
- wrap
- wrap-reverse
.container {
background: #ecf0f1;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
}
Con flex-wrap: wrap;
los elementos que ya no caben se acomodan en la siguiente línea (líneas flex).
flex-flow
Esta propiedad es un shorthand para establecer las siguientes propiedades de una sola vez:
- flext-direction
- flex-wrap
.container {
background: #ecf0f1;
display: flex;
flex-flow: row wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
}
Main Axis y Cross Axis
En Flexbox existen dos ejes en los cuales los elementos flex son colocados:
Main Axis
Es el eje principal donde los elementos flex se van posicionado uno después de otro.
Cross Axis
Es el eje perpendicular al Main Axis
Veamos siguiente ejemplo para describir los ejes:
.container {
background: #ecf0f1;
display: flex;
flex-flow: row wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
min-height: 494px;
}
.container__item {
flex-basis: 150px;
height: 200px;
}
Una vez que conocemos estos ejes vamos a ver como podemos alinear nuestros elementos en base a estos.
Alineación en Cross Axis
Primero hagamos algunos ajustes para establecer un ancho inicial de nuestros elementos de 400px.
.container__item {
flex-basis: 400px;
flex-grow: 1;
height: 200px;
}
Al hacer estos nuestros elementos se van desbordando hacia la siguiente línea sobre el Cross Axis.
align-content
Esta propiedad nos ayuda a alinear nuestros elementos sobre el Cross Axis y puede recibir multiples valores.
- flex-start
- flex-end
- center
- space-between
- space-around
- space-evenly
- stretch
Ejemplo con align-content: flex-start;
.container {
background: #ecf0f1;
display: flex;
flex-flow: row wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
min-height: 494px;
align-content: flex-start;
}
Ejemplo con align-content: center;
Nota: Únicamente funciona cuando hay elementos que se desbordan en otra línea sobre el Cross Axis y solo sobre esas líneas.
align-items
Esta propiedad alinea cada uno de los elementos flex sobre el Cross Axis, por defecto tiene un valor de stretch
que hace que estos ocupen todo el alto de su contenedor, pero puede recibir los siguientes valores.
- flex-start
- flex-end
- center
- baseline
- stretch
Ejemplo con align-items: center;
.container {
background: #ecf0f1;
display: flex;
flex-flow: row wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
min-height: 494px;
align-items: center;
}
.container__item {
flex-basis: 150px;
flex-grow: 1;
}
align-self
También es posible alinear cada uno de los elementos de manera individual. La propiedad align-self
es aplicada a los elementos flex y puede recibir los mismos valores que la propiedad align-items
.
Ejemplo con align-self: flex-start;
.container__item:last-child {
align-self: flex-start;
}
Alineación en Main Axis
Ahora veamos como podemos alinear nuestros elementos sobre el eje principal.
justify-content
Esta es la propiedad que nos permite alinear nuestros elementos en el Main Axis y puede recibir los siguientes valores.
- flex-start
- flex-end
- center
- space-between
- space-around
Ejemplo con justify-content: space-between;
.container {
background: #ecf0f1;
display: flex;
flex-flow: row wrap;
margin-left: auto;
margin-right: auto;
max-width: 800px;
min-height: 494px;
justify-content: space-between;
}
.container__item {
flex-basis: 150px;
}
Prefijos propietarios
Flexbox no funciona por defecto en todos los navegadores, debemos agregar prefijos propietarios.
http://caniuse.com/#feat=flexbox
#flex-container > .flex-item {
-webkit-flex: auto;
flex: auto;
}