Qué hay detrás de flex:1;

La matemática detrás de CSS

Leonidas Esteban

Leonidas Esteban

Qué hay detrás de flex: 1;

flex: 1;

En Flexbox es super común utilizar este valor para hacer que un elemento cubra todo el espacio disponible de un contenedor flexible y hoy quiero contarte que significa y ponernos a prueba en casos menos usuales.

Flex

Flex es la sintaxis corta de 3 propiedades del flex layout box model flex-grow, flex-shrink y flex-basis.

Flex Grow

Es la capacidad de "agrandamiento" o expansión de un flex item.

Flex Shrink

Es la capacidad de "achicamiento" o reducción de un flex item.

Flex Basis

Es la base Flexible sobre la cual hacer cálculos tanto para expansión o reducción.

los valores flexibles por defecto de un flex item son:

flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;

Te voy a explicar en profundidad esos 3 conceptos y como es que flex 1 funciona.

/* supón que viewport width son 1000px */
.flexContainer {
  display: flex;
  height: 100px;
}

.flexItem-1 {
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #ef0070;
}
alt

En resumen obtienes un flex item con 100px de ancho (pero sin asignar un ancho explicito). Esto es justamente la base flexible, el ancho mínimo con el cual trabajar que teniendo en cuenta tanto "grow" como "shrink" están en 0.

Combinarla con los otro parámetros pueden empezar a hacer esto algo más confuso

.flexItem-1 {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #ef0070;
}

Ahora actualizamos el valor de flex-grow a 1, donde 1 significa el 100% de su contenedor flexible y este es el resultado:

alt

Como puedes imaginar el flex item a tomado el 100% del tamaño físico (1000px) de su contenedor, pero la explicación real consiste en que flex-grow: 1; se traduce así:

.flexItem-1 ahora es capaz de extenderse hasta un máximo del 100% de su contenedor flexible.

Es una posibilidad que se hizo realidad en exactamente esta condición porque el contenedor flexible no contenía ningún otro flex item. Entonces ahora agreguemos otros 2 elementos con configuraciones particulares.

.flexItem-2 {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #00f8fb;
}

.flexItem-3 {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #fbf57e;
}
División al mismo tamaño.División al mismo tamaño.

Ahora tenemos 3 elementos que se han divido el 100% del área total del contenedor flexible equitativamente. Esto ocurre por la "posibilidad" de tener el 100% del tamaño de su padre pero al haber más elementos en sus mismas condiciones el resultado fue que sean exactamente iguales en sus dimensiones.

Ahora, que tal si variamos más los valores de crecimiento:

.flexItem-3 {
  flex-grow: 2;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #fbf57e;
}

¿Cuál crees que será el resultado?

agregué textos con los tamaños finalesagregué textos con los tamaños finales

¿Esto tiene sentido para ti? ¿Crees que el área amarilla debería tener 500px? te explico por qué no pasó así.

El tamaño de la sección posible de crecimiento sale de restar al tamaño total del contenedor flexible, la sumatoria de las bases flexibles y dividirlo por la suma de todo el crecimiento flexible:

Tamaño total: 1000;
Suma de bases flexibles: 300;
Suma de crecimiento flexible: 4;

(1000 - 300) / 4 = 175

175

Ahora calculemos el ancho del área amarilla que es el tamaño de la sección posible de crecimiento multiplicados su el crecimiento flexible y sumado por su base flexible:

Sección posible de crecimiento: 175;
Crecimiento flexible: 2;
Base Flexible: 100;

175 * 2 + 100 = 450

Eureka

Ahora... que tal si agregamos más propiedades que modificarían el tamaño de una caja.

.flexItem-3 {
  flex-grow: 2;
  flex-shrink: 0;
  flex-basis: 100px;
  background: #fbf57e;
  padding: 20px;
  border: 10px dashed red;
}
alt

Oh no!

Que no cunda el pánico, solo nuestra formula final no estaba completa:

Sección de posible crecimiento:

Tamaño total: 1000;
Suma de bases flexibles: 300;
Suma de crecimiento flexible: 4;
Suma de relleno totales: 40;
Suma de bordes totales: 20;

(1000 - 300 - 40 - 20) / 4 = 160

Ancho de la sección amarilla:

Sección posible de crecimiento: 160;
Crecimiento flexible: 2; 
Base Flexible: 100;
Suma de relleno: 40;
Suma de Bordes: 20;

160 * 2 + 100 + 40 + 20 = 480

Este calculo final no sería necesario si agregáramos el valor border-box a la propiedad box-sizing del elemento, la cual no es de ninguna manera mi recomendación.

¿Y flex-shrink?

Bien, gracias.

flex-shrink: 0; se interpretaría como:

Bajo ningún motivo serás más pequeño de tu tamaño deseado.

hagamos un ligero cambio en la base flexible del primer flex item

.flexItem-1 {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 1000px;
  background: #ef0070;
}
alt

Esto generó varios fenómenos:

  • La suma de tamaños de linea (ancho) del los flex items ahora es 1260.
  • El tamaño de el contenedor flexible no a aumento su tamaño quedando en 1000.
  • Se genera un desbordamiento.
  • Si pusieramos un overflow: scroll; en el contenedor flexible. tendríamos un scroll en el eje principal del contenedor flexible.
  • Todo esto porque los 3 elementos eran "inflexibles" gracias al mínimo de su tamaño esperado.
  • flex-basis reemplazó un ancho mínimo sobre los 3.
  • El 3rer elemento flexible también cuenta con bordes y rellenos que suman 60 en su línea.

¿Cuándo entonces es útil un elemento inflexible?

El proyecto spotifuEl proyecto spotifu

Si viéramos el proyecto de Spotifu tendríamos que decidir cómo se comportarán las secciones laterales que si me preguntas a mi son inflexibles dejando al área central expandirse sobre el espacio disponible.

Eureka, oh wait. Ya estoy sintiendo el comentario que no leeré porque no hay comentarios sobre que debería usar un grid en este caso. si, pero estamos hablando de Flex y este ejemplo estaba bonito.

Pero aquí otra situación contextual

alt
El cover del album sería un elemento inflexible (o con otras condiciones más sofisticadas de flexibilidad) dejando el área disponible al titulo de la canción y compañía.

Ah! flex:1, casi lo olvido

Traduce por alguna razón a:

flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%; /* hmmm */

Ahora que sabes cómo se comporta cada propiedad en particular ya sabes porque flex:1 "ocupa todo el área disponible" (y a veces no).

Si sabes la razón técnica sobre por qué flex-basis pasa de auto a 0% por favor escríbeme.

Te dejo de tarea tambien entender que es lo que pasa si flex-shinrk es diferente de 0, o podemos averiguarlo juntos en el curso de Flexbox Layout y Componentes.

Ilustracion que representa como crece alguien profesionalmente

Entérate de las últimas novedades

Streamings, Noticias y Early Adopter bonus. Sé el primero en enterarte de todo.