В предыдущем уроке мы выяснили, что, когда флекс элементам не хватает места, они начинают сжиматься. То, насколько суммарная ширина больше ширины родителя называется отрицательным свободным пространством.
Технически сжатие означает, что от ширины каждого элемента отщипывается кусочек ширины так, чтобы все элементы поместились в своего родителя.
Давайте произведем некоторый расчет. Пусть,
к примеру, у нас есть 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
.