Guia definitiva de Flexbox (2): Flex basis, flex-frow, flex-shrink

Como su nombre lo indica, Flexbox es un modelo de cajas flexibles, esto significa que las dimensiones de las cajas son elásticas y pueden expandirse o encogerse. En otras palabras, aunque se definan un alto o ancho, estos valores no siempre serán respetados por el navegador al dibujar el documento.

Diseño web
8 minutos
Hace 8 años
Guia definitiva de Flexbox (2): Flex basis, flex-frow, flex-shrink

¡Accede a cientos de cursos
con solo un pago al año!

Blog Microbanner

Como su nombre lo indica, Flexbox es un modelo de cajas flexibles, esto significa que las dimensiones de las cajas son elásticas y pueden expandirse o encogerse. En otras palabras, aunque se definan un alto o ancho, estos valores no siempre serán respetados por el navegador al dibujar el documento.

Que a un elemento le asignemos width: 100px y que su ancho final sea 160px confunde mucho cuando comenzamos. Pero una vez que comprendemos cómo se calculan las dimensiones en Flexbox, podremos resolver problemas complejos de layout con facilidad.

Main size y cross size

Main size y cross size (tamaño principal y secundario) son las dimensiones de ancho y alto de los flex-items. Estos tamaños son siempre relativos a los ejes, por lo que main size podría ser width o height según la dirección del main axis (de igual manera con el cross size).

Debe tenerse en cuenta que, como en cualquier caja, los valores de padding y border suman al tamaño final (salvo que se use box-sizing: border-box).

Una vez entendido esto, el problema es saber cómo hace el navegador para calcular las dimensiones finales de los items.

Para el cross size, hay tres escenarios:

  1. Si se ha definido (por width o height) ese tamaño se respetará.
  2. Si no se ha definido, se utilizará todo el espacio disponible.
  3. Si no se ha definido y se utiliza un valor diferente de stretch para align-content o align-items en el contenedor, se tomará el tamaño de su contenido.

Para el main-size, el cálculo es más complejo. Pero se basa en los siguientes principios:

  1. Si no se ha definido el tamaño, se calculará según el contenido.
  2. Si se ha definido (por width o height) esté podría respetarse, podría encogerse, o crecer.

Espacio disponible y espacio ocupado

Según lo anterior, el verdadero reto es determinar el main size. Para hacerlo, primero debemos entender los siguientes conceptos:

  • El espacio ocupado es la suma de los main-size de todos los flex-items en la misma línea, más los márgenes si los hubiera.
  • El espacio disponible es la diferencia entre el tamaño del contenedor y el espacio ocupado. Este valor podría ser positivo o negativo.
  • Si el espacio disponible es negativo (es decir, el tamaño sumado de los items supera al del contenedor) el comportamiento predeterminado es que los flex-items se encojan para caber en una sola línea.
  • Aunque el main-size puede encogerse, los márgenes nunca colapsan.

Tamaño base para los items: “flex-basis”

La propiedad flex-basis, como su nombre lo indica, define el main-size base para un flex-item. Tamaño base principal (main size base) significa que no necesariamente ese será su tamaño al dibujarse por el navegador, pero que será un punto de partida para calcular el tamaño final.

En otras palabras, si el main axis es horizontal (predeterminado), flex-basis será equivalente a width; y si el main axis es vertical, flex-basis será equivalente a height.

Ten en cuenta que el tamaño definido por flex-basis es, como su nombre lo dice, el tamaño base. Es decir, que podrá variar (crecer o encogerse), según los valores de flex-grow y flex-shrink que veremos más adelante.

Importante

  • flex-basis siempre gana sobre el valor de width o height.
  • Si no se define el valor de flex-basis o se establece en auto, se tomará en cuenta el valor de width o height según sea el caso.
  • Si no se define un valor para flex-basis y tampoco se especifica el tamaño por width o height, se definirá el main-size según su contenido.

Crecimiento del main-size: “flex-grow”

La propiedad flex-grow, como su nombre lo indica, controla que tanto crecerá el flex-item para rellenar el espacio disponible. Su valor solo puede ser un número entero (no negativo).

Esta propiedad solo se aplica si el espacio disponible es positivo (el tamaño del contenedor es mayor a la suma de los flex-items y sus márgenes).

¿Qué significa el número en flex-grow?

En flex-grow:x el numero x indica cuantas unidades crecerá el item para calcular su tamaño final. Por ejemplo, flex-grow: 3 significa que el item crecerá 3 unidades.

¿Cuánto vale cada unidad?

Para el ejemplo anterior, sabemos que el item crecerá 3 unidades. ¿Pero cuanto vale cada unidad? La forma para calcularlo es bastante sencilla. Simplemente hay que dividir el espacio disponible entre la suma de los flex-grow de todos los items (en la misma linea). Así:

unit grow = espacio disponible / suma de flex-grow

Veamoslo con un ejemplo

.container { width: 500px; } .item-1 { flex-basis: 100px ; flex-grow: 1 } .item-2 { flex-basis: 100px ; flex-grow: 2 } .item-3 { flex-basis: 100px ; flex-grow: 1 } .item-4 { flex-basis: 100px ; flex-grow: 1 }

En este caso el espacio disponible es de 100px (tamaño del contenedor menos la suma del tamaño de los items) y este debe distribuirse entre los items de la siguiente forma:

100px/(1+2+1+1) = 20px ->; Este es el valor de la unidad (unit grow).

Luego esta unidad de crecimiento se multiplicará por el valor de flex-grow para determinar cuanto crecerá cada item.

item1->; 20px * 1 = 20px item2->; 20px * 2 = 40px item3->; 20px * 1 = 20px item4->; 20px * 1 = 20px

Finalmente, el main size de cada item al dibujarse por el navegador será:

item1 ->; 120px item2 ->; 140px item3 ->; 120px item4 ->; 120px

Ten en cuenta que si los items tuvieran márgenes, el espacio disponible sería menor (habría que restarle el tamaño total de los márgenes). Por ejemplo, si para el caso anterior todos los items tuvieran margin: 5px, el espacio disponible sería:

500px - (100px+100px+100px+100px) - (5px+5px+5px+5px+5px+5px+5px+5px) = 60px

Encogimiento del main-size: “flex-shrink”

Si el espacio disponible es negativo (el tamaño del contenedor es menor a la suma de los tamaños de los items), de forma predeterminada los items se encogen en proporciones iguales para caber en una sola línea (en un próximo artículo trabajaremos flexbox con varias líneas de items). Con la propiedad flex-shrink se controla cómo se encogerán los elementos.

Para calcular el tamaño final de un item que se ha encogido, se usan los mismos principios que con flex-grow solo que en el sentido opuesto. Veamoslo con un ejemplo:

.container { width: 500px; } .item-1 { flex-basis: 150px ; flex-shrink: 1 } .item-2 { flex-basis: 150px ; flex-shrink: 2 } .item-3 { flex-basis: 150px ; flex-shrink: 1 } .item-4 { flex-basis: 150px ; flex-shrink: 1 }

  • En este caso, el espacio disponible es negativo (–100px) ya que todos los items sumados dan 600px y el contenedor tiene solo 500px.
  • La unidad (unit shrink) se define dividiendo el espacio disponible entre la suma de los valores de flex-shrink, es decir: -100px/5 = -20px
  • Luego, los tamaños finales serán:

item-1: 130px (150-20px*1) item-2: 110px (150-20px*2) item-3: 130px (150-20px*1) item-4: 130px (150-20px*1)

En la siguiente página web puedes probar con los valores de flex-grow, flex-shrink y flex-basis:

http://madebymike.com.au/demos/flexbox-tester/

Ten en cuenta Un item no se reducirá más de su contenido mínimo (la palabra más corta o el elemento más pequeño con un tamaño determinado). Se puede cambiar esto con min-width o min-height.

Propiedad abreviada: “flex”

flex es el shorthand (propiedad abreviada) para flex-grow, flex-shrink y flex-basis (en ese orden específico).

Entonces:

.item { flex: 2 1 200px; }

Es igual a

.item { flex-grow: 2; flex-shrink: 1; flex-basis: 200px; }

El valor predeterminado de flex (si no se especifica) es:

flex: 0 1 auto;

Es decir que por defecto los items no van a crecer pero si reducirse de manera proporcional para ajustarse al espacio. Además, que flex-basis se establece en auto (respecto a su contenido).

Otros ajustes:

flex: auto;

Equivale a flex: 1 1 auto. Los items pueden crecer o reducirse según el caso y su flex-basis es calculado según el contenido.

flex: none

Equivale a: flex: 0 0 auto. Los items no crecen ni se reducen y flex-basis se calcula según el contenido.

flex: ;

Equivale a flex: 1 0. Esto significa que el item recibe el valor de espacio disponible proporcional a . Si todos los items usan este principio, sus **main-size** se verían definidos directamente por el.

Comentarios de los usuarios