Contenedor flexible.
El modelo de caja flexible resuelve los problemas del modelo de caja tradicional de una manera elegante. Este modelo aprovecha las herramientas que usa el modelo de caja tradicional, como el posicionamiento absoluto y las columnas, pero en lugar de hacer flotar los elementos organiza las cajas usando contenedores flexibles. Un contenedor flexible es un elemento que convierte su contenido en cajas flexibles. En este nuevo modelo, cada grupo de cajas debe estar incluido dentro de otra caja que es la encargada de configurar sus características, tal como muestra el siguiente ejemplo.
<section id="cajapadre">
<div id="caja-1">Caja 1</div>
<div id="caja-2">Caja 2</div>
<div id="caja-3">Caja 3</div>
<div id="caja-4">Caja 4</div>
</section>
Elementos flexibles.
Para que un elemento dentro de un contenedor flexible se vuelva flexible, tenemos que declararlo como tal. Las siguientes son las propiedades disponibles para configurar elementos flexibles.
flex-grow – Esta propiedad declara la proporción en la cual el elemento se va a expandir o encoger. La proporción se determina considerando los valores asignados al resto de los elementos de la caja (los elementos hermanos).
flex-shrink – Esta propiedad declara la proporción en la que el elemento se va a reducir. La proporción se determina a partir de los valores asignados al resto de los elementos de la caja (los elementos hermanos).
flex-basis – Esta propiedad declara un tamaño inicial para el elemento.
flex – Esta propiedad nos permite configurar los valores de las propiedades flex-grow, lex-shrink, y flex-basis al mismo tiempo.
Las cajas flexibles se expanden o encogen para ocupar el espacio libre dentro de la caja padre. La distribución del espacio depende de las propiedades del resto de las cajas. Si todas las cajas se configuran como flexibles, el tamaño de cada uno de ellas dependerá del tamaño de la caja padre y del valor de la propiedad flex.
#cajapadre {
display: flex;
width: 600px;
}
#cajapadre > div {
height: 145px;
margin: 5px;
background-color: #CCCCCC;
}
#caja-1 {
flex: 1;
}
#caja-2 {
flex: 1;
}
#caja-3 {
flex: 1;
}
#caja-4 {
flex: 1;
}
En el ejemplo anterior, solo declaramos el valor flex-grow para la propiedad flex con el fin de determinar cómo se expandirán las cajas. El tamaño de cada caja se calcula multiplicando el valor del tamaño de la caja padre por el valor de su propiedad flex dividido por la suma de los valores flex-grow de todas las cajas. Por ejemplo, la fórmula para el elemento caja-1 es 600 × 1 / 4 = 150 (si la caja padre tuviera 600px de ancho). El valor 600 es el tamaño de la caja padre, 1 es el valor de la propiedad flex asignado al elemento caja-1, y 4 es la suma de los valores de la propiedad flex asignados a cada una de las cajas. Debido a que todas las cajas de nuestro ejemplo tienen el mismo valor 1 en su propiedad flex, el tamaño de cada caja será de 150 píxeles menos los márgenes.
El potencial de esta propiedad es evidente cuando asignamos diferentes valores a cada elemento.
#cajapadre {
display: flex;
width: 600px;
}
#cajapadre > div {
height: 145px;
margin: 5px;
background-color: #CCCCCC;
}
#caja-1 {
flex: 2;
}
#caja-2 {
flex: 1;
}
#caja-3 {
flex: 1;
}
#caja-4 {
flex: 1;
}
En el ejemplo anterior, asignamos el valor 2 a la propiedad flex del elemento caja-1. Ahora, la fórmula para calcular el tamaño de esta caja es 600 × 2 / 5 = 240. Debido a que no cambiamos el tamaño de la caja padre, el primer valor de la fórmula es el mismo, pero el segundo valor es 2 (el nuevo valor de la propiedad flex de caja-1), y la suma de los valores de todas las propiedades flex es 5 (2 para caja-1 y 1 para cada una de las otras tres cajas). Aplicando la misma fórmula para el resto de las cajas, podemos obtener sus tamaños: 600 × 1 / 5 = 120.
Comparando los resultados, podemos ver cómo se distribuye el espacio. El espacio disponible se divide en porciones de acuerdo a la suma de los valores de la propiedad flex de cada caja (un total de 5 en nuestro ejemplo). Luego, las porciones se distribuyen entre las cajas. El elemento caja-1 recibe dos porciones porque el valor de su propiedad flex es 2 y el resto de elementos recibe solo una porción porque el valor de sus propiedades flex es 1.
La ventaja no es solo que los elementos se vuelven flexibles, sino también que cada vez que agregamos un nuevo elemento, no tenemos que calcular su tamaño; los tamaños de todas las cajas se recalculan automáticamente.
Estas características son interesantes, pero existen otros escenarios posibles. Por ejemplo, cuando una de las cajas es inflexible y tiene un tamaño explícito, las otras cajas se flexionan para compartir el resto del espacio disponible.
#cajapadre {
display: flex;
width: 600px;
}
#cajapadre > div {
height: 145px;
margin: 5px;
background-color: #CCCCCC;
}
#caja-1 {
width: 300px;
}
#caja-2 {
flex: 1;
}
#caja-3 {
flex: 1;
}
#caja-4 {
flex: 1;
}
Del mismo modo que podemos tener una caja con un tamaño explícito, podemos tener dos o más. El principio es el mismo, solo que el espacio remanente se distribuye entre las cajas flexibles.
Existe un posible escenario en el cual podríamos tener que declarar el tamaño de un elemento pero mantenerlo flexible. Para lograr esta configuración, debemos utilizar el resto de los parámetros disponibles para la propiedad flex (flex-shrink y flex-basis).