# Фактор сжимаемости флекс блоков

В предыдущем уроке мы выяснили, что, когда флекс элементам не хватает места, они начинают сжиматься. То, насколько суммарная ширина больше ширины родителя называется отрицательным свободным пространством.

Технически сжатие означает, что от ширины каждого элемента отщипывается кусочек ширины так, чтобы все элементы поместились в своего родителя.

Давайте произведем некоторый расчет. Пусть, к примеру, у нас есть `4` элемента шириной в `200px`. Пусть при этом ширина родителя равна `700px`. Получается, что суммарная ширина элементов равна:

``200px` * `4` = `800px``

Это ширина на `100px` больше ширины родителя. Давайте вычислим, сколько от каждого элемента надо отщипнуть, чтобы элементы поместились в своего родителя:

``100px` / `4` = `25px``

То есть ширина элементов будет:

``200px` - `25px` = `175px``

Реализуйте описанные блоки и проверьте измерением, что ширина элементов будет действительно равна рассчитанной нами.

Рассчитайте ширину блоков, а затем проверьте расчеты измерением:

`<div class="parent"> <div class="child elem1">1</div> <div class="child elem2">2</div> <div class="child elem3">3</div> </div>` `.parent { display: flex; width: 200px; height: 200px; border: 1px solid red; } .child { height: 50px; border: 1px solid green; } .elem1 { width: 100px; } .elem2 { width: 100px; } .elem3 { width: 100px; }`

## Разная ширина элементов

Пусть теперь наши элементы имеют разную ширину. В этом случае отщепляемый кусочек будет пропорционален ширине этого элемента и будет вычисляться по следующей формуле: отриц. св. пространство * (ширина элемента / сумма всех ширин элементов).

Пусть у нас есть `4` элемента. Пусть ширина первого элемента равна `400px`, ширина остальных элементов - `200px`, а ширина родителя `900px`.

Суммарная ширина элементов равна:

``400px` + `3` * `200px` = `1000px``

Тогда отрицательное свободное пространство будет равно:

``1000px` - `900px` = `100px``

Найдем сколько отщипнется первого элемента:

``100px` * (`400px` / `1000px`) = `40px``

То есть его ширина будет равна:

``400px` - `40px` = `360px``

Найдем сколько от каждого из остальных элементов:

``100px` * (`200px` / `1000px`) = `20px``

То есть ширина этих элементов будет равна:

``200px` - `20px` = `180px``

Реализуйте описанные блоки и проверьте измерением, что ширина элементов будет действительно равна рассчитанной нами.

Рассчитайте ширину блоков, а затем проверьте расчеты измерением:

`<div class="parent"> <div class="child elem1">1</div> <div class="child elem2">2</div> <div class="child elem3">3</div> </div>` `.parent { display: flex; width: 300px; height: 200px; border: 1px solid red; } .child { height: 50px; border: 1px solid green; } .elem1 { width: 300px; } .elem2 { width: 100px; } .elem3 { width: 100px; }`

## Регулируем сжатие

По умолчанию от всех элементов отщипываются кусочки, пропорциональные ширине элемента. Однако, можно сделать так, чтобы от некоторых элементов отщипывались большие или меньшие куски. Для этого существует специальное свойство `flex-shrink`.

Данное свойство представляет собой некоторый вес, на который будет умножаться ширина элемента при подсчете отщипываемого кусочка по уже приведенной выше формуле. К примеру, если ширина элемента равна `200px`, а его `flex-shrink` равен `3`, то взвешенная (т.е. умноженная на вес) ширина элемента получится равна:

``200px` * `3` = `600px``

Формула с учетом `flex-shrink` будет иметь следующий вид: отриц. св. пространство * (взвешенная ширина элемента / сумма всех взвеш. ширин элементов).

Давайте посмотрим на примере. Пусть у нас есть `4` элемента. Пусть ширина первого элемента равна `400px`, а `flex-shrink` равен `2`, ширина остальных элементов - `200px`, а их `flex-shrink` равен `1`. Пусть ширина родителя `900px`.

Суммарная ширина элементов равна:

``400px` + `3` * `200px` = `1000px``

Отрицательное свободное пространство будет равно:

``1000px` - `900px` = `100px``

Суммарная взвешенная ширина элементов равна:

``400px` * `2` + `200px` * `1` + `200px` * `1` + `200px` * `1` = `1400px``

Взвешенная ширина первого элемента равна:

``400px` * `2` = `800px``

От первого элемента отщипнется следующий кусочек:

``100px` * (`800px` / `1400px`) = `100px` * `0.57` = `57.14px``

Ширина элемента будет равна:

``400px` - `57``.14px` = `342.86px` ~ `343px``

Взвешенная ширина каждого из остальных элемента равна:

``200px` * `1` = `200px``

От каждого элемента отщипнется следующий кусочек:

``400px` - `57.14px` = `342.86px` ~ `343px``

Ширина элемента будет равна:

``200px` - `14.2px` = `185.8px` ~ `186px``

Реализуйте описанные блоки и проверьте измерением, что ширина элементов будет действительно равна рассчитанной нами.

Рассчитайте ширину блоков, а затем проверьте расчеты измерением:

`<div class="parent"> <div class="child elem1">1</div> <div class="child elem2">2</div> <div class="child elem3">3</div> </div>` `.parent { display: flex; width: 200px; height: 200px; border: 1px solid red; } .child { height: 50px; border: 1px solid green; } .elem1 { width: 100px; flex-shrink: 2; } .elem2 { width: 100px; flex-shrink: 1; } .elem3 { width: 100px; flex-shrink: 1; }`

Рассчитайте ширину блоков, а затем проверьте расчеты измерением:

`<div class="parent"> <div class="child elem1">1</div> <div class="child elem2">2</div> <div class="child elem3">3</div> </div>` `.parent { display: flex; width: 200px; height: 200px; border: 1px solid red; } .child { height: 50px; border: 1px solid green; } .elem1 { width: 100px; flex-shrink: 3; } .elem2 { width: 100px; flex-shrink: 2; } .elem3 { width: 100px; flex-shrink: 1; }`

Рассчитайте ширину блоков, а затем проверьте расчеты измерением:

`<div class="parent"> <div class="child elem1">1</div> <div class="child elem2">2</div> <div class="child elem3">3</div> <div class="child elem4">4</div> </div>` `.parent { display: flex; width: 500px; height: 200px; border: 1px solid red; } .child { height: 50px; border: 1px solid green; } .elem1 { width: 300px; flex-shrink: 3; } .elem2 { width: 200px; flex-shrink: 2; } .elem3 { width: 200px; flex-shrink: 1; } .elem4 { width: 200px; flex-shrink: 1; }`

## Нюансы

Свойство `flex-shrink` по умолчанию имеет значение 1 - именно поэтому элементы сжимаются. Чтобы отменить сжатие, нужно установить это свойство в значение `0`. Кроме того, можно давать дробные значения, например, `0.5` или `1.5`.

←→
↑