Flex-grow в CSS: как это работает
Flex-grow является CSS-свойством модуля Flexbox, который отвечает за построение гибких макетов. Модель Flexbox (с англ. «гибкая коробка») довольно популярна, отчасти на ее основе создавался когда-то Bootstrap — фреймворк для создания адаптивных дизайнов. В модуле содержится набор свойств. Они назначаются родительским и дочерним элементам для их распределения по всем правилам современной CSS-верстки.
С помощью Flexbox можно решить такие задачи:
- создание одинаковых по высоте колонок;
- создание футера, который будет прижат к низу страницы;
- переопределение порядка вывода элементов;
- распределение элементов справа налево, слева направо, снизу вверх и сверху вниз;
- определение в автоматическом режиме размеров элементов для заполнения свободного пространства;
- центрирование по горизонтали и вертикали.
Flex-grow, как одно из свойств модуля, определяет, какой объем пространства внутри flex-контейнера (родительского элемента) должен занимать элемент. Это свойство всегда зависит от размера других элементов. Идея его использования — в распределении доступного места внутри контейнера.
Например:
- Значение flex-grow = 0
При наличии свободного места элемент (Item) не изменит своих размеров.
- Значение flex-grow = 1
Элемент заполнит свободное пространство и увеличится на 1 значение.
- Значение flex-grow = 2
Поскольку значение flex-grow является относительным, его поведение зависит от значения других элементов одного уровня вложенности в модуле Flexbox.
В этом случае пространство разделяется на три части:
- ⅓ — зеленый элемент;
- ⅔ — красный элемент;
- желтый элемент сохраняет свою первоначальную ширину.
Это говорит о том, что вопреки устоявшемуся мнению, flex-grow не делает элементы равными по ширине.
Ширина каждого элемента рассчитывается на основе своей первоначальной ширины до применения flex-grow.
Flex-grow-свойство определяет коэффициент увеличения гибкого элемента по отношению к другим гибким элементам внутри одного контейнера при условии, что в нем есть свободное пространство.
В гибком контейнере элементы могут быть расположены в любом направлении, они могут изменять собственные размеры: увеличиваться, чтобы заполнить родительский элемент, или уменьшаться, чтобы не выйти за его пределы.
Коэффициент — положительное число. Отрицательные значения не работают.
Flex-grow может иметь 3 значения:
- number — число, которое указывает на то, во сколько раз гибкий элемент увеличится по отношению к другим гибким элементам. Значение по умолчанию — 0;
- inherit — наследует значение свойства от родительского элемента;
- initial — устанавливает свойство в значение по умолчанию — 0.
Давайте рассмотрим пример работы flex-grow.
Пусть в контейнере шириной 500 рх находятся два элемента с шириной сторон 100 рх каждый. Свободных рх в контейнере теперь 300.
Применим значения 2 и 1 к каждому элементу соответственно, тогда ширина первого элемента будет равна 300 рх, а второго — 200 рх. Это значит, что свободное пространство в размере 300 рх распределилось между блоками в соотношении 2:1.
Как flex-grow распределяет свободное пространство между элементами?
Расположение элементов до применения свойства flex-grow:
Найдем ширину блока CSS, где flex-grow для всех элементов равно 1.
Для вычислений воспользуемся формулой:
Ширина = ((значение flex-grow / сумма значений flex-grow) х свободное пространство) + исходная ширина
где:
- значение flex-grow — заданный коэффициент;
- сумма значений flex-grow — сумма всех заданных коэффициентов;
- свободное пространство — свободное место в контейнере до применения свойства flex-grow;
- исходная ширина — ширина элемента до применения свойства flex-grow.
Итак:
Ширина = ((1/1+1+1) х 498) + 77
Ширина элемента CSS равна 241.
Хорошо, а как будет распределяться свободное пространство при условии, что flex-grow имеет разные значения? Flex-grow для CSS блока — 2, Is и Awesome — 1. Найдем ширину все того же элемента CSS.
Ширина = ((2/2+1+1) х 498) + 77
Ширина элемента CSS в этом случае будет равна 326.
Рассмотрим вариант, в котором значение flex-grow элемента CSS равно 0.
Ширина = ((0/0+1+1) х 498) + 77
Ширина элемента CSS равна 77. Это значит, что изначальная ширина блока осталась прежней.
Примечание: значения можно брать как в пикселях, так и в процентах.
Box-модель: flex-grow плюс margin и padding
Как ведет себя flex-grow, если добавить поля и отступы CSS: margin и padding? Margin — отступы за пределами элемента, межблоковое пространство, padding — отступы внутри элемента. Ничего сложного в этом нет, просто учитывайте при вычислении эти отступы и вычитайте их, как в этом примере.
Здесь самое главное не забывать, что при изменении алгоритма расчета ширины и высоты элемента (box-sizing) поведение flex-basis (min-width и max-width) будет полностью идентично свойству width.
То есть как только свойство box-sizing будет претерпевать изменения, результат вычислений будет другим.
При добавлении значения border-box при вычислении во внимание будут браться только margin и flex-basis. Так произойдет, потому что padding уже включен в ширину.
Использование flex-grow в проектах
Без width: [ x ]%
Свободное пространство распределяется автоматически, а значит — нет поводов беспокоиться о ширине, когда родительский элемент заполняется дочерними элементами.
Заполнение оставшегося места в контейнере любым из элементов
Можете использовать этот способ, когда нужно, чтобы поле ввода на странице сайта заполняло оставшееся свободное пространство.
Гибкая трехколоночная раскладка с фиксированными колонками
Flex-grow в сочетании с flex-basis умеет смешивать фиксированную и плавающую ширину в колоночных раскладках.
Использование Flex-grow совместно с flex-basis
Итак, свойство flex-grow делит свободное пространство на общее количество значений. Полученное число умножается на значения каждой из частей flex-grow. Потом это значение добавляется к каждому элементу с дефолтной шириной.
Но представим, что свободного пространства почти не осталось. В этом случае совместно с flex-grow используется другое гибкое свойство flex-basis. Flex-basis определяет изначальный размер элемента. То есть указывается исходный размер flex-элемента, прежде чем распределиться свободное пространство.
Приведем пример с добавленным flex-basis к каждому элементу и произведем его вычисления:
main { display: flex; max-width: 900px; } section { flex-grow: 2; flex-basis: 400px; } aside { flex-grow: 1; flex-basis: 200px; }
Для начала узнаем, сколько свободного пространства осталось в родительском элементе:
900–400–200
Количество свободного пространства равно 300 рх.
Теперь рассчитаем ширину блока. Использовать будем flex-grow:
300/3
Итак, ширина элемента flex-grow равна 100 рх.
Заключительным шагом будет распределение оставшегося свободного пространства:
400 + (2 х 100)
и
200 + (1 х 100)
Значения равны 600 и 300 рх.
В заключение
Коэффициент растягивания элементов flex-grow работает только с гибкими элементами внутри контейнера. Иначе в его использовании нет никакого смысла.
Браузеры, которые поддерживают flex-grow:
Flex-grow поддерживается всеми современными браузерами (с использованием префиксов: IE10+, Edge12+, Firefox 2+, Chrome 4+, Safari 3.1+, Opera 12.1+, iOS Safari 3.2, Opera mini, Android 2.1+, Blackberry 7+).
С помощью этого свойства можно сделать так, чтобы некоторые элементы растягивались в одном контейнере больше, чем все остальные.
Важно понимать, что значение flex-grow равное 1 не означает, что все элементы в контейнере будут иметь одинаковую ширину. Но если одному из элементов назначить flex-grow = 2, то он будет в два раза больше других элементов.
Этому есть свое объяснение. В родительском элементе все дочерние элементы находятся друг за другом в горизонтальном положении. Как только свободного пространства становится мало, элементы автоматически сужаются. Но при достаточном свободном пространстве в контейнере элементы сами по себе не растягиваются — за это отвечает Flexbox. Поэтому flex-grow не сообщает браузеру ширину элементов, а определяет их долю и распределяет свободное место между ними.
Чем выше коэффициент grow, тем больше места будет занято элементом.
Запомните: flex-grow взаимодействует исключительно с пустым пространством.
Например, если в браузере нет свободного места, то распределение ячеек будет осуществляться согласно тому, сколько в них содержимого.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: