Модуль Flexbox-лейаута (flexible box — «гибкий блок», на данный момент W3C Candidate Recommendation) ставит задачу предложить более эффективный способ вёрстки, выравнивания и распределения свободного места между элементами в контейнере, даже когда их размер неизвестен и/или динамический (отсюда слово «гибкий»).

Главная задумка flex-вёрстки в наделении контейнера способностью изменять ширину/высоту (и порядок) своих элементов для наилучшего заполнения пространства (в большинстве случаев — для поддержки всех видов дисплеев и размеров экранов). Flex-контейнер растягивает элементы для заполнения свободного места или сжимает их, чтобы предотвратить выход за границы.

Самое важное, flexbox-лейаут не зависит от направления в отличие от обычных лейаутов (блоки, располагающиеся вертикально, и инлайн-элементы, располагающиеся горизонтально). В то время, как обычный лейаут отлично подходит для веб-страниц, ему не хватает гибкости (никакого каламбура) для поддержки больших или сложных приложений (особенно когда дело доходит до смены ориентации экрана, изменения размера, растягивания, сжатия и т.п.).

Замечание: Flexbox-лейаут лучше всего подходит для составных частей приложения и мелкомасштабных лейаутов, в то время как Grid-лейаут больше используется для лейаутов большого масштаба.

Основы


Т.к. flexbox — это целый модуль, а не просто единичное свойство, он объединяет в себе множество свойств. Некоторые из них должны применяться к контейнеру (родительскому элементу, так называемому flex-контейнеру), в то время как другие свойства применяются к дочерним элементам, или flex-элементам.

Если обычный лейаут основывается на направлениях потоков блочных и инлайн-элементов, то flex-лейаут основывается на «направлениях flex-потока». Ознакомьтесь с этой схемой из спецификации, разъясняющей основную идею flex-лейаутов.

Flexbox

В основном элементы будут распределяться либо вдоль главной оси (от main-start до main-end), либо вдоль поперечной оси (от cross-start до cross-end).

  • main-axis — главная ось, вдоль которой располагаются flex-элементы. Обратите внимание, она необязательно должна быть горизонтальной, всё зависит от свойства flex-direction (см. ниже).

  • main-start | main-end — flex-элементы размещаются в контейнере от позиции main-start до позиции main-end.
  • main size — ширина или высота flex-элемента в зависимости от выбранной основной величины. Основная величина может быть либо шириной, либо высотой элемента.
  • cross axis — поперечная ось, перпендикулярная к главной. Её направление зависит от направления главной оси.
  • cross-start | cross-end — flex-строки заполняются элементами и размещаются в контейнере от позиции cross-start и до позиции cross-end.
  • cross size — ширина или высота flex-элемента в зависимости от выбранной размерности равняется этой величине. Это свойство совпадает с width или height элемента в зависимости от выбранной размерности.

Свойства

display: flex | inline-flex;

Применяется к: родительскому элементу flex-контейнера.

Определяет flex-контейнер (инлайновый или блочный в зависимости от выбранного значения), подключает flex-контекст для всех его непосредственных потомков.

display: other values | flex | inline-flex; 

Имейте в виду:

  • CSS-столбцы columns не работают с flex-контейнером
  • float, clear и vertical-align не работают с flex-элементами

flex-direction

Применяется к: родительскому элементу flex-контейнера.

Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.

flex-direction: row | row-reverse | column | column-reverse 
  • row (по умолчанию): слева направо для ltr, справа налево для rtl;
  • row-reverse: справа налево для ltr, слева направо для rtl;
  • column: аналогично row, сверху вниз;
  • column-reverse: аналогично row-reverse, снизу вверх.

flex-wrap

Применяется к: родительскому элементу flex-контейнера.

Определяет, будет ли контейнер однострочным или многострочным, а также направление поперечной оси, определяющей направление, в котором будут располагаться новые строки.

flex-wrap: nowrap | wrap | wrap-reverse 
  • nowrap (по умолчанию): однострочный / слева направо для ltr, справа налево для rtl;
  • wrap: многострочный / слева направо для ltr, справа налево для rtl;
  • wrap-reverse: многострочный / справа налево для ltr, слева направо для rtl.

flex-flow

Применяется к: родительскому элементу flex-контейнера.

Это сокращение для свойств flex-direction и flex-wrap, вместе определяющих главную и поперечную оси. По умолчанию принимает значение row nowrap.

flex-flow: <'flex-direction'> || <'flex-wrap'> 

justify-content

Применяется к: родительскому элементу flex-контейнера.

Определяет выравнивание относительно главной оси. Помогает распределить оставшееся свободное место в случае, когда элементы строки не «тянутся», либо тянутся, но уже достигли своего максимального размера. Также позволяет в некотором роде управлять выравниванием элементов при выходе за границы строки.

justify-content: flex-start | flex-end | center | space-between | space-around 
  • flex-start (по умолчанию): элементы сдвигаются к началу строки;
  • flex-end: элементы сдвигаются к концу строки;
  • center: элементы выравниваются по центру строки;
  • space-between: элементы распределяются равномерно (первый элемент в начале строки, последний — в конце);
  • space-around: элементы распределяются равномерно с равным расстоянием между собой и границами строки.

justify-content

align-items

Применяется к: родительскому элементу flex-контейнера.

Определяет поведение по умолчанию для того, как flex-элементы располагаются относительно поперечной оси на текущей строке. Считайте это версией justify-content для поперечной оси (перпендикулярной к основной).

align-items: flex-start | flex-end | center | baseline | stretch 
  • flex-start: граница cross-start для элементов располагается на позиции cross-start;
  • flex-end: граница cross-end для элементов располагается на позиции cross-end;
  • center: элементы выравниваются по центру поперечной оси;
  • baseline: элементы выравниваются по своей базовой линии;
  • stretch (по умолчанию): элементы растягиваются, заполняя контейнер (с учётом min-width/max-width).

align-items

align-content

Применяется к: родительскому элементу flex-контейнера.

Выравнивает строки flex-контейнера при наличии свободного места на поперечной оси аналогично тому, как это делает justify-content на главной оси.

Замечание: это свойство не работает с однострочным flexbox.

align-content: flex-start | flex-end | center | space-between | space-around | stretch 
  • flex-start: строки выравниваются относительно начала контейнера;
  • flex-end: строки выравниваются относительно конца контейнера;
  • center: строки выравниваются по центру контейнера;
  • space-between: строки распределяются равномерно (первая строка в начале строки, последняя — в конце);
  • space-around: строки распределяются равномерно с равным расстоянием между собой;
  • stretch (по умолчанию): строки растягиваются, заполняя свободное пространство.

align-content

order

Применяется к: дочернему элементу / flex-элементу.

По умолчанию flex-элементы располагаются в исходном порядке. Тем не менее, свойство order может управлять порядком их расположения в контейнере.

order: <integer>     

flex-grow

Применяется к: дочернему элементу / flex-элементу.

Определяет для flex-элемента возможность «вырастать» при необходимости. Принимает безразмерное значение, служащее в качестве пропорции. Оно определяет, какую долю свободного места внутри контейнера элемент может занять.

Если у всех элементов свойство flex-grow задано как 1, то каждый потомок получит внутри контейнера одинаковый размер. Если вы задали одному из потомков значение 2, то он заберёт в два раза больше места, чем другие.

flex-grow: <number> (по умолчанию 0) 

Отрицательные числа не принимаются.

flex-shrink

Применяется к: дочернему элементу / flex-элементу.

Определяет для flex-элемента возможность сжиматься при необходимости.

flex-shrink: <number> (default 1) 

Отрицательные числа не принимаются.

flex-basis

Применяется к: дочернему элементу / flex-элементу.

Определяет размер по умолчанию для элемента перед распределением пространства в контейнере.

flex-basis: <length> | auto (default auto)     

flex

Применяется к: дочернему элементу / flex-элементу.

Это сокращение для flex-grow, flex-shrink и flex-basis. Второй и третий параметры (flex-shrink, flex-basis) необязательны. Значение по умолчанию — 0 1 auto.

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] 

align-self

Применяется к: дочернему элементу / flex-элементу.

Позволяет переопределить выравнивание, заданное по умолчанию или в align-items, для отдельных flex-элементов.

Обратитесь к описанию свойства align-items для лучшего понимания доступных значений.

align-self: auto | flex-start | flex-end | center | baseline | stretch 

Примеры

Начнём с очень-очень простого примера, встречающегося практически каждый день: выравнивание точно по центру. Нет ничего проще, если использовать flexbox.

   
.parent { display: flex; height: 300px; /* Или что угодно */ } .child { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! */ }

Этот пример основывается на том, что margin во flex-контейнере, заданный как auto, поглощает лишнее пространство, поэтому задание отступа таким образом выровняет элемент ровно по центру по обеим осям.

Теперь давайте используем какие-нибудь свойства. Представьте набор из 6 элементов фиксированного размера (для красоты), но с возможностью изменения размера контейнера. Мы хотим равномерно распределить их по горизонтали, чтобы при изменении размера окна браузера всё выглядело хорошо (без @media-запросов!).

.flex-container {  /* Сначала создадим flex-контекст */  display: flex;    /* Теперь определим направление потока и хотим ли мы, чтобы элементы   переносились на новую строку  * Помните, что это тоже самое, что и:  * flex-direction: row;  * flex-wrap: wrap;  */  flex-flow: row wrap;    /* Теперь определим, как будет распределяться пространство */  justify-content: space-around; }     

Готово. Всё остальное — уже дело оформления. Ниже размещён CodePen, демонстрирующий этот пример. Обязательно попробуйте растянуть/сжать окно браузера и посмотрите, что произойдёт.

Check out this Pen!

Давайте попробуем что-нибудь ещё. Представьте, что нам нужна выровненная по правому краю навигация в самом верху нашего сайта, но мы хотим, чтобы она выравнивалась по центру для экранов среднего размера и превращалась в один столбец на маленьких. Всё достаточно просто.

/* Большие экраны */ .navigation {  display: flex;  flex-flow: row wrap;  /* Сдвигает элементы к концу строки по главной оси */  justify-content: flex-end; }  /* Экраны среднего размера */ @media all and (max-width: 800px) {  .navigation {  /* Для экранов среднего размера мы выравниваем навигацию по центру,   равномерно распределяя свободное место между элементами */  justify-content: space-around;  } }  /* Маленькие экраны */ @media all and (max-width: 500px) {  .navigation {  /* На маленьких экранах вместо строки мы располагаем элементы в столбце */  flex-direction: column;  } } 
Check out this Pen!

Давайте попробуем кое-что получше и поиграем с гибкостью flex-элементов! Как насчёт ориентированного на мобильные устройства трёхколоночного макета с полноширинной шапкой и подвалом? И другим порядком расположения.

.wrapper {  display: flex;  flex-flow: row wrap; }  /* Задаём всем элементам ширину в 100% */ .header, .main, .nav, .aside, .footer {  flex: 1 100%; }  /* В этом случае мы полагаемся на исходный порядок для ориентации на   * мобильные устройства:  * 1. header  * 2. nav  * 3. main  * 4. aside  * 5. footer  */  /* Экраны среднего размера */ @media all and (min-width: 600px) {  /* Оба сайдбара располагаются в одной строке */  .aside { flex: 1 auto; } }  /* Большие экраны */ @media all and (min-width: 800px) {  /* Мы меняем местами элементы .aside-1 и .main, а также сообщаем  * элементу .main забирать в два раза больше места, чем сайдбары.  */  .main { flex: 2 0px; }    .aside-1 { order: 1; }  .main { order: 2; }  .aside-2 { order: 3; }  .footer { order: 4; } } 
Check out this Pen!

Другие ресурсы

  • Flexbox in the CSS specifications
  • Flexbox at MDN
  • Flexbox at Opera
  • Diving into Flexbox by Bocoup
  • Mixing syntaxes for best browser support on CSS-Tricks
  • Flexbox by Raphael Goetter (FR)
  • Flexplorer by Bennett Feely

frontender.info

Пример 1. Как сделать фотогалерею на Флексбокс

Разместить фотографии по строкам и столбцам на Флексбокс гораздо проще, чем многим кажется.
Рассмотрим простую сетку:

У нас есть main.gallery и 10 изображений в нем.
Убедимся, что main.gallery растягивается на весь доступный экран:

Кое-что об изображениях

По умолчанию все изображения inline-block элементы. У них есть ширина и высота. Они выстроятся в линию (только если они не слишком большие и могут все поместиться)

На старт

Сейчас наша галерея будет выглядеть следующим образом:

А теперь, на сцену выходит Флексбокс:

С этого момента поведение изображений изменилось. Из inline-block элементов они стали flex-items.
В результате применения Флексбокс к .gallery все картинки уместились в одну линию. Да еще и растянулись по вертикали, вот так:

Все это результат стандартного поведения Флексбокс:

  1. Сплющить все дочерние элементы в одну линию и никуда их не переносить. Не самое лучшее решение для галереи, так что изменим его:

    Это разрешит перенос элементов на другую строку как и полагается

  2. Теперь картинки располагаются в несколько линий. Но они все еще растянуты по вертикали и это определенно не характерно для изображений в галерее.
    Свойство align-items флекс-контейнера по умолчанию равно значению stretch

    Изменим его:

    Это защитит картинки от растягивания.
    Кроме того они выровнены относительно начала вертикальной оси:

Наша мощная флексбокс-галерея готова.

Преимущества использования Флексбокс

Сейчас преимущества использования Флексбокс не особо заметны, ведь тот же самый вид был и до его подключения.
Кроме легко получаемой адаптивности, преимущество флексбокс заключается в возможностях выравнивания.
Флекс-контейнер .gallery имеет несколько свойств для настройки выравнивания: flex-direction: row , justify-content: flex-start и align-items: flex-start.
Разметку галереи можно легко поменять поигравшись со следующим значением:

Кроме того, картинки могут быть отцентрованы и по горизонтали и по вертикали .gallery.

Флексбокс предоставляет много вариантов выравнивания. Играйтесь со значениями, как сочтете нужным.

Можете посмотреть на действующую Флексбокс галерею здесь.

Пример 2: Как сделать карточки на Флексбокс

Карточки очень популярны в интернете. Гугл, Твиттер, Пинтерест и прочие им подобные – все используют карточки.
В UI-дизайне карточка – это шаблон, объединяющий схожую информацию в адаптивный контейнер. Внешне он напоминает игральную карту.
Существует много хороших способов применения Карточек. Например, сетка с ценами.

Давайте сделаем такую.

Разметка

Каждая карточка построена следующим образом:

У нас будет как минимум три карточки. Обернем их в div.cards

Теперь у нас есть родственные элементы.
В этом примере родственные элементы будут заполнять вcе доступное окно просмотра

Установка Флексбокс

Следующий код инициализирует Флексбокс в контексте блока .card

Если вы помните предыдущий пример, flex-wrap позволяет элементам flex-items располагаться в несколько линий, если они не помещаются в контейнер. Давайте зададим .card исходную ширину, используя Флексбокс

Это свойство устанавливает значения flex-grow и flex-shrink равными 0. Значение flex-basis будет равным 250px.
В том виде, что у нас есть сейчас карточки будут выровнены относительно начала страницы и растянуты по вертикали

В некоторых случаях это может быть идеальным решением. Но в большинстве случаев – нет.

Поведение флекс-контейнеров по умолчанию

Вид наших карточек является результатом стандартного поведения флекс-контейнеров.
Карточки располагаются в начале страницы (top left) потому что у justify-content установлено значение flex-start.
Кроме того, карточки растянуты на всю высоту родительского элемента, потому что у свойства align-items значение по умолчанию stretch.

Изменение стандартных значений

Мы можем получить впечатляющий результат, изменив стандартные значения флексбокс свойств.
Смотрите сами:

Мы можете посмотреть код примера на Codepen.

Пример 3: Как сделать сетку на Флексбокс

На концепции, которая обсуждается в этом примере, строятся целые CSS-фреймфорки. Так что это очень важно.

Что такое сетка?

Сетка – это набор прямых пересекающихся вертикальных и горизонтальных линий, использующихся для структурирования контента

Если вам знакомы CSS-фреймворки, такие как Bootstrap, то вы точно использовали сетки раньше.

Давайте начнем с базовой сетки

Базовая сетка

Некоторые свойства этой сетки:

  1. Ячейки клетки располагаются равномерно и растянуты по всей ширине линии.
  2. Все ячейки одинаковой высоты.

Этого очень легко добиться, используя Флейксбокс

Каждая строка .row будет флекс-контейнером.
Каждый элемент внутри .row станет флекс-элементом. Все флех-элементы равномерно распределяются по линии.
С точки зрения дизайна не важно, будет ли у нас три вложенных элемента

Или 6:

Или 12:

Решение

Чтобы получить этот результат необходимы всего два шага.

  1. Инициализировать Флексбокс
  2. Каждому flex-item позволить заполнять строку в равных пропорциях

Вот и все.

Объяснение решения

flex – это сокращенное имя свойства, объединяющего в себе flex-grow, flex-shrink и flex-basis.
flex: 1 – установлено только одно значение для свойства и оно задается свойству flex-grow.
flex-shrink и flex-basis будут равны 1 и 0

Ячейки определенного размера

Иногда нам не нужно, чтобы все элементы строки были одинакового размера.
Вам могут понадобиться ячейки вдвое (или в любое другое количество раз) большие чем прочие.

Решение довольно просто.
Для конкретно этой ячейки необходимо изменить класс следующим образом:

Затем включите класс в разметку:

Ячейка с классом .row__cell–2 будет в два раза больше ячейки по умолчанию.

Для ячейки, занимающей треть свободного пространства код будет следующий:

Ячейки с определенным выравниванием

Благодаря Флекбоксу не нужно для каждой ячейки задавать определенное выравнивание, каждая может иметь свое собственное значение

Используйте следующее свойство:

Таким образом определенная ячейка будет выровнена по верху row.

Разумеется, вы должны добавить класс этой особой ячейки в разметку. Взгляните на первый вложенный div разметки:

Ниже приведены другие примеры выравнивания

 

Общее выравнивание внутри строк

Выровнены могут быть не только ячейки, но и все дочерние элементы блока.
Измените класс следующим образом:

Очень важно, чтобы измененный класс .row–top был добавлен элементу row или родительскому флекс-контейнеру.

Ниже приведены другие варианты выравнивания:

 

Вложенные сетки

Без лишних действий элементы row могут быть вложены друг в друга.

Здесь расположены готовые сетки.

Пример 3: Как сделать макет сайта, используя Флексбокс

Строительство макетов полностью на Флексбокс не особо одобряется сообществом разработчиков.
И, разделяя данное мнение, я все же считаю, что бывают ситуации, когда это допустимо.
Самый главный совет, который я могу вам дать: Используйте флексбокс, когда это имеет смысл.
Я объясню это на следующем примере.

Макет сайта “святой Грааль”

Самый наистандартнейший макет страницы на свете

Есть два способа попытаться построить этот макет с помощью Flexbox.
Начнем с первого. Для него нужно разместить во флекс-контейнере header, footer, nav, article и aside.

Разметка

Так выглядит наша разметка:

Среди прочих, в стандартнейшей разметке есть особое правило: центральная колонка, article в разметке должна идти перед обоими сайдбарами nav и aside.

Подключаем флексбокс

Поскольку дочерние элементы должны идти сверху вниз, изменим стандартное направление флексбокс

  1. header и footer должны быть фиксированной ширины
  2. main должен занимать все свободное пространство в контейнере

Надеюсь, вы помните, что запись flex: 1 означает тоже самое что и flex-grow: 1, flex-shrink: 1 и flex-basis: 0

На этом этапе необходимо позаботиться о содержимом main – блоках article, nav и aside.
Сделаем main флекс-контейнером

А для nav и aside установим значение width

Убедимся, что article занимает все доступное ему пространство

Осталось сделать всего одну вещь. Поменяем значения flex-order, чтобы nav отображался первым

Свойство order используется, чтобы переопределить порядок flex-items.
Все элементы flex-items внутри контейнера отображаются в порядке возрастания значения order. Элемент с наименьшим значением будет отображаться первым.
По умолчанию значение order для всех flex-items равно 0.

Второе решение для макета

Предудышее решение использует flex-container для всего контейнера. Макет очень сильно зависит от flexbox.
Посмотрим на более разумный подход. Еще раз взглянем на результат, который должен у нас получиться.

header и footer могут быть блочными элементами. Без лишних вмешательств они и так заполнят все доступное им простанство контейнера и будут прижаты к верху и низу

Что означает, что флекс-контейнер необходим только для main.
Единственная сложность здесь заключается в том, что вам необходимо самим вычислить высоту блока main. Он должен занимать все свободное пространство между header и footer

Рассмотрим этот код. Он использует CSS функцию calc для того, чтобы вычислить высоту main.
Высота блока должна быть равна calc (100vh – высота хэдера – высота футера).
В предыдущем случае вы должны были задать фиксированную высоту футеру и хэдеру. Теперь вы поступаете таким же образом только с main.
Здесь лежит готовый результат.

Макет сайта в 2 колонки

Двухколоночный макет очень распространен. Их тоже очень легко строить на флексбокс.

Вот наша верстка:

Инициализируем флексбокс

Задаем блоку aside фиксированную ширину

И, наконец, убедимся, что main занимает все доступное пространство

Вот, в общем-то, и все, что нужно сделать.

Пример 5. Медиа-объекты на Флексбокс

Медиа-объекты повсюду: от твитов до постов в Фейсбуке.

Внимательно посмотрим на верстку

Как вы догадались, .media станет нашим основным флекс-контейнером

По умолчанию flex-items контейнера растягивается по вертикали, чтобы занять всю доступную высоту.
Убедимся, что .media-body заполняет все свободное пространство

Давайте зафиксируем тянущийся бокс

Вот и все.

Перевернутый медиа-объект

Нет никакой необходимости вносить изменения в html-код, чтобы повернуть медиа-объект.
Просто поменяем местами элементы flex-items вот так:

Теперь картинки будут располагаться после .media-body и media-heading

Вложенные медиа-объекты

Вы можете сделать вложенные медиа-объекты без изменения CSS-стилей, написанных ранее!

Все работает!

Unicode медиа-объекты

Мы не обязаны ограничиваться только картинками.
Без каких-либо изменений в ранее написанных CSS-стилях, вы можете вместо изображения вставить юникод.

Я поместил сюда смайлик

Чтобы получить этот результат мы просто заменили img на div. А вот здесь вы можете подсмотреть юникоды некоторых смайликов-эмодзи.

Медиа-объект с HTML

А еще вы можете использовать html-объекты как в примере ниже

В качестве html-объекта в примере используется ☎ и на картинке вы можете видеть результат

Поэкспериментируйте с этими примерами на CodePen.

Пример 6. Как сделать компоненты форм на Флексбокс

Очень сложно найти сайты, которые не используют формы в том или ином виде

Посмотрим на код

В этом примере представлена комбинация выровненных полей ввода с кнопкой или с текстовым блоком. И вновь, это очень легко сделать при помощи флексбокса.

Инициализируем флексбокс-контекст

Убедимся, что поле занимает все доступное ему пространство

Наконец, по своему желанию, вы можете добавить стили для кнопок и блоков с текстом

Код из этих примеров есть на Codepen.

Пример 7. Как сделать макет мобильного приложения на Флексбокс

В этом примере рассмотрим построение вот такого макета мобильного приложения.

Но этот пример будет немного отличаться от предыдущих. Я объясню процесс построения макета при помощи псевдокода, а вы его сделаете.
Считайте это практикой, чтобы вы не расслаблялись.

Шаг 1.
Отделите макет от картинки iPhone и получите следующее:

Шаг 2.
Определите body как флекс-контейнер.

Шаг 3.
По умолчанию flex-direction контейнера установлен как row. Но в нашем случае, нужен column.

Шаг 4.
Задайте элементам 1 и 3 фиксированные значения высоты height: 50px.

Шаг 5.
Элемент 2 должен занимать все доступное пространство. Используйте свойство flex-grow или короткую запись flex; 1.

Шаг 6.
Наконец, определите каждый блок контента медиа-объектом, как в предыдущем примере.

В результат этих шести шагов у вас получится макет мобильного приложения.

Заключение

По моему опыту работы в UI рано или поздно вы столкнетесь с одним из вышеперечисленных примеров.

А теперь идите и напишите что-нибудь шикарное! ?

Оригинал статьи

keynikell.ru

Базовый макет

Чтобы понять, каково это — создавать макеты на каждой системе, мы сделаем одну и ту же HTML-страницу дважды — один раз с помощью Flexbox, а затем на CSS Grid. Вы можете скачать оба проекта отсюда или проверить их в этой демонстрационной версии.

Уменьшенный макет веб-страницы

Уменьшенный макет веб-страницы

Дизайн довольно простой — он состоит из выровненного по центру контейнера, внутри которого у нас есть шапка, основной раздел, боковая панель и подвал. Вот главные «испытания», которые мы должны провести, сохраняя CSS и HTML по возможности чистыми:

  1. Разместить четыре основных раздела макета.
  2. Сделать страницу адаптивной (боковая панель опускается ниже основного содержимого на маленьких экранах).
  3. Выровнять содержимое шапки — навигация слева, кнопка справа.

Как вы можете видеть, ради сравнения мы оставили всё максимально простым. Начнём с первого испытания.

Испытание 1. Размещение разделов страницы

Решение на Flexbox

Добавляем display: flex к контейнеру и задаём направление дочерних элементов по вертикали. Это позиционирует все разделы друг под другом.

.container {  display: flex;  flex-direction: column; }

Теперь нам нужно сделать так, чтобы основной раздел и боковая панель располагались рядом. Поскольку flex-контейнеры обычно однонаправлены, нам нужно добавить дополнительный элемент.

<header></header> <div class="main-and-sidebar-wrapper">  <section class="main"></section>  <aside class="sidebar"></aside> </div> <footer></footer>

Затем мы устанавливаем этому элементу display: flex и flex-direction с противоположным направлением.

.main-and-sidebar-wrapper {  display: flex;  flex-direction: row; }

Последний шаг — задать размеры основного раздела и боковой панели. Мы хотим, чтобы основное содержимое было в три раза шире боковой панели, что несложно сделать с помощью flex или процентов.

.main {  flex: 3;  margin-right: 60px; } .sidebar {  flex: 1; }

Как вы можете видеть, Flexbox сделал всё хорошо, но нам кроме этого понадобилось довольно много свойств CSS плюс дополнительный элемент HTML. Давайте посмотрим, как будет работать CSS Grid.

Решение на CSS Grid

Существует несколько вариантов использования CSS Grid, но мы воспользуемся синтаксисом grid-template-areas, как наиболее подходящего для наших целей.

Сперва мы определим четыре grid-area, по одному на каждый раздел страницы:

<header></header> <!-- Обратите внимание, что в этот раз нет дополнительных элементов --> <section class="main"></section> <aside class="sidebar"></aside> <footer></footer>
header {  grid-area: header; } .main {  grid-area: main; } .sidebar {  grid-area: sidebar; } footer {  grid-area: footer; }

Теперь мы можем настроить нашу сетку и определить расположение каждой области. Вначале код может показаться довольно сложным, но как только вы познакомитесь с системой сетки, он становится проще для понимания.

.container {  display: grid;    /* Определяем размер и число колонок нашей сетки.   Единица fr работает подобно Flexbox:  колонки делят свободное пространство в строке согласно их значениям.  У нас будет две колонки — первая в три раза больше второй. */  grid-template-columns: 3fr 1fr;    /* Связываем сделанные ранее области с местами в сетке.  Первая строка — шапка.  Вторая строка делится между основным разделом и боковой панелью.  Последняя строка — подвал. */  grid-template-areas:   "header header"  "main sidebar"  "footer footer";   /* Интервал между ячейками сетки будет 60 пикселей */  grid-gap: 60px; }

Вот и всё! Наш макет теперь будет соответствовать указанной выше структуре и мы его настроили так, что нам не придётся иметь дело с margin или padding.

Испытание 2. Делаем страницу адаптивной

Решение на Flexbox

Выполнение этого шага строго связано с предыдущим. Для решения на Flexbox нам придётся изменить flex-direction и отрегулировать margin.

@media (max-width: 600px) {  .main-and-sidebar-wrapper {  flex-direction: column;  }    .main {  margin-right: 0;  margin-bottom: 60px;  } }

Наша страница довольно простая, поэтому в медиа-запросе мало работы, но в более сложном макете придётся много чего переделывать.

Решение на CSS Grid

Поскольку мы уже определили grid-areas, нам просто нужно переопределить их порядок в медиа-запросе. Мы можем использовать ту же настройку колонок.

@media (max-width: 600px) {  .container {  /* Выравнивание областей сетки для мобильного макета */  grid-template-areas:   "header header"  "main main"  "sidebar sidebar"  "footer footer";  } }

Или можем переопределить весь макет с нуля, если считаем, что это решение чище.

@media (max-width: 600px) {  .container {  /* Переделываем сетку в одноколоночный макет */  grid-template-columns: 1fr;  grid-template-areas:   "header"  "main"  "sidebar"  "footer";  } }

Испытание 3. Выравнивание компонентов шапки

Наша шапка включает некоторые ссылки навигации и кнопку. Мы хотим, чтобы навигация была слева, а кнопка справа. Ссылки внутри навигации должны быть выровнены относительно друг друга.

Решение на Flexbox

<header>  <nav>  <li><a href="#"><h1>Logo</h1></a></li>  <li><a href="#">Link</a></li>  <li><a href="#">Link</a></li>  </nav>  <button>Button</button> </header>

Мы уже делали похожий макет на Flexbox в одной из наших старых статей — Простейший способ создания адаптивной шапки. Техника довольно простая:

header {  display: flex;  justify-content: space-between; }

Теперь список навигации и кнопка выровнены правильно. Осталось только разместить пункты внутри <nav> по горизонтали. Проще это сделать с помощью display: inline-block, но поскольку мы собираемся целиком использовать Flexbox, применим решение только для него:

header nav {  display: flex;  align-items: baseline; }

Только две строки! Совсем неплохо. Давайте посмотрим, как с этим справится CSS Grid.

Решение на CSS Grid

Чтобы разделить навигацию и кнопку, мы должны добавить display: grid к header и настроить двухколоночную сетку. Нам также понадобятся две дополнительные строки в CSS, чтобы позиционировать всё на соответствующих границах.

header{  display: grid;  grid-template-columns: 1fr 1fr; } header nav {  justify-self: start; } header button {  justify-self: end; }

Что касается ссылок в одну строку внутри навигации, у нас не получилось сделать это корректно с CSS Grid. Вот как выглядит наша лучшая попытка:

Flex box

Ссылки строчные, но они не могут быть выровнены правильно, поскольку не существует варианта baseline, как у align-items. Мы также должны определить ещё одну вложенную сетку.

header nav {  display: grid;  grid-template-columns: auto 1fr 1fr;  align-items: end;  }

Понятно, что CSS Grid не справилась с этой частью макета, но это и не удивительно — основное внимание уделяется выравниванию контейнеров, а не содержимому внутри них. Эта система не для нанесения последних штрихов.

Выводы

Если вы прочитали статью целиком (а это отличная работа!), выводы не должны вас удивить. На деле нет лучшей системы — и Flexbox и CSS Grid хороши по своему и должны использоваться совместно, а не как альтернатива друг другу.

Для тех из вас, кто перепрыгнул непосредственно к выводам этой статьи (не волнуйтесь, мы тоже так делаем), вот краткий итог сравнения:

  • CSS Grid отлично подходит для создания большой картины. Эта система облегчает управление макетом страницы и даже может иметь дело с нестандартным и асимметричным дизайном.
  • Flexbox отлично подходит для выравнивания содержимого внутри элементов. Используйте эту систему для размещения мелких деталей дизайна.
  • Используйте CSS Grid для двумерных макетов (строк И колонок).
  • Flexbox лучше работает только в одном измерении (со строками ИЛИ с колонками).
  • Нет причин применять только CSS Grid или только Flexbox. Изучайте их и используйте совместно.

htmlbook.ru

Свойства flex-контейнера

flex-direction Определяет направление главной оси. Возможные значения:

  • row – слева направо (по умолчанию);
  • row-reverse – справа налево;
  • column – сверху вниз;
  • column-reverse – снизу вверх.
flex-wrap Определяет многострочность контейнера. Возможные значения:

  • nowrap – flex-элементы выстраиваются в одну строку, если не помещаются в контейнер, то выходят за его границы (по умолчанию);
  • wrap – flex-элементы выстраиваются в несколько строк, если не помещаются в одну;
  • wrap-reverse – похоже на wrap, но перенос происходит снизу вверх.
flex-flow Определяет сразу два параметра: flex-direction и flex-wrap.
Например, flex-flow: column wrap; justify-content Определяет выравнивание элементов по главной оси. Возможные значения:

  • flex-start – flex-элементы прижимаются к началу главной оси (по умолчанию);
  • flex-end – flex-элементы прижимаются к концу главной оси;
  • center – flex-элементы выравниваются по центру главной оси;
  • space-between – flex-элементы распределяются вдоль главной оси, при этом первый элемент прижат к началу оси, а последний — к концу;
  • space-around – flex-элементы распределяются вдоль главной оси, при этом свободное пространство делится поровну между элементами. Но стоит отметить, что промежутки суммируются и расстояние между элементами в два раза больше, чем расстояние между краями контейнера и крайними элементами.

Пример

align-items Определяет выравнивание элементов по поперечной оси. Возможные значения:

  • flex-start – flex-элементы прижимаются к началу поперечной оси (по умолчанию);
  • flex-end – flex-элементы прижимаются к концу поперечной оси;
  • center – flex-элементы выравниваются по центру поперечной оси;
  • baseline – flex-элементы выравниваются по своей базовой линии. Базовая линия – это воображаемая линия, проходящая по нижнему краю символов без учёта свисаний, таких как у букв «д», «р», «ц», «щ»;
  • stretch – flex-элементы растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.
align-content Определяет выравнивание целых строк flex-элементов по поперечной оси. Возможные значения:

  • flex-start – строки flex-элементов прижимаются к началу поперечной оси (по умолчанию);
  • flex-end – строки flex-элементов прижимаются к концу поперечной оси;
  • center – fстроки flex-элементов выравниваются по центру поперечной оси;
  • space-between – строки flex-элементов распределяются вдоль поперечной оси, при этом первая строка прижата к началу оси, а последняя — к концу;
  • space-around – строки flex-элементов распределяются вдоль поперечной оси, при этом свободное пространство делится поровну между строками. Но стоит отметить, что промежутки суммируются и расстояние между строками в два раза больше, чем расстояние между краями контейнера и крайними строками.
  • stretch – строки flex-элементов растягиваются, занимая все доступное место по поперечной оси. Но если для элементов задана высота, то stretch будет проигнорирован.

Пример

Это свойство не работает для однострочного flex-контейнера.

Свойства flex-элементов

order Определяет порядок следования отдельно взятого flex-элемента внутри flex-контейнера. Задается целым числом. По умолчанию равно 0, тогда элементы следуют друг за другом в порядке естественного потока. Значение order задает вес позиции элемента в последовательности, а не абсолютную позицию.

Пример

flex-basis Определяет базовый размер flex-элемента перед распределением пространства в контейнере. Может быть задан в px, %, em и остальных единицах измерения. По сути это своего рода отправная точка, относительно которой происходит растягивание или сжатие элемента. Значение по умолчанию – auto, при этом размер элемента зависит от размера внутреннего контента.

В спецификации CSS Flexible Box Layout Module Level 1 приведена наглядная диаграмма для трех flex-элементов со значениями flex-grow 1, 1, 2 соответственно:

Свойство flex-basis

Пример flex-basis: 0

Пример flex-basis: auto

flex-grow Определяет, какую долю свободного места внутри контейнера добавит к своему базовому размеру flex-элемент. Задается целым числом, служащим пропорцией. По умолчанию равно 0. Если у всех элементов flex-grow: 1, то все они будут одинакового размера. Если одному flex-элементу задать значение 2, то к его базовому размеру добавится в два раза больше, чем к другим.

Пример

flex-shrink Определяет, на сколько в случае недостатка места будет уменьшаться flex-элемент относительно уменьшения соседних элементов внутри flex-контейнера. Задается целым числом, служащим пропорцией. По умолчанию равно 1. Если одному flex-элементу задать значение flex-shrink: 2, то из его базового размера вычтется в два раза больше, чем из других, если контейнер меньше, чем сумма базовых размеров входящих в него элементов.

Пример

flex Определяет сразу три параметра: flex-grow, flex-shrink, flex-basis.
Например, flex: 1 1 200px;
align-self Переопределяет выравнивание, заданное по умолчанию или в align-items, для конкретного flex-элемента. Возможные значения:

  • flex-start – flex-элемент прижимается к началу поперечной оси (по умолчанию);
  • flex-end – flex-элемент прижимается к концу поперечной оси;
  • center – flex-элемент выравнивается по центру поперечной оси;
  • baseline – flex-элемент выравнивается по базовой линии;
  • stretch – flex-элементы растягивается, занимая все доступное место по поперечной оси. Но если задана высота, то stretch будет проигнорирован.

Пример

Особенности применения Flexbox на практике

1. Выравнивание по правому краю

Чтобы прижать заголовок сайта влево, а номер телефона вправо, то заголовку надо задать flex: 1.

.header {  display: flex; } .header .title {  flex: 1; }

Если же по какой-то причине тянуть заголовок на всю ширину нельзя, то блоку с номером телефона надо задать margin-left: auto.

.header {  display: flex; } .header .phone {  margin-left: auto; }

Для наглядности блокам добавлены пунктирные границы.

2. Сжатие блоков с длинными словами

Есть блок, состоящий из названия услуги и номера телефона, по которому ее можно заказать. Описание услуги использует столько пространства, сколько может, а затем переходит на следующую строку.

.serv {  display: flex; } .serv .description {  font-size: 30px; } .serv .call {  margin-left: auto;  width: 120px;  text-align: center;  align-self: center; }

Теперь в описании услуги появляется длинное слово.

Красной границей обозначена ширина смартфона, и если переполнение скрыто (overflow: hidden), то кнопку «Оставить заявку» никто не увидит и заказать услугу не сможет.

Дело в том, что минимальная ширина (min-width) блока description по умолчанию имеет значение auto, что в данном случае равняется ширине слова «пенополистиролбетонных». Значит, flex-элемент не может быть уже, чем это слово.

Решение данной проблемы – указать для flex-элемента нулевую минимальную ширину (min-width: 0). Теперь элемент может быть уже, чем его содержимое. А длинное слово можно просто перенести.

.serv {  display: flex; } .serv .description {  font-size: 30px;  min-width: 0;  word-wrap: break-word; } .serv .call {  margin-left: auto;  width: 120px;  text-align: center;  align-self: center; }

3. Гарантированная ширина

Кнопка «Оставить заявку» по ширине совсем не 120px, как было указано в стилях. Дело в том, что по умолчанию flex-элемент сжимается, если места недостаточно.

Следующие три комбинации разработчики Flexbox посчитали наиболее часто используемыми и присвоили им ключевые слова:

flex: 0 1 auto Элемент сжимается, если места не хватает, но не тянется шире, чем ему надо.
Соответствует flex: initial и является значением по умолчанию.
flex: 1 1 auto Элемент сжимается, если места не хватает и тянется для заполнения всего доступного пространства. Соответствует flex: auto.
flex: 0 0 auto Элемент не меняет свои размеры. Соответствует flex: none.

Итак, чтобы ширина кнопки «Оставить заявку» равнялась именно 120px, надо ей добавить flex: none.

.serv {  display: flex; } .serv .description {  font-size: 30px;  min-width: 0;  word-wrap: break-word; } .serv .call {  margin-left: auto;  width: 120px;  flex: none;  text-align: center;  align-self: center; }


4. Несколько полезных замечаний

Надо не забывать, что:

  • вертикальное выравнивание (vertical-align) не влияет на flex-элемент,
  • для flex-элементов следует полностью избегать использования margin или padding в %,
  • отступы (margin) соседних flex-элементов никогда не объединяются,
  • z-index на flex-элементе работает даже при position: static,
  • для вертикального выравнивания flex-элементов с различным размером шрифта лучше установить align-items: baseline.

htmlweb.ru

Why Flexbox?

For a long time, the only reliable cross browser-compatible tools available for creating CSS layouts were things like floats and positioning. These are fine and they work, but in some ways they are also rather limiting and frustrating.

The following simple layout requirements are either difficult or impossible to achieve with such tools, in any kind of convenient, flexible way:

  • Vertically centering a block of content inside its parent.
  • Making all the children of a container take up an equal amount of the available width/height, regardless of how much width/height is available.
  • Making all columns in a multiple column layout adopt the same height even if they contain a different amount of content.

As you’ll see in subsequent sections, flexbox makes a lot of layout tasks much easier. Let’s dig in!

Introducing a simple example

In this article we are going to get you to work through a series of exercises to help you understand how flexbox works. To get started, you should make a local copy of the first starter file — flexbox0.html from our github repo — load it in a modern browser (like Firefox or Chrome), and have a look at the code in your code editor. You can see it live here also.

You’ll see that we have a <header> element with a top level heading inside it, and a <section> element containing three <article>s. We are going to use these to create a fairly standard three column layout.

Flex box

Specifying what elements to lay out as flexible boxes

To start with, we need to select which elements are to be laid out as flexible boxes. To do this, we set a special value of display on the parent element of the elements you want to affect. In this case we want to lay out the <article> elements, so we set this on the <section> (which becomes a flex container):

section {  display: flex; }

The result of this should be something like so:

Flex box

So, this single declaration gives us everything we need — incredible, right? We have our multiple column layout with equal sized columns, and the columns are all the same height. This is because the default values given to flex items (the children of the flex container) are set up to solve common problems such as this. More on those later.

An aside on the flex model

When elements are laid out as flexible boxes, they are laid out along two axes:

flex_terms.png

  • The main axis is the axis running in the direction the flex items are being laid out in (e.g. as rows across the page, or columns down the page.) The start and end of this axis are called the main start and main end.
  • The cross axis is the axis running perpendicular to the direction the flex items are being laid out in. The start and end of this axis are called the cross start and cross end.
  • The parent element that has display: flex set on it (the <section> in our example) is called the flex container.
  • The items being laid out as flexible boxes inside the flex container are called flex items (the <article> elements in our example).

Bear this terminology in mind as you go through subsequent sections. You can always refer back to it if you get confused about any of the terms being used.

Columns or rows?

Flexbox provides a property called flex-direction that specifies what direction the main axis runs in (what direction the flexbox children are laid out in) — by default this is set to row, which causes them to be laid out in a row in the direction your browser’s default language works in (left to right, in the case of an English browser).

Try adding the following declaration to your section rule:

flex-direction: column;

You’ll see that this puts the items back in a column layout, much like they were before we added any CSS. Before you move on, delete this declaration from your example.

Wrapping

One issue that arises when you have a fixed amount of width or height in your layout is that eventually your flexbox children will overflow their container, breaking the layout. Have a look at our flexbox-wrap0.html example, and try viewing it live (take a local copy of this file now if you want to follow along with this example):

Flex box

Here we see that the children are indeed breaking out of their container. One way in which you can fix this is to add the following declaration to your section rule:

flex-wrap: wrap;

Try this now; you’ll see that the layout looks much better with this included:

Flex boxWe now have multiple rows — as many flexbox children are fitted onto each row as makes sense, and any overflow is moved down to the next line. The flex: 200px declaration set on the articles means that each will be at least 200px wide; we’ll discuss this property in more detail later on. You might also notice that the last few children on the last row are each made wider so that the entire row is still filled.

But there’s more we can do here. First of all, try changing your flex-direction property value to row-reverse — now you’ll see that you still have your multiple row layout, but it starts from the opposite corner of the browser window and flows in reverse.

flex-flow shorthand

At this point it is worth noting that a shorthand exists for flex-direction and flex-wrapflex-flow. So for example, you can replace

flex-direction: row; flex-wrap: wrap;

with

flex-flow: row wrap;

Flexible sizing of flex items

Let’s now return to our first example, and look at how we can control what proportion of space flex items take up. Fire up your local copy of flexbox0.html, or take a copy of flexbox1.html as a new starting point (see it live).

First, add the following rule to the bottom of your CSS:

article {  flex: 1; }

This is a unitless proportion value that dictates how much of the available space along the main axis each flex item will take up. In this case, we are giving each <article> element a value of 1, which means they will all take up an equal amount of the spare space left after things like padding and margin have been set. It is a proportion, meaning that giving each flex item a value of 400000 would have exactly the same effect.

Now add the following rule below the previous one:

article:nth-of-type(3) {  flex: 2; }

Now when you refresh, you’ll see that the third <article> takes up twice as much of the available width as the other two — there are now four proportion units available in total. The first two flex items have one each so they take 1/4 of the available space each. The third one has two units, so it takes up 2/4 of the available space (or 1/2).

You can also specify a minimum size value inside the flex value. Try updating your existing article rules like so:

article {  flex: 1 200px; }  article:nth-of-type(3) {  flex: 2 200px; }

This basically states «Each flex item will first be given 200px of the available space. After that, the rest of the available space will be shared out according to the proportion units.» Try refreshing and you’ll see a difference in how the space is shared out.

Flex box

The real value of flexbox can be seen in its flexibility/responsiveness — if you resize the browser window, or add another <article> element, the layout continues to work just fine.

flex: shorthand versus longhand

flex is a shorthand property that can specify up to three different values:

  • The unitless proportion value we discussed above. This can be specified individually using the flex-grow longhand property.
  • A second unitless proportion value — flex-shrink — that comes into play when the flex items are overflowing their container. This specifies how much of the overflowing amount is taken away from each flex item’s size, to stop them overflowing their container. This is quite an advanced flexbox feature, and we won’t be covering it any further in this article.
  • The minimum size value we discussed above. This can be specified individually using the flex-basis longhand value.

We’d advise against using the longhand flex properties unless you really have to (for example, to override something previously set). They lead to a lot of extra code being written, and they can be somewhat confusing.

Horizontal and vertical alignment

You can also use flexbox features to align flex items along the main or cross axis. Let’s explore this by looking at a new example — flex-align0.html (see it live also) — which we are going to turn into a neat, flexible button/toolbar. At the moment you’ll see a horizontal menu bar, with some buttons jammed into the top left hand corner.

Flex box

First, take a local copy of this example.

Now, add the following to the bottom of the example’s CSS:

div {  display: flex;  align-items: center;  justify-content: space-around; }

Refresh the page and you’ll see that the buttons are now nicely centered, horizontally and vertically. We’ve done this via two new properties.

align-items controls where the flex items sit on the cross axis.

  • By default, the value is stretch, which stretches all flex items to fill the parent in the direction of the cross axis. If the parent hasn’t got a fixed width in the cross axis direction, then all flex items will become as long as the longest flex items. This is how our first example got equal height columns by default.
  • The center value that we used in our above code causes the items to maintain their intrinsic dimensions, but be centered along the cross axis. This is why our current example’s buttons are centered vertically.
  • You can also have values like flex-start and flex-end, which will align all items at the start and end of the cross axis respectively. See align-items for the full details.

You can override the align-items behavior for individual flex items by applying the align-self property to them. For example, try adding the following to your CSS:

button:first-child {  align-self: flex-end; }

Have a look at what effect this has, and remove it again when you’ve finished.

justify-content controls where the flex items sit on the main axis.

  • The default value is flex-start, which makes all the items sit at the start of the main axis.
  • You can use flex-end to make them sit at the end.
  • center is also a value for justify-content, and will make the flex items sit in the center of the main axis.
  • The value we’ve used above, space-around, is useful — it distributes all the items evenly along the main axis, with a bit of space left at either end.
  • There is another value, space-between, which is very similar to space-around except that it doesn’t leave any space at either end.

We’d like to encourage you to play with these values to see how they work before you continue.

Ordering flex items

Flexbox also has a feature for changing the layout order of flex items, without affecting the source order. This is another thing that is impossible to do with traditional layout methods.

The code for this is simple: try adding the following CSS to your button bar example code:

button:first-child {  order: 1; }

Refresh, and you’ll now see that the «Smile» button has moved to the end of the main axis. Let’s talk about how this works in a bit more detail:

  • By default, all flex items have an order value of 0.
  • Flex items with higher order values set on them will appear later in the display order than items with lower order values.
  • Flex items with the same order value will appear in their source order. So if you have four items with order values of 2, 1, 1, and 0 set on them respectively, their display order would be 4th, 2nd, 3rd, then 1st.
  • The 3rd item appears after the 2nd because it has the same order value and is after it in the source order.

You can set negative order values to make items appear earlier than items with 0 set. For example, you could make the «Blush» button appear at the start of the main axis using the following rule:

button:last-child {  order: -1; }

Nested flex boxes

It is possible to create some pretty complex layouts with flexbox. It is perfectly ok to set a flex item to also be a flex container, so that its children are also laid out like flexible boxes. Have a look at complex-flexbox.html (see it live also).

Flex box

The HTML for this is fairly simple. We’ve got a <section> element containing three <article>s. The third <article> contains three <div>s. :

section - article  article  article - div - button   div button  div button  button  button

Let’s look at the code we’ve used for the layout.

First of all, we set the children of the <section> to be laid out as flexible boxes.

section {  display: flex; }

Next, we set some flex values on the <article>s themselves. Take special note of the 2nd rule here — we are setting the third <article> to have its children laid out like flex items too, but this time we are laying them out like a column.

article {  flex: 1 200px; }  article:nth-of-type(3) {  flex: 3 200px;  display: flex;  flex-flow: column; } 

Next, we select the first <div>. We first use flex:1 100px; to effectively give it a minimum height of 100px, then we set its children (the <button> elements) to also be laid out like flex items. Here we lay them out in a wrapping row, and align them in the center of the available space like we did in the individual button example we saw earlier.

article:nth-of-type(3) div:first-child {  flex:1 100px;  display: flex;  flex-flow: row wrap;  align-items: center;  justify-content: space-around; }

Finally, we set some sizing on the button, but more interestingly we give it a flex value of 1 auto. This has a very interesting effect, which you’ll see if you try resizing your browser window width. The buttons will take up as much space as they can and sit as many on the same line as they can, but when they can no longer fit comfortably on the same line, they’ll drop down to create new lines.

button {  flex: 1 auto;  margin: 5px;  font-size: 18px;  line-height: 1.5; }

Cross browser compatibility

Flexbox support is available in most new browsers — Firefox, Chrome, Opera, Microsoft Edge and IE 11, newer versions of Android/iOS, etc. However you should be aware that there are still older browsers in use that don’t support Flexbox (or do, but support a really old, out-of-date version of it.)

While you are just learning and experimenting, this doesn’t matter too much; however if you are considering using flexbox in a real website you need to do testing and make sure that your user experience is still acceptable in as many browsers as possible.

Flexbox is a bit trickier than some CSS features. For example, if a browser is missing a CSS drop shadow, then the site will likely still be usable. Not supporting flexbox features however will probably break a layout completely, making it unusable.

We discuss strategies for overcoming cross browser support issues in our Cross browser testing module.

Summary

That concludes our tour of the basics of flexbox. We hope you had fun, and will have a good play around with it as you travel forward with your learning. Next we’ll have a look at another important aspect of CSS layouts — CSS Grids.

developer.mozilla.org