Flexbox: flex-grow, flex-shrink y flex-basis 🎨
Tags: spanish, css, webdev, html
Published: 2022-03-28 14:14:05

#**Índice**   
1. [Introducción](#id1)
2. [El _shorthand_ `flex`](#id2)
3. [`flex-grow` para rellenar el espacio sobrante](#id3)
4. [`flex-shrink` para rellenar el espacio faltante](#id4)
5. [`flex-basis` para establecer el ancho base de los items](#id5)
6. [Conclusiones](#id6)
7. [Referencias](#id7)

## **1. Introducción** <a name="id1"><a/>
Flexbox ya es un estándar al momento de posicionar elementos y maquetar nuestras app y páginas web, como bien sabes existen propiedades `flex` que se pueden aplicar a nuestro `flex-container` como bien hay otras que se aplican a los `flex-items`.

Desde hace algún tiempo me tenía muy confundido el uso del _shorthand_ `flex`, gracias a esa duda este pequeño post existe.

## **2. El _shorthand_ `flex`** <a name="id2"><a/>
La propiedad `flex` nos sirve para escribir 3 propiedades propias de los `flex-item` en una sola línea.

![img](https://dev-to-uploads.s3.amazonaws.com/i/onoxj7gs9xj4wuf87kjl.png)

## **3. `flex-grow` para rellenar el espacio sobrante** <a name="id3"><a/>
* Se aplica a un `flex-item`.
* Acepta valores enteros escalares sin unidad de medida.
* Valor por defecto: `0`.

`flex-grow` permite repartir el espacio sobrante de un `flex-container` entre todos los `flex-items`.
Un hack útil para calcular cuánto crecerán los `flex-items` sería:

{% katex %}
 x = EspacioSobrante / \sum grow
{% endkatex %}

Donde:
`x` es el espacio que se debe adicionar a cada `flex-item` por unidad de `grow` que haya en la regla css.

Imagina un escenario como el siguiente:

![img](https://github.com/crisdux/img-dev-to/blob/master/flex-grow-2.png?raw=true)

Tenemos 5 `flex-items` de `100px x 100px` donde el `flex-container` tiene un ancho de `700px`, entonces nos sobran `200px` para poder repartir como queramos. Acá entra `flex-grow` al rescate.

En el código siguiente vemos a `flex-grow` en acción.

{% codepen https://codepen.io/dux-soft/pen/MWreMxe %}

Cada `flex-item` tiene la propiedad `flex-grow` con sus respectivos valores. Ahora apliquemos nuestro hack 😎

{% katex %}
 x = 200px/8 = 25px
{% endkatex %}

> La sumatoria de los `flex-grow` es `8` por que adicionamos todos los valores de todos los `flex-items`.

Por cada unidad de `flex-grow` debemos adicionar `25px`, de esta manera sabremos cual es el nuevo ancho de todos los `flex-items`.

Podemos resumir la operación en la siguiente tabla:

| items  | flex-grow | adicción | TOTAL |
| ------ | --------- | -------- | ----- |
| item-1 | 1         | 25px     | 125px |
| item-2 | 2         | 50px     | 150px |
| item-3 | 1         | 25px     | 125px |
| item-4 | 2         | 50px     | 150px |
| item-5 | 2         | 50px     | 150px |

![img](https://github.com/crisdux/img-dev-to/blob/master/grow-final.png?raw=true)

De esta manera `flex-grow` sirve para rellenar el espacio sobrante de `flex-container` entre todos sus `flex-items`.

## **4. `flex-shrink` para rellenar el espacio faltante** <a name="id4"><a/>
* Se aplica a un `flex-item`.
* Acepta valores enteros escalares sin unidad de medida.
* Valor por defecto: `1`.

`flex-shrink` permite repartir el espacio faltante de un `flex-container` entre todos los `flex-items`.
Esta propiedad es la contraria a `flex-grow` y por eso mismo el funcionamiento es muy similar.

Imagina un escenario como el siguiente:

![img](https://github.com/crisdux/img-dev-to/blob/master/flex-shrink-1.png?raw=true)

Tenemos 4 `flex-items` de `250px x 100px` donde el `flex-container` tiene un ancho de `550px`, el ancho total de los 4 `flex-items` es de `1000px` pero el contenedor solo es de `550px`. ¿Qué ocurre entonces? Por defecto el navegador intentará tratar de acomodar los `flex-items` dentro del `flex-container` de una manera proporcional (esto hará que cada item ya no mida `250px` de ancho como establecimos en el código), pero ¿que pasa si queremos que algunos `flex-items` en particular ocupen más o menos espacio? Acá entra en acción `flex-shrink` 🤗

> _Pese a que en el código indicamos que el ancho de cada item sea de `250px` el navegador recalcula este ancho para que no desborden su contenedor, entonces hace `450px / 4 = 112.5` (entre 4 por que es la cantidad de los items), y restamos `250px - 112.5px = 137.5px`, eso medirá cada item para el navegador antes de aplicar `flex-shrink`._

Puedes ver el código a continuación:

{% codepen https://codepen.io/dux-soft/pen/bGaqWzB %}

Se puede usar la misma fórmula que vimos con `flex-grow` pero teniendo en cuenta el espacio que falta, ya no el que sobra:

{% katex %}
 x = EspacioFaltante/ \sum shrink
{% endkatex %}

El contenedor mide `550px` y la suma de todos los items es de `1000px`, entonces tendríamos un déficit de `450px` que debemos acomodar.

La suma de `flex-shrink` de todos los items es de `8`.

{% katex %}
 x = 450px/8 = 56.25px
{% endkatex %}

Finalmente debemos restar `56.25px` a `250px` (ancho original) por unidad de `flex-shrink`.

Podemos resumir la operación en la siguiente tabla:

| items  | flex-shrink | adicción           | TOTAL    |
| ------ | ----------- | ------------------ | -------- |
| item-1 | 2           | 56.25px*2=112.5px  | 137.5px  |
| item-2 | 2           | 56.25px*2=112.5px  | 137.5px  |
| item-3 | 3           | 56.25px*3=168.75px | 81.25px  |
| item-4 | 1           | 56.25px            | 193.75px |


Finalmente el ejemplo se ve así:
![img](https://github.com/crisdux/img-dev-to/blob/master/flex-shrink-2.png?raw=true)

## **5. `flex-basis` para establecer el ancho base de los items** <a name="id5"><a/>

* Se aplica a un `flex-item`.
* Acepta los mismos valores y unidades que `width` (px, %, etc.)
* Valor por defecto: `auto`. (respeta el `width` y `height` si están establecidos)

`flex-basis` establece el ancho base de un item, si mantenemos el valor en `auto` respetara el ancho y alto previamente establecidos (si existe), si escribimos un `flex-basis` con valores específicos **siempre** sobre escribirá valores de ancho y alto.

{% codepen https://codepen.io/dux-soft/pen/OJzpaBj %}


Al inicio de este post empezamos hablando de el atajo `flex` que resume en una línea todas estas propiedades; dejaremos esto para otro post.

Por ahora conocer esto es más que suficiente.

## **6. Conclusiones**<a name="id6"><a/>
* `flex-grow` se usa cuando tenemos espacio de sobra en el `flex-container`, en otras palabras, cuando él anchos de los items es menor al de su contenedor repartiendo dicho espacio como el programador quiera.
* `flex-shrink` reparte el espacio faltante del contenedor entre sus items, en otras palabras, cuando el contenedor es más pequeño que el anchos de todos sus items.
* `flex-basis` establece el ancho base de los items.

## **7. Referencias**<a name="id7"><a/>
* [Learn CSS](https://web.dev/learn/css/flexbox/)
* [Guía completa de flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
* https://www.desarrollolibre.net/blog/css/las-propiedades-flex-grow-flex-shrink-y-flex-basis
* https://ed.team/blog/guia-definitiva-de-flexbox-2-flex-basis-flex-frow-flex-shrink

---

Posiblemente los siguientes artículos sean de tu interés: 

{% link https://dev.to/duxtech/es6-promesas-en-javascript-5bpb %}

{% link https://dev.to/duxtech/logical-nullish-assignment-en-javascript-4367 %}

{% link https://dev.to/duxtech/local-storage-api-en-javascript-o88 %}

![img](https://media.giphy.com/media/tYyQObj37kBMs/giphy.gif)