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 смотрите в нашем учебнике здесь.
Примеры
<!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