Если значение flex-grow равно нулю, то флекс-элемент «не претендует» на оставшееся свободное место во флекс-контейнере и не будет увеличиваться, чтобы занять это место.
Если значение flex-grow больше нуля, то флекс-элемент будет увеличиваться, «захватывая» оставшееся свободное место.
Получается, что базовый размер — это исходный размер флекс-элементов до применения flex-grow.
Пропорциональное растягивание элементов [8/28]
Если сразу у нескольких флекс-элементов значение flex-grow больше нуля, то они будут делить свободное место между собой.
Свободное место будет добавляться флекс-элементам пропорционально значениям их «коэффициента жадности».Например, если во флекс-контейнере есть два элемента:
.element-1 { flex-grow: 1; }.element-2 { flex-grow: 2; }То второму элементу достанется в два раза больше свободного места, чем первому. Если изменить значения коэффициентов у этих элементов на такие:
.element-1 { flex-grow: 50; }.element-2 { flex-grow: 100; }То ничего не изменится, так как отношение коэффициентов не изменилось: 100 в два раза больше 50. То есть важно не само значение коэффициента, а его соотношение с коэффициентами остальных элементов.
Расчёт итогового размера с flex-grow [9/28]
1 шаг. Рассчитываем свободное место во флекс-контейнере:
Свободное место = Ширина контейнера - Сумма базовых размеров элементов2 шаг. Считаем размер минимальной доли свободного места:
Доля свободного места = Свободное место / Сумма flex-grow всех элементов3 шаг. Базовый размер каждого флекс-элемента увеличиваем на размер минимальной доли свободного места умноженной на значение flex-grow этого элемента:
Итоговый размер = Базовый размер + (Доля свободного места * flex-grow)Для верхнего блока с енотами хочется задать коэффициенты 1 и 2. Но нужные размеры блоков получаются с коэффициентами 1 и 3. Давайте посчитаем:
Свободное место = 300px - (50px * 2) = 200pxДоля свободного места = 200px / (1 + 3) = 50pxИтоговый размер зелёного енота = 50px + (50px * 1) = 100pxИтоговый размер коричневого енота = 50px + (50px * 3) = 200pxНо если задать флекс-элементам нулевой базовый размер, свободное место будет занимать всю ширину флекс-контейнера, и коэффициенты жадности будут другими.
Использовать flex-basis: 0 и flex-grow для точного управления относительными размерами не стоит. Лучше использовать базовый размер в процентах.
Тонкость. На размер оставшегося свободного места влияет не только flex-basis, но и рамки, и отступы. Если flex-basis явно задано нулевое значение, то min-width на размер свободного места влиять не будет, так как ограничения размеров к флекс-элементам применяются уже после перераспределения свободного места.
Коэффициент сжатия элементов, flex-shrink [10/28]
Если сумма базовых размеров флекс-элементов больше, чем размер флекс-контейнера, то возникает отрицательное пространство.
Механизм перераспределения работает не только для свободного места, но и для отрицательного пространства. Флекс-элементы умеют распределять отрицательное пространство между собой и сжиматься.
За уменьшение флекс-элементов отвечает свойство flex-shrink, которое можно назвать «коэффициентом сжатия».
Свойство flex-shrink принимает неотрицательные числовые значения, его значение по умолчанию — 1.
Если значение flex-shrink больше нуля, то флекс-элемент будет уменьшаться, «впитывая» часть отрицательного пространства, если оно существует.
Если значение flex-shrink равно нулю, то флекс-элемент уменьшаться не будет.
Флекс-элементы стараются быть максимально «гибкими» и не выпадать из своего контейнера, поэтому у flex-shrink значение по умолчанию равно 1. Но если задавать нулевые значения для коэффициента сжатия, то выпадения элементов добиться можно.
Пропорциональное сжатие элементов [11/28]
Свойство flex-shrink очень похоже на свойство flex-grow. Оно задаёт пропорции, в которых флекс-элементы «впитывают» отрицательное пространство.
Чем больше значение коэффициента сжатия у элемента, тем больше отрицательного пространства он «впитает» и тем сильнее сожмётся.
Когда базовые размеры флекс-элементов одинаковы, пропорции сжатия элементов считаются так же, как пропорции увеличения. Если базовые размеры флекс-элементов отличаются, то механизм усложняется.
Расчёт итогового размера с flex-shrink[12/28]
Ниже описан механизм расчёта размеров элементов, когда места в контейнере не хватает:
1 шаг. Рассчитываем отрицательное пространство (ОП) во флекс-контейнере:
ОП = Ширина контейнера - Сумма базовых размеров элементов
2 шаг. Находим сумму произведений базовых размеров (СПБР) элементов на их коэффициенты сжатия:
СПБР = (Базовый размер1 * flex-shrink1) + (Базовый размер2 * flex-shrink2) + … + (Базовый размерn * flex-shrinkn)
3 шаг. Для каждого элемента считаем «нормированный коэффициент сжатия» (НКС), для чего произведение базового размера элемента на его коэффициент сжатия делим на СПБР:
НКС = (Базовый размер * flex-shrink) / СПБР
4 шаг. Базовый размер элемента уменьшаем на часть ОП пропорциональную НКС элемента:
Итоговый размер = Базовый размер - (НКС * ОП)
Получается, что доля отрицательного пространства, которую «впитает» элемент, зависит от двух факторов:
· соотношения коэффициента сжатия элемента с коэффициентами других элементов,
· соотношения базового размера элемента с базовыми размерами других элементов.
Именно поэтому в формулах присутствуют нормировки. А теперь снова попробуйте подобрать коэффициенты сжатия.
Есть несколько тонкостей, касающихся сжатия флекс-элементов:
· элементы сжимаются в пределах своих базовых размеров, внутренние отступы и рамки не сжимаются;
· «ограничительные» свойства, такие как min-width, применяются к элементам после этапа перераспределения свободного места или отрицательного пространства.
И эти тонкости могут приводить к неожиданным эффектам, когда элементы выпадают из флекс-контейнера.