CSS :: Свойство flex-shrink
css-свойство flex-shrink (от англ. flex shrink – сжатие флекс-элемента) определяет, какую долю своего доступного пространства будет отдавать данный флекс-элемент по сравнению с другими флекс-элементами.
Характеристики
- Значение по умолчанию: 1.
- Применяется: к флекс-элементам.
- Наследуется: нет.
- Анимируется: да.
- JavaScript: object.style.flexShrink="value".
Синтаксис
flex-shrink: <число>
Значения
В качестве значений свойство flex-shrink принимает число, называемое коэффициентом сжатия флекс-элемента. Он может быть нулем (флекс-элемент не участвует в сжатии) или любым положительным целым или дробным числом (по умолчанию 1). При этом следует помнить, что при установке паддингов у флекс-элементов, они при сжатии не уменьшаются (уменьшаться может только сам базовый размер элемента). Кроме того, чем больше коэффициент сжатия, тем сильнее сжимается элемент по сравнению с другими элементами.
Чтобы рассчитать итоговый размер требуемого флекс-элемента можно использовать следующий алгоритм.
- Первый шаг. Рассчитываем размер свободного отрицательного пространства флекс-контейнера (РСОПК). Для этого от ширины контейнера (ШК) (чистое пространство без паддингов) отнимаем сумму базовых размеров флекс-элементов (СБР), а также сумму их паддингов (СПЭ), соответствующих данному направлению: РСОПК = ШК - СБР - СПЭ;
- Второй шаг. Находим сумму произведений (СПБР) базовых размеров (БР) флекс-элементов на их коэффициенты сжатия (КС): СПБР = БР1*КС1 + БР2*КС2 + ... + БРn*КСn, где n - общее число флекс-элементов контейнера.
- Третий шаг. Рассчитываем нормированный коэффициент сжатия (НКС) каждого флекс-элемента. Для этого находим произведение базового размера элемента на его коэффициент сжатия, а результат делим на сумму произведений всех базовых размеров флекс-элементов на их коэффициенты сжатия: НКС = БР*КС/СПБР.
- Четвертый шаг. Рассчитываем итоговый размер флекс-элемента (ИР). Для этого от базового размера флекс-элемента отнимаем произведение модуля размера свободного отрицательного пространства на нормированный коэффициент сжатия: ИР = БР - РСОПК*НКС.
Как видим, алгоритм расчета итогового размера флекс-элемента при сжатии сложнее аналогичного алгоритма при распределении свободного пространства между элементами. Это связано с тем, что при сжатии учитываются не только соотношения коэффициентов сжатия элементов, но и соотношения их размеров между собой. Однако вдаваться в подробности мы не будем, заметим только, что полученный алгоритм (опять же) является результатом составления ряда пропорций и уравнений, которые могут быть решены в рамках школьной программы по математике.
Ссылки
Официальный сайт W3C: https://drafts.csswg.org/css-flexbox-1/#propdef-flex-shrink
Статья на Mozilla Firefox: https://developer.mozilla.org/ru/docs/Web/CSS/flex-shrink
Подробнее о модуле Flexbox смотрите в нашем учебнике здесь.
Примеры
htmlCodes
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Пример №1</title>
<style>
/* Оформляем родительские div'ы flex-элементов */
div{
display: flex;
width: 300px;
height: 120px;
margin: auto;
margin-top: 20px;
background-color: #DFDFDF;
border-radius: 5px;
}
/* Это общий стиль flex-элементов */
p, span{
width: 200px;
min-width: 50px;
padding: 10px;
margin: auto;
background-color: #55aa55;
border-radius: 5px;
text-align: center;
font-weight: bold;
color: #F9F9F9;
}
.p_normal{
display: block;
width: 480px;
height: auto;
text-align: left;
margin-top: 2em;
}
</style>
</head>
<body>
<div>
<p>1</p><span>2</span><p>3</p>
</div>
<div>
<p style="flex-shrink: 3">1</p>
<span style="flex-shrink: 3">2</span>
<p style="flex-shrink: 3">3</p>
</div>
<div>
<p>1</p><span>2</span>
<p style="width: 250px;">3</p>
</div>
<div>
<p>1</p><span>2</span>
<p style="flex-shrink: 0">3</p>
</div>
<div>
<p style="flex-shrink: 0.5">1</p>
<span style="flex-shrink: 2; width: 300px;">2</span>
<p style="flex-shrink: 6; width: 400px;">3</p>
</div>
<p class="p_normal">
В первом блоке флекс-элементы имеют одинаковый базовый размер
(в нашем случае это ширина) в 200px и коэффициент сжатия равный
1 (установился по умолчанию). Рассчитываем размер свободного
отрицательного пространства флекс-контейнера:
300px - 3*200px - 3*20px = -360px. Находим сумму произведений
базовых размеров флекс-элементов на их коэффициенты сжатия:
200px*1 + 200px*1 + 200px*1 = 600px. Рассчитываем нормированный
коэффициент сжатия каждого флекс-элемента (в нашем случае для всех
элементов будет одинаковое значение): 200px*1/600px = 1/3.
Получаем итоговые размеры наших флекс-элементов (тоже будут
одинаковы): 200px - 360px*(1/3) = 80px.
</p>
<p class="p_normal">
Во втором блоке флекс-элементы также имеют одинаковый базовый
размер (в нашем случае это ширина) в 200px и одинаковый коэффициент
сжатия равный 3. Следовательно они также будут сжиматься полностью
одинаково и будут иметь финальные размеры по 80px (схема та же,
что и в первом блоке).
</p>
<p class="p_normal">
В третьем блоке все флекс-элементы имеют коэффициент сжатия равный
1 (установился по умолчанию), но для третьего флекс-элемента мы
применили встроенный стиль, увеличив его ширину (базовый размер для
нашего случая) до 250px. Рассчитываем размер свободного
отрицательного пространства флекс-контейнера:
300px - 2*200px - 250px - 3*20px = -410px. Находим сумму произведений
базовых размеров флекс-элементов на их коэффициенты сжатия:
200px*1 + 200px*1 + 250px*1 = 650px. Рассчитываем нормированный
коэффициент сжатия каждого флекс-элемента: для первых двух элементов
получаем 200px*1/650px = 4/13, а для третьего - 250px*1/650px = 5/13.
Рассчитываем итоговые размеры наших флекс-элементов: для первого и
второго элементов получаем величину 200px - 410px*(4/13) = 73.85px,
а для третьего - 250px - 410px*(5/13) = 92.31px.
</p>
<p class="p_normal">
В четвертом блоке флекс-элементы имеют различные коэффициенты сжатия
и размеры. Рассчитываем размер свободного отрицательного
пространства флекс-контейнера:
300px - 200px - 300px - 400px - 3*20px = -660px. Находим сумму
произведений базовых размеров флекс-элементов на их коэффициенты
сжатия: 200px*0.5 + 300px*2 + 400px*6 = 3100px. Рассчитываем
нормированный коэффициент сжатия каждого флекс-элемента: для первого
элемента получаем 200px*0.5/3100px = 2/31, для второго -
300px*2/3100px = 6/31, а для третьего - 400px*6/3100px = 24/31.
Рассчитываем итоговые размеры наших флекс-элементов: для первого
элемента получаем величину 200px - 660px*(2/31) = 157.42px, для
второго - 300px - 660px*(6/31) = 172.33px, а для третьего -
400px - 660px*(24/31) = -110.97px.<br><br>
Т.к. итоговый размер третьего флекс-элемента стал меньше допустимого
минимального размера элемента (в нашем случае это «min-width: 50px»),
то ему присваиваем минимальный размер в 50px, а итоговые размеры первых
двух элементов пересчитываем по алгоритму заново, но с учетом того, что
третий элемент как бы имеет базовый размер в 50px и коэффициент сжатия 0.
Итак, рассчитываем размер свободного отрицательного пространства
флекс-контейнера: 300px - 200px - 300px - 50px - 3*20px = -310px.
Находим сумму произведений базовых размеров флекс-элементов участвующих
в сжатии на их коэффициенты сжатия: 200px*0.5 + 300px*2 = 700px.
Рассчитываем нормированный коэффициент сжатия каждого флекс-элемента:
для первого элемента получаем значение 200px*0.5/700px = 1/7, а для
второго - 300px*2/700px = 6/7. Рассчитываем итоговые размеры наших
флекс-элементов: для первого - 200px - 310px*(1/7) = 155.71px, а для
второго - 300px - 310px*(6/7) = 34.29px.<br><br>
Как видим, для второго элемента значение получилось меньше допустимого
минимального, поэтому его ширину также устанавливаем в 50px, а коэффициент
сжатия в 0. Повторяем алгоритм еще раз, но уже для одного оставшегося
первого элемента. Рассчитываем размер свободного отрицательного
пространства флекс-контейнера:
300px - 200px - 50px - 50px - 3*20px = -60px. Находим сумму произведений
базовых размеров флекс-элементов участвующих в сжатии на их коэффициенты
сжатия: 200px*0.5 = 100px. Рассчитываем нормированный коэффициент сжатия
каждого флекс-элемента: 200px*0.5/100px = 1. Рассчитываем итоговый размер
нашего флекс-элемента: 200px - 60px*1 = 140px.
</p>
</body>
</html>
Пример №1