Как работает Flex-grow в CSS. Подробное руководство | by Stas Bagretsov
Очень много людей у меня спрашивают как правильно работает flex-grow
и как вообще им оперировать. Это конечно очень хитрое свойство, но если в нём разобраться, то оно не представляет собой ничего сложного, нужно только захотеть и приложить небольшие усилия. К сожалению, в рунете я не нашел достойной статьи, которая рассказывает в деталях про flex-grow
, были только небольшие отрывки по работе с дробями.
Но я нашел статью `flex-grow` is weird. Or is it?, которая максимально ясно показывает то, как работает flex-grow
и то, как он рассчитывается. Ниже будет её перевод на русский язык.
👉Мой Твиттер — там много из мира фронтенда, да и вообще поговорим🖖. Подписывайтесь, будет интересно: ) ✈️
Как только я узнал о flex-grow
, то сразу же сделал простое демо, чтобы посмотреть как оно работает и что вообще делает.
Я думал, что во всём разобрался, но когда я попытался применить его на сайте, который недавно сделал мой коллега, то ничего не заработало так, как ожидалось. Что мы только ни делали, а шаблон всё не выглядел и не работал так, как бы мы хотели в моей демке. Это заставило меня переосмыслить всё, что я до этого знал о flex-grow
.
Перед тем как мы углубимся в функционал flex-grow
, я бы хотел объяснить вам то, что я сделал неверно в первый раз.
Я думал, что все flex элементы с flex-grow
с параметром 1 будут иметь одинаковую ширину. А если один из элементов будет иметь flex-grow
с параметром 2, то этот элемент будет в два раза больше чем другие в этой группе.
Это звучит великолепно. Кажется, что именно так все и происходит в примере указанном выше. Родительский элемент имеет ширину 900px
, секция с flex-grow:2
получает ширину в 600px
, а боковой элемент с flex-grow:1
имеет ширину 300px
.
Как вы видите, в этой демке все работает просто идеально, но это так не работает в реальной жизни, даже если бы мы использовали тот же самый CSS код. Оказывается, что проблема была не в самом с CSS, а в контенте, вернее в его недостатке. Демка, которую я сделал — она работает, да, но только потому что там использовались два пустых элемента, созданные для тестирования и в итоге оказавшиеся слишком простыми для того, чтобы показать все важные моменты этого свойства.
Только что я объяснил как flex-grow
не работает, но я показал вам демо, которое на самом деле не делает то, что по моим утверждениям это не делает. Далее в статье я вам объясню причину этого.
Чтобы прояснить ситуацию, позвольте показать вам еще один Pen. В нём такие же установки, как и в первом, но на этот раз секция и боковые элементы не пустые. Теперь соотношение больше не 2:1 и элемент с flex-grow
выставленным на один больше, чем элемент с flex-grow
на 2.
Если мы применим display:flex
для родительского элемента и ничего больше не поменяем, то дочерние элементы встанут горизонтально, не смотря ни на что. Если будет недостаточно места, то они сократятся в размере. С другой стороны, если будет слишком много места, то они не будут расти, потому что Flexbox хочет, чтобы мы определили насколько им нужно вырасти. Таким образом, прежде чем указывать браузеру каким по ширине должен быть элемент, flex-grow
определяет как оставшееся место распределяется среди flex элементов и насколько велика доля каждого из них.
Или другими словами:
Flex контейнер распределяет свободное место своим элементам, пропорционально их flex-grow
фактору, чтобы заполнить контейнеры или урезать их, пропорционально их flex-shrink
фактору, для того того, чтобы пресечь переполнение контейнера.
#Демонстрация
Эту концепцию гораздо проще понять, если мы её визуализируем.
Во-первых мы выставим display
свойство для нашего родительского элемента на flex и сделав это наши дочерние элементы станут flex-элементами и будут горизонтально расставлены друг за другом.
Далее, мы решаем сколько частей свободного места получит каждый элемент. В нашем предыдущем примере первый элемент получил 2/3 оставшегося места flex-grow:2
и второй элемент 1/3 flex-grow:1
. Зная сколько flex-grow
значений мы можем иметь в сумме, мы будем знать на какое число делить оставшееся место.
Наконец-то у нас есть количество распределяющихся частей. Каждый элемент получает соответствующее количество частей, основываясь на его flex-grow
значении.
#Считаем
Теории и визуальные представления это хорошо, но давайте по пачкаем руки и сделаем математические вычисления для примера выше.
Для наших расчетов понадобится четыре числа: ширина родителя, изначальная ширина секции и бокового элемента и общее количество flex-grow
значений, которые мы будем использовать. Итак, у нас получается:
Ширина родителя: 900px
Ширина секции: 99px
Ширина бокового элемента: 623px
Общее количество flex-grow значений: 3
1. Во первых нам надо рассчитать оставшееся место. Это довольно легко, мы возьмем ширину родителя и вычтем общую ширину изначальных дочерних элементов.
900 — 99 — 623 = 178
2. Далее нам нужно определить размер каждого значения flex-grow
Теперь, когда у нас есть оставшееся место, нам нужно определить на сколько частей мы хотим его разделить. Очень важно понимать, что мы не делим оставшееся место на количество элементов, а делим на общее количество flex-grow
значений. В нашем случае это будет 3 (flex-grow:2
+ flex-grow:1
)
178 / 3 = 59.33
3. Наконец-то разрезанное оставшееся место будет распределено между всеми элементами
Основываясь на их flex-grow
значениях секция получит 2 куска (2*59. 33), а боковая сторона получит 1 кусок (1*59.33). Эти числа добавляются к изначальной ширине каждого элемента.
99 + (2 * 59,33) = 217,66 (~218px) | Изначальная ширина секции + (значение flex-grow
для секции * размер одного flex-grow
)
623 + (1* 59.33) = 682.33 (~682px) | Изначальная ширина боковой стороны + (значение flex-grow
боковой стороны * размер одного flex-grow
)
Теперь вообще легко, правда?
Отлично, но почему сработало первое демо?
У нас есть формула, теперь давайте разберемся почему мы получили нужные результаты в первой демке, даже не понимая как мы это делаем.
Ширина родителя: 900px
Ширина секции: 0px
Ширина бокового элемента: 0px
Общее количество
flex-grow
значений: 3
1. Рассчитываем оставшееся место.
900–0–0 = 900
2. Определяем размер каждого значения flex-grow
900 / 3 = 300
3. Распределяем нарезанное свободное место
0 + (2 * 300) = 600
0 + (1 * 300) = 300
Если ширина каждого элемента равна нулю, то оставшееся место равняется настоящей ширине родительского элемента и поэтому все выглядит так, будто flex-grow
разделяет ширину элемента на равные пропорциональные части.
Давайте быстренько повторим: flex-grow
берет оставшееся место и делит его на общее количество flex-grow
значений. Полученный показатель умножается на соответствующее каждой части значение flex-grow
и полученный результат добавляется каждому дочернему элементу с его изначальной шириной.
Но что поделать, если нет оставшегося места или что делать в том случае, если мы не хотим полагаться на изначальную ширину элемента, но значение flex-grow
надо выставить? Мы что, не можем использовать flex-grow
?
Конечно же можем. Есть такое свойство, которое называется flex-basis
, оно определяет изначальный размер элемента. Если вы используете flex-basis
в связке с flex-grow,
то механизм вычисления ширины изменится.
Этот компонент устанавливает flex-basis
, указывая его flex основу: изначальный главный размер flex элемента, перед тем как свободное пространство будет распределено в соответствии с flex факторами.
Тут большая разница в том, что если мы применим flex-basis
для элемента, то для вычислений мы не будем использовать его изначальный размер, а применим значение свойства flex-basis
.
Я адаптировал наш предыдущий пример, добавив flex-basis
для каждого элемента. Вот он. Давайте посмотрим, как это происходит.
1. Рассчитываем оставшееся место
900–400–200 = 300
2. Определяем ширину элемента flex-grow
300/3= 100
3. Распределяем оставшееся место
400 + (2 * 100) = 600
200 + (1 * 100) = 300
Небольшой оффтоп для завершенности дела, вам не нужно использовать исключительно пиксельные значения и надеяться на лучшее, проценты работают так же хорошо.
Чтобы покрыть вообще все сферы и ситуации, которые случаются с flex-grow
, давайте посмотрим что будет, если мы добавим padding
и margin
. На самом деле ничего особенного. На первом шаге вычислений вам просто нужно не забыть также вычесть внешние отступы.
Единственное, что вам нужно подметить, так это в случае с box-sizing
flex-basis
ведет себя как свойство width
. Это означает то, что вычисления как и результат меняются, если box-sizing
свойство меняется. Если box-sizing
был выставлен на border-box
, то вам надо работать только с flex-basis
и margin
значениями в ваших вычислениях, потому что значение padding
уже включено в ширину.
Несколько полезных примеров
И так, достаточно математики. Давайте посмотрим несколько примеров того, как вы можете эффективно применить flex-grow
в своих проектах.
#Скажи нет width: [x]%
Так как оставшееся место распределяется автоматически, нам не нужно думать о значениях ширины, если мы хотим, чтобы наши дочерние элементы заполняли весь родительский элемент.
#Святой грааль трех колоночного “жидкого” макета с шириной в пикселях
Смеси фиксированных и флюидных широт в column шаблонах возможны с флоатами, но это и не понятно и просто не гибкое решение. Конечно с помощью Flexbox и немного flex-grow
и flex-basis
магии это становится вполне возможным.
#Заполняем оставшееся место любым элементом
Если вы, к примеру, имеете поле ввода прямо за лейблом и хотите, чтобы это поле занимало все оставшееся место, вам больше не нужны убоговатые хаки в верстке. Смотрите.
Прислушиваемся к спецификациям
Следуя спецификации, нам стоит использовать flex сокращения, а не flex-grow
напрямую.
Но будьте аккуратны! Если вы просто будете использовать flex:1;
некоторые из примеров выше не будут работать, потому что значения выставленные для всеобщего удобства не равны дефолтным значениям и это мешает нашим целям.
Если вы хотите использовать flex в нашем случае, то вам нужно определять его параметры вот так:
flex: 2 1 auto;* (<flex-grow> | <flex-shrink> | <flex-basis>) *
Flex-grow
сложный и запутанный? Всё совсем не так плохо, как кажется. Нам нужно просто понять как он работает и что он делает. Если у элемента flex-grow
выставлен на 3, это не означает того, что он будет в три раза больше чем элемент у которого flex-grow
стоит с параметром 1. Это будет означать то, что он получит в три раза больше пикселей к изначальной ширине, чем другой элемент.
Я выучил свой урок, тестируя flex-grow
с двумя пустыми элементами, которые дали мне совершенно другое понимание того, что это свойство делает и это само собой привело меня к неверным заключениям. Вам нужно проверять новые фишки в среде, которая максимально приближена к реальности, тогда вы получите максимально реалистичное понимание того, как это работает и себя ведет.
Управление элементами. flex-basis, flex-shrink и flex-grow ⚡️ HTML и CSS с примерами кода
Кроме свойств, устанавливающих выравнивание элементов относительно границ flex-контейнера, есть еще три свойства, которые позволяют управлять элементами:
flex-basis
: определяет начальный размер flex-элементаflex-shrink
: определяет, как flex-элемент будет уменьшаться относительно других flex-элементов во flex-контейнереflex-grow
: определяет, как flex-элемент будет увеличиваться относительно других flex-элементов во flex-контейнере
flex-basis
Flex-контейнер может увеличиваться или уменьшаться вдоль своей центральной оси, например, при изменении размеров браузера, если контейнер имеет нефиксированные размеры. И вместе с контейнером также могут увеличиваться и уменьшаться его flex-элементы. Свойство flex-basis
определяет начальный размер flex-элемента до того, как он начнет изменять размер, подстраиваясь под размеры flex-контейнера.
Это свойство может принимать следующие значения:
auto
: начальный размер flex-элемента устанавливается автоматическиcontent
: размер flex-элемента определяется по его содержимому, в то же время это значение поддерживается не всеми современными браузерами, поэтому его пока стоит избегатьчисловое значение
: мы можем установить конкретное числовое значение для размеров элемента
Например:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Flexbox в CSS3</title> <style> .flex-container { display: flex; border: 1px #ccc solid; } .flex-item { text-align: center; font-size: 1em; padding: 1.2em; color: white; } .item1 { background-color: #675ba7; flex-basis: auto; width: 150px; } .item2 { background-color: #9bc850; flex-basis: auto; width: auto; } .item3 { background-color: #a62e5c; flex-basis: 200px; width: 150px; } </style> </head> <body> <div> <div>Flex Item 1</div> <div>Flex Item 2</div> <div>Flex Item 3</div> </div> </body> </html>
У первого элемента у свойства flex-basis
установлено значение auto
. Поэтому первый элемент в качестве реального значения для ширины будет использовать значение свойства width
.
У второго элемента у свойства flex-basis
установлено значение auto
, однако и свойство width
имеет значение auto
. Поэтому реальная ширина элемента будет устанавливаться по его содержимому.
У третьего элемента свойство
имеет конкретное значение, которое и используется. А свойство width
в этом случае уже не играет никакой роли.
flex-shrink
Если flex-контейнер имеет недостаточно места для размещения элемента, то дальнейшее поведение этого элемента мы можем определить с помощью свойства flex-shrink
. Оно указывает, как элемент будет усекаться относительно других элементов.
В качестве значения свойство принимает число. По умолчанию его значение 1
.
Рассмотрим действие этого свойства на примере:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Flexbox в CSS3</title> <style> .flex-container { display: flex; border: 1px #ccc solid; width: 400px; } .flex-item { text-align: center; font-size: 1em; padding: 1.2em; color: white; } .item1 { background-color: #675ba7; flex-basis: 200px; flex-shrink: 1; } .item2 { background-color: #9bc850; flex-basis: 200px; flex-shrink: 2; } .item3 { background-color: #a62e5c; flex-basis: 200px; flex-shrink: 3; } </style> </head> <body> <div> <div>Flex Item 1</div> <div>Flex Item 2</div> <div>Flex Item 3</div> </div> </body> </html>
В данном случае начальная ширина каждого элемента равна 200px
, то есть совокупная ширина составляет 600px
. Однако ширина flex-контейнера составляет всего 400px
. То есть размер контейнера недостаточен для вмещения в него элементов, поэтому в действие вступает свойство flex-shrink
, которое определено у элементов.
Для усечения элементов браузер вычисляет коэффициент усечения (shrinkage factor).
flex-basis
на flex-shrink
. Таким образом, для трех элементов мы получим следующие вычисления:// первый элемент 200px * 1 = 200 // второй элемент 200px * 2 = 400 // третий элемент 200px * 3 = 600
Таким образом, мы получаем, что для второго элемента коэффициент усечения в два раза больше, чем коэффициент для первого элемента. А для третьего элемента коэффициент больше в три раза, чем у первого элемента. Поэтому в итоге первый элемент при усечении будет в три раза больше, чем третий и в два раза больше, чем второй.
flex-grow
flex-grow
управляет расширением элементов, если во flex-контейнере есть дополнительное место. Данное свойство во многом похоже на свойство flex-shrink
за тем исключением, что работает в сторону увеличения элементов.В качестве значения свойство flex-grow
принимает положительное число, которое указывает, во сколько раз элемент будет увеличиваться относительно других элементов при увеличении размеров flex-контейнера. По умолчанию свойство
равно 0
.
Итак, используем свойство flex-grow
:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Flexbox в CSS3</title> <style> .flex-container { display: flex; border: 1px #ccc solid; } .flex-item { text-align: center; font-size: 1em; padding: 1.3em; color: white; } .item1 { background-color: #675ba7; flex-grow: 0; } .item2 { background-color: #9bc850; flex-grow: 1; } .item3 { background-color: #a62e5c; flex-grow: 2; } </style> </head> <body> <div> <div>Flex Item 1</div> <div>Flex Item 2</div> <div>Flex Item 3</div> </div> </body> </html>
Итак, для каждого элемента есть базовые начальные размеры. Здесь явным образом размеры для элементов не указаны, поэтому размер каждого элемента в данном случае будет складываться из размеров внутреннего содержимого, к которым добавляются внутренние отступы.
По мере растягивания контейнера будут увеличиваться элементы в соответствии со свойством flex-grow
Так как у первого элемента свойство flex-grow
равно 0
, то первый элемент будет иметь константные постоянные размеры. У второго элемента flex-grow
равно 1
, а третьего — 2
. Таким образом, в сумме они дадут 0 + 1 + 2 = 3
. Поэтому второй элемент будет увеличиваться на 1/3
дополнительного пространства, на которое растягивается контейнер, а третий элемент будет получать 2/3
дополнительного пространства.
Свойство flex
Свойство flex
является объединением свойств
, flex-shrink
и flex-grow
и имеет следующий формальный синтаксис:
flex: [flex-grow] [flex-shrink] [flex-basis];
По умолчанию свойство flex
имеет значение 0 1 auto
.
Кроме конкретных значений для каждого из подсвойств мы можем задать для свойства flex
одно из трех общих значений:
flex: none
: эквивалентно значению0 0 auto
, при котором flex-элемент не растягивается и не усекается при увеличении и уменьшении контейнераflex: auto
: эквивалентно значениюflex: initial
: эквивалентно значению0 1 auto
Так, применим свойство flex:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Flexbox в CSS3</title> <style> .flex-container { display: flex; border: 1px #ccc solid; width: 600px; } .flex-item { text-align: center; font-size: 16px; padding: 10px 0; color: white; } .item1 { background-color: #675ba7; width: 150px; flex: 0 0 auto; } . item2 { background-color: #9bc850; width: 150px; flex: 1 0 auto; } .item3 { background-color: #a62e5c; width: 150px; flex: 0 1 auto; } .item4 { background-color: #2a9fbc; width: 150px; flex: 1 1 auto; } </style> </head> <body> <div> <div>Flex Item 1</div> <div>Flex Item 2</div> <div>Flex Item 3</div> <div>Flex Item 4</div> </div> </body> </html>
Здесь каждый элемент имеет начальную ширину в 150 пикселей, так как у всех элементов свойство flex-basis
имеет значение 0
, что в целом для всех элементов будет составлять 600 пикселей.
При сжатии контейнера будут уменьшаться 3-й и 4-й элементы, так как у них свойство flex-shrink
больше нуля. И так как у обоих элементов это свойство равно 1
, то оба элемента будут уменьшаться в равных долях.
При растяжении контейнера будут увеличиваться 2-й и 4-й элементы, так как у этих элементов свойство flex-grow
больше нуля. И также, так как это свойство равно 1
, то эти элементы будут увеличиваться в равных долях.
См. также
- flex
- flex-basis
- flex-shrink
- flex-grow
Свойство CSS flex-grow
❮ Предыдущий Полное руководство по CSS Далее ❯
Пример
Пусть второй flex-элемент станет в три раза шире остальных:
div:nth-of-type(1) {flex-grow: 1;}
div:nth-of-type (2) {flex-grow: 3;}
div:nth-of-type(3) {flex-grow: 1;}
Попробуйте сами »
Определение и использование
flex-grow
Свойство указывает, насколько элемент будет увеличиваться по сравнению с остальными гибкими элементами внутри того же контейнера.
Примечание: Если элемент не является гибким, свойство flex-grow
не действует.
Показать демо ❯
Значение по умолчанию: | 0 |
---|---|
Унаследовано: | нет |
Анимация: | да. Читать о анимированном Попробуй |
Версия: | CSS3 |
Синтаксис JavaScript: | объект .style.flexGrow=»5″ Попробуй |
Поддержка браузера
Числа в таблице указывают первую версию браузера, которая полностью поддерживает это свойство.
Числа, за которыми следует -webkit- или -moz-, указывают первую версию, которая работала с префиксом.
Собственность | |||||
---|---|---|---|---|---|
flex-grow | 29,0 21,0 -вебкит- | 11,0 | 28,0 18,0 -мунц- | 9. 0 6.1 -вебкит- | 17,0 |
Синтаксис CSS
flex-grow: number |initial|inherit;
Значения свойств
Значение | Описание | Играй |
---|---|---|
номер | Число, указывающее, насколько элемент будет увеличиваться по сравнению с остальными гибкими элементами. Значение по умолчанию 0 | Демонстрация ❯ |
начальный | Устанавливает для этого свойства значение по умолчанию. Читать про начальный | |
унаследовать | Наследует это свойство от родительского элемента. Читать о унаследовать |
Связанные страницы
Учебник по CSS: CSS Flexible Box
Справочник по CSS: свойство flex
Справочник по CSS: свойство flex-basis
Справочник CSS: свойство flex-direction
Справочник CSS: свойство flex-flow
Справочник CSS: свойство flex-shrink
Справочник CSS: свойство flex-wrap
Ссылка HTML DOM: свойство flexGrow
❮ Previous Полное руководство по CSS Следующий ❯
ВЫБОР ЦВЕТА
Лучшие учебники
Учебное пособие по HTMLУчебное пособие по CSS
Учебное пособие по JavaScript
Учебное пособие
Учебное пособие по SQL
Учебное пособие по Python
Учебник по W3. CSS
Учебник по Bootstrap
Учебник по PHP
Учебник по Java
Учебник по C++
Учебник по jQuery
Основные ссылки
HTML ReferenceCSS Reference
JavaScript Reference
SQL Reference
Python Reference
W3.CSS Reference
Bootstrap Reference
PHP Reference
HTML Colors
Java Reference
Angular Reference
jQuery Reference
7 Top8 Examples
Примеры HTML
Примеры CSS
Примеры JavaScript
Примеры инструкций
Примеры SQL
Примеры Python
Примеры W3.CSS
Примеры Bootstrap
Примеры PHP
Примеры Java
Примеры XML
Примеры jQuery
FORUM | О
W3Schools оптимизирован для обучения и обучения. Примеры могут быть упрощены для улучшения чтения и обучения. Учебники, ссылки и примеры постоянно пересматриваются, чтобы избежать ошибок, но мы не можем гарантировать полную правильность всего содержания. Используя W3Schools, вы соглашаетесь прочитать и принять наши условия использования, куки-файлы и политика конфиденциальности.
Copyright 1999-2023 Refsnes Data. Все права защищены.
W3Schools работает на основе W3.CSS.
гибкий рост | CSS-трюки — CSS-трюки
DigitalOcean предоставляет облачные продукты для каждого этапа вашего путешествия. Начните с бесплатного кредита в размере 200 долларов США!
Свойство flex-grow
является подсвойством модуля Flexible Box Layout.
Определяет возможность гибкого элемента увеличиваться при необходимости. Он принимает безразмерное значение, которое служит пропорцией. Он определяет, какое количество доступного пространства внутри гибкого контейнера должен занимать элемент.
.элемент { гибкий рост: 2; }
Например, если для всех элементов flex-grow
установлено значение 1, каждый дочерний элемент будет иметь одинаковый размер внутри контейнера. Если бы вы присвоили одному из дочерних элементов значение 2, этот дочерний элемент занял бы в два раза больше места, чем другие.
Синтаксис
flex-grow: <число>
Демонстрация
Следующая демонстрация показывает, как вычисляется оставшееся пространство в соответствии с различными значениями flex-grow
(см. CodePen для лучшего понимания).
Все элементы имеют flex-grow
значение 1, кроме 3-го, у которого flex-grow
значение 2. Это означает, что когда доступное пространство распределено, 3-й flex-элемент будет иметь вдвое больше места как другие.
Поддержка браузера
IE | EDGE | Firefox | Chrome | Safari | Opera | All | 20+ | 22-28 2 29+ | 7-8 2 9+ | 12. 1+ |
---|
iOS | Chrome Android | Firefox Android | Android | Opera Mobile |
---|---|---|---|---|
7-8.4 2 9+ | 22-28 2 29+ | 90+ | 92+ | 12.1+ |
- 1 Uses the non-standard name
-ms-flex-positive
- 2 Supported with prefix
-webkit-
Браузер Blackberry 10+ поддерживает новый синтаксис.
Для получения дополнительной информации о том, как смешивать синтаксис, чтобы получить наилучшую поддержку браузера, обратитесь к разделу «Использование Flexbox» или этой статье от DevOpera.
Дополнительная информация
- flex-grow в спецификации
- flex-grow на MDN
- Расширенный кроссбраузерный flexbox
- Руководство по Flexbox
Понимание flex-grow, flex-shrink и flex-basis
flexbox
`flex-grow` это странно. Или это?
flexbox
Использование Flexbox: сочетание старого и нового для лучшей поддержки браузера
flexbox
«Старый» Flexbox и «Новый» Flexbox
flexbox
Как заставить ширину и гибкие элементы хорошо сочетаться друг с другом
flexbox
Равные столбцы с Flexbox: это сложнее, чем вы думаете
flexbox
Как сделать адаптивный компонент карты без медиазапросов
flexbox
сгибаться
.элемент { flex: 1 1 100px; }
гибкая основа
.элемент { flex-basis: 100px; }
flex-направление
.element { flex-direction: column-reverse; }
гибкий поток
.element { flex-flow: перенос строки; }