Тарифы Услуги Сим-карты

CSS Grid и Flexbox: сравнение на практике. Что такое Flexbox? Описание всех css свойств, основные принципы, преимущества и недостатки

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

Для чего нужен Flexbox?

Разработчики на протяжении долгого времени использовали таблицы, float-элементы, inline-block и другие CSS свойства, чтобы придать блокам нужное расположение. Однако ни один из вышеперечисленных инструментов не был предназначен для создания сложных страниц и приложений, которые в настоящее время используются почти в каждом проекте. Простые вещи, как вертикальное центрирование, осуществлялись достаточно сложно. Создание же макета на основе жидких сеток вообще считается верхом профессионализма, вот почему широкое распространение получили CSS-фреймворки на основе сеток. Итак, если множество проектов часто используют жидкие сетки, блоки одинаковой высоты, вертикальное центрирование блоков и т.д., то возникает вопрос: "Почему до сих пор нет свойства, которе позволило бы осуществлять эти вещи быстро и просто?"

Целью Flexbox является решение всех этих проблем!

Статус спецификации и поддержка браузерами

Модель flexbox разрабатывается уже четвёртый год. Браузеры используют разные экспериментальные версии спецификации. В сентябре 2012 года 3-я проверка ситаксиса Flexbox группой разработчиков из W3C достигла статуса W3C Candidate. Это означает, что W3C утверждает текущий синтаксис и даёт добро на использование вендорных префиксов браузерами.

История изменений спецификации по Flexbox:

  • Июль 2009 Working Draft (display: box;)
  • Март 2011 Working Draft (display: flexbox;)
  • Ноябрь 2011 Working Draft (display: flexbox;)
  • Март 2012 Working Draft (display: flexbox;)
  • Июнь 2012 Working Draft (display: flex;)
  • Сентябрь 2012 Candidate Recommendation (display: flex;)

Браузеры получили быструю поддержку Flexbox. Chrome 22+, Opera 12.1+, IE10, Firefox >=16 уже поддерживают Flexbox. Я рекомендую использовать один из этих браузеров для просмотра примеров.

Концепция и терминология

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

Модель Flexbox включает в себя flex-контейнер (flex container) и flex-пункты (flex items). Flex container должен иметь свойство display со значением flex или inline-flex . Со значением flex контейнер представляет из себя блочный элемент, а с inline-flex - строчный (инлайновый).

Пример объявления flex container:

Flex-container { display: -webkit-flex; display: flex; }

Flex container является родителем по отношению к flex items. Flex-пунктов может быть сколько угодно. Всё что находится вне flex-контейнера и внутри flex-пунктов отображается как обычно. Таким образо, Flexbox определяет, как flex-пункты будут расположены внутри flex-контейнера.

Flex items расположены внутри flex container вдоль flex line (flex линии). По умолчанию во flex-контейнере присутствует только одна flex-линия. Вот пример с двумя пунктами, расположенными по умолчанию вдоль flex-линии слева направо:

Flex-container{ display: -webkit-flex; display: flex; width: 700px; background-color: green; margin: 20px auto; } .flex-item{ background-color: red; width: 100px; height: 100px; margin: 5px; color: #fff; }

Writing modes (режимы отображения содержимого)

Важной частью настройки flexbox является изменение направления flex-линии. По умолчанию направление flex-линии совпадает с направлением текста: слева направо, сверху вниз.

В спецификации появился новый модуль writing modes. Он позволяет менять направление текста справа налево, или даже вертикально.

Данный модуль находтся в стадии разработки, но Chrome поддерживает CSS свойство direction. Если в предыдущем примере установить свойство direction: rtl (справа налево), то изменится не только направление отображения содержимого справа налево, но и direction flex-линии, что приведет к изменению макета.

Body { direction: rtl; } .flex-container { display: -webkit-flex; display: flex; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }

Из данного примера можно сделать вывод, почему терминология Flexbox на данный момент настолько абстрактна. Нельзя просто указать “вправо”, “влево”, “вниз”, “вверх” когда мы не имеем понятия на каком языке написана данная страница (возможно на арабском - стиль письма справа налево!).

Главная и поперечная оси

Чтобы не зависеть от режима отображения содержимого direction, Flexbox использует концепцию главной оси и поперечной оси (Main Axis и Cross Axis). Flex-линия следуют по главной оси. Поперечная ось перпендикулярна главной оси. Имена начальных и конечных точек, а также направления каждой оси:

  • Main Start
  • Main End
  • Main Direction (иногда называется Flow Direction)
  • Cross Start
  • Cross End
  • Cross Direction

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

Свойства Flex контейнера:

Flex-direction

Свойство flex-direction позволяет менять оси flex-контейнера. По умолчанию свойство flex-direction имеет значение row. В этом случае flex-пункты располагаются в соответствии с режимом writing-mode. Еще раз напомним, что это означает направление слева направо, сверху вниз (по умолчанию).

Другие возможные значения:

  • row-reverse : Main Start И Main End меняются местами. Если даже writing-mode указан ltr (слева налево), то flex-пункты все равно будут расположены справа налево.
  • column : Главная ось и поперечная ось меняются местами. Если режим отображения содержимого горизонтальный, то flex-пункты все равно будут располагаться вертикально.
  • column-reverse : аналогично column только обратный.

Изменим в предыдущем примере свойство flex-direction на column :

Flex-container { display: -webkit-flex; display: flex; -webkit-flex-direction: column; flex-direction: column; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }

Теперь flex-пункты располагаются вертикально.

justify-content

justify-content регулирует расположение flex-пунктов по главной оси. Возможные значения:

  • flex-start (по умолчанию)
  • flex-end
  • center
  • space-between
  • space-around

Рассмотрим пример с justify-content: center чтобы flex-пункты центрировались по главной оси:

Flex-container { display: -webkit-flex; display: flex; -webkit-justify-content: center; justify-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }

flex-start , flex-end , и center работают, соединившись вместе по главной оси. А вот space-between и space-around распределяют свободное пространство между flex-пунктами определённым способом. Приведу диаграмму из спецификации, которая показывает распределение justify-content :

align-items

align-items является дополнительным свойством к justify-content . align-items регулирует отображение flex-пунктов относительно перпендикулярной оси. Возможные значения:

  • flex-start (по умолчанию)
  • flex-end
  • center
  • baseline
  • stretch

Рассмотрим примение свойства align-items:center , которе позволяет flex-пункты вертикально центрировать относительно перпендикулярной оси:

Flex-container { display: -webkit-flex; display: flex; -webkit-align-items: center; align-items: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; }

Итак, flex-start , flex-end , и center всегда располагаются соединившись вместе. Значение stretch довольно простое: оно заставляет flex-пункты растягиваться от Cross Start до Cross End, то есть по вертикали относительно flex-контейнера. baseline заставляет flex-пункты располагаться по базовой линии. Базовая линия вычисляется исходя из инлайнового содержимого flex-пунктов. Вот лучшее объяснение работы данных значений:

Flex-wrap

Во всех рассмотренных примерах flex-контейнер имел одну flex-линию. Использование свойства flex-wrap позволит создать flex-контейнер с разным количеством flex-линий. Возможные значения:

  • nowrap (по умолчанию)
  • wrap-reverse

Если во flex-wrap установлено значение wrap , то во flex-пункты включаются дополнительные flex-линии, но только в том случае, если flex-пунктам не хватает пространства для расположения на одной flex-линии. Дополнительные flex-линии добавляются в направлении перпендикулярной оси.

Пример использования flex-wrap :

Flex-container { display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 300px; height: 100px; margin: 5px; }

Значение wrap-reverse аналогично значению wrap за исключением того, что новые flex-линии добавляются в обратном направлении по перпендикулярной оси.

align-content

align-content изменяет поведение свойства flex-wrap . Это значение аналогично align-items только вместо выравнивания flex-пунктов, оно выравнивает flex-линии. Как и можно было ожидать, значения аналогичные:

  • stretch (по умолчанию)
  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

Принцип работы этих значений аналогичный justify-content и align-items .

Пример align-content: center

flex-flow

Данное свойство компонует в себя свойства flex-direction и flex-wrap .

flex-flow:

Flex-container { -webkit-flex-flow: column nowrap; flex-flow: column nowrap; }

Свойства flex-пунктов (flex items)

Flex-пункт является дочерним блоком по отношению к flex-контейнеру. Содержимое flex-контейнера относится к flex-пункту этого контейнера. Содержимое flex-пункта отображается как обычно. Например, пока действует свойство float, flex-пункты никак на это не реагируют. Плавающие также могут находиться внутри самого flex-пункта.

Как говорят, flex-пункты имеют Main Size и Cross Size. Main Size – это размер flex-пункта в направлении главной оси, а Cross Size - в направлении поперечной оси. Фактически, шириной или высотой flex-пункта могут быть Main Size и Cross Size в зависимости от оси flex-контейнера.

Рассмотрим свойства, которые регулируют поведение flex-пунктов.

Order

Order является простейшим свойством. Порядок расположения flex-пунктов обеспечивается расположением flex-пунктов в HTML. В этом примере мы изменим значение свойства order одного flex-пункта на -1 и посмотрим, как при этом поменяется порядок расположения других flex-пунктов.

Flex-container { display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 300px; height: 100px; margin: 5px; } .first { -webkit-order: -1; order: -1; }

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

Margin

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

Например, объявим margin-right: auto; для первого flex-пункта, при этом он предоставит всё возможное свободное пространство справа от себя:

Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; } .flex-item:first-child{ margin-right: auto; }

Теперь посмотрим на примере как работает margin: auto

Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; height: 100px; margin: 5px; } .flex-item:first-child{ margin: auto; }

align-self

Свойство align-self пункта служит для перекрытия свойства align-items flex-контейнера. Возможные значения аналогичные align-items :

  • stretch (по умолчанию)
  • flex-start
  • flex-end
  • center
  • baseline

В этом примере мы назначим пунктам различные значения свойства align-self:

Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-align-self: flex-start; align-self: flex-start; } .item2 { -webkit-align-self: flex-end; align-self: flex-end; } .item3 { -webkit-align-self: center; align-self: center; } .item4 { -webkit-align-self: baseline; align-self: baseline; } .item5 { -webkit-align-self: baseline; align-self: baseline; padding: 2em 0; } .item6 { -webkit-align-self: stretch; align-self: stretch; }

flex

Наконец-то мы дошли до свойства flex во Flexbox. Flex определяет,как flex-пункты будут использовать свободное пространство по главной оси. Рассмотрим каждое из возможных значений.

Flex:

Такой синтаксис указывает какую часть должен занимать flex-пункт от общей ширины flex-контейнера. В следующем примере первый flex-пункт будет занимать 2/4 свободного места, а остальные два flex-пункта по 1/4:

Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-flex: 2; flex: 2; } .item2 { -webkit-flex: 1; flex: 1; } .item3 { -webkit-flex: 1; flex: 1; }

Часто приходится равномерно распределять элементы по ширине. Для этого достаточно задать значение данного свойства 1 и все flex-пункты распределятся по ширине контейнера.

Flex-container { display: -webkit-flex; display: flex; -webkit-align-content: center; align-content: center; width: 700px; height: 240px; background-color: green; margin: 10px auto; } .flex-item { background-color: red; width: 100px; min-height:70px; margin: 5px; } .item1 { -webkit-flex: 1; flex: 1; } .item2 { -webkit-flex: 1; flex: 1; } .item3 { -webkit-flex: 1; flex: 1; }

flex: initial

Flex-пункты с данным значением будет иметь строго фиксированную ширину, но только при наличии свободного пространства (при необходимости уменьшиться в размере - становится резиновым).

flex: auto

Flex-пункты становятся полностью резиновыми вдоль главной оси. Не корректно работает в Chrome 23.0.1271.95, поэтому лучше использовать flex: 1 .

flex: none

flex-пункты становятся фиксированной ширины при всех ситуациях

advanced flex

Свойство flex можно использовать в режиме сокращения для придания спецефичности выбора flex-grow , flex-shrink , и flex-basis в одном объявлении: flex:

В большинтсве случаев не требуется такой синтаксис. Более того, для применения данного сокращения необходимо глубокое понимание модели Flexbox. Вы можете сделать каждое из свойств flex-grow , flex-shrink , и flex-basis специфичным. Я настоятельно рекомендую не использовать данное сокращение: по умолчанию придаются более разумные значения.

visibility

Когда реализуется свойство visibility: collapse; оно будет отличаться от значений visibility: hidden; и display: none; для flex-пунктов. Со значением collapse элемент задействует Cross Size flex-контейнера, но затрагивать пространство главной оси не будет. Это может быть полезным для динамического добавления или удаления flex-пунктов без оказания влияния на Cross Size flex-контейнера.

В настоящее время visibility: collapse; не коррексно работает в браузерах. На данный момент visibility: collapse; выполняет тоже самое что и visibility: hidden; Я уверен, что в ближайшее время ситуация изменится.

Посмотреть, как должно работать значение collapse в спецификации (http://www.w3.org/TR/css3-flexbox/#visibility-collapse)

Заключение

Как вы понимаете, Flexbox представляет мощное средство конструирования макетов. Он требует совершенно нового подхода для отображения блоков. Надеюсь, эта статья стала полезной для вас и вы сможете уже сейчас начать экспериментировать с макетами с помощью Flexbox. Будущее этой модели действительно потрясающее.

Если говорить коротко, то верстка с Flexbox дает нам простые решения некогда непростых задач. Например, когда нужно выровнять элемент по вертикали, или прижать подвал к низу экрана, или просто вставить несколько блоков в один ряд, так чтобы они занимали все свободно пространство. Подобные задачи решаются и без flex. Но как правило, эти решения больше похожи на «костыли» - приемы использовать css не по назначению. Тогда как с flexbox такие задачи решаются именно так, как задумывает flex-модель.

CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), коротко flexbox, создана, чтобы убрать недостатки при создании самых разных HTML конструкций, в том числе адаптированных под разную ширину и высоту, и сделать верстку логичной и простой. А логичный подход, как правило работает в неожиданных местах, там где результат не проверялся - логика наше все!

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

Базовые знания

FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).

Для включения flexbox, любому HTML элементу достаточно присвоить css свойство display:flex; или display:inline-flex; .

1
2

После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси. По умолчанию главная ось горизонтальная и имеет направление слева направо (>), а кросс ось соответственно вертикальная и направлена сверху вниз (v).

Главную и кросс оси можно поменять местами, тогда элементы будут располагаться сверху вниз (v) и когда перестанут вмещаться в высоту то будут двигаться слева направо (>) - то есть оси просто поменялись местами. При этом начало и конец расположения элементов не меняется - меняются только направления (оси)! Именно поэтому нужно представлять себе оси внутри контейнера. Однако не нужно думать, что есть какие-то там «физические» оси и они на что-то влияют. Ось тут - это только лишь направление движения элементов внутри контейнера. Например, если мы указали выравнивание элементов по центру основной оси и потом изменили направление этой основной оси, то изменится и выравнивание: элементы были в середине по горизонтали, а стали в середине по вертикали... См. пример.

Еще одной важной особенностью Флекс-бокс является наличие рядов в поперечном направлении. Чтобы их представить и понять, давайте представим: есть главная горизонтальная ось, много элементов и они не «лезут» в контейнер, поэтому переходят на другой ряд. Т.е. контейнер выглядит так: контейнер, внутри него два ряда, в каждом ряду по несколько элементов. Представили? А теперь запомните, что выравнивать мы можем не только элементы, но и ряды! Как это работает хорошо видно в примере к свойству . А вот так это выглядит схематически:

CSS свойства, которые могут влиять на модель построения макета: float , clear , vertical-align , columns не работают во flex конструкции - там используется другая модель построения макета и эти css свойства просто игнорируются...

CSS свойства Flexbox

Flexbox содержит разные css правила для управления всей flex конструкцией. Одни нужно применять к основному контейнеру, а другие к элементам этого контейнера.

Для контейнера

display:

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

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

flex и inline-flex отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block .

flex-direction:

Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.

  • row (default) - направление элементов слева направо (>)
  • column - направление элементов сверху вниз (v)
  • row-reverse - направление элементов справа налево (<)
  • column-reverse - направление элементов снизу вверх (^)
flex-wrap:

Управляет переносом непомещающихся в контейнер элементов.

  • nowrap (default) - вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет.
  • wrap - включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси.
  • wrap-reverse - тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).
flex-flow: direction wrap

Объединяет оба свойства flex-direction и flex-wrap . Они часто используются вместе, поэтому чтобы писать меньше кода было создано свойство flex-flow .

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

/* только flex-direction */ flex-flow: row; flex-flow: row-reverse; flex-flow: column; flex-flow: column-reverse; /* только flex-wrap */ flex-flow: nowrap; flex-flow: wrap; flex-flow: wrap-reverse; /* сразу оба значения: flex-direction и flex-wrap */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse; justify-content:

Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.

  • flex-start (default) - элементы будут идти с начала (в конце может остаться место).
  • flex-end - элементы выравниваются по концу (место останется в начале)
  • center - по центру (место останется слева и права)
  • space-between - крайние элементы прижимаются к краям (место между элементами распределяется равномерно)
  • space-around - свободное пространство равномерно распределяется между элементами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
  • space-evenly
align-content:

Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что justify-content только для противоположной оси.

Т.е. если flex-direction: row , то это свойство будет выравнивать невидимые ряды по вертикали (¦). Тут важно заметить, что высота блока должна быть задана жестко и должна быть больше высоты рядов иначе сами ряды будут растягивать контейнер и любое их выравнивание теряет смысл, потому что между ними нет свободного места... А вот когда flex-direction: column , то ряды движется по горизонтали (>) и ширина контейнера почти всегда больше ширины рядов и выравнивание рядов сразу приобретает смысл...

Это свойство мало где нужно и чаще используется align-items (см.ниже).

  • stretch (default) - ряды растягиваются заполняя строку полностью
  • flex-start - ряды группируются в верхней части контейнера (в конце может остаться место).
  • flex-end - ряды группируются в нижней части контейнера (место останется в начале)
  • center - ряды группируются по центру контейнера (место останется по краям)
  • space-between - крайние ряды прижимаются к краям (место между рядами распределяется равномерно)
  • space-around - свободное пространство равномерно распределяется между рядами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
  • space-evenly - тоже что space-around , только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
align-items:

Выравнивает элементы по поперечной оси внутри ряда (невидимой строки). Т.е. сами ряды выравниваются через align-content , а элементы внутри этих рядов (строк) через align-items и все это по поперечной оси. По главной оси такого разделения нет, там нет понятия рядов и элементы выравниваются через justify-content .

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

Для элементов контейнера

flex-grow:

Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию flex-grow: 0 т.е. никакой из элементов не должен увеличиваться и заполнять свободное место в контейнере.

По умолчанию flex-grow: 0

  • Если всем элементам указать flex-grow: 1 , то все они растянуться одинаково и заполнять все свободное место в контейнере.
  • Если одному из элементов указать flex-grow: 1 , то он заполнит все свободное место в контейнере и выравнивания через justify-content работать уже не будут: свободного места нет выравнивать нечего...
  • Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные
  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:3 , то они будут одинакового размера
  • Если один из них имеет flex-grow:12 , то он будет в 4 раза больше, чем все остальные

Как это работает? Допустим, что контейнер имеет ширину 500px и содержит два элемента, каждый из которых имеет базовую ширину 100px. Значит в контейнере остается 300 свободных пикселей. Теперь, если первому элементу укажем flex-grow: 2; , а второму flex-grow: 1; , то блоки займут всю доступную ширину контейнера и ширина первого блока будет 300px, а второго 200px. Объясняется это тем, что доступные 300px свободного места в контейнере распределились между элементами в соотношении 2:1, +200px первому и +100px второму.

Заметка: в значении можно указывать дробные числа, например: 0.5 - flex-grow:0.5

flex-shrink:

Задает коэффициент уменьшения элемента. Свойство противоположное flex-grow и определяет как элемент должен сжиматься, если в контейнере не остается свободного места. Т.е. свойство начинает работать, когда сумма размеров всех элементов больше чем размер контейнера.

По умолчанию flex-shrink:1

Допустим, что контейнер имеет ширину 600px и содержит два элемента, каждый из которых имеет ширину 300px - flex-basis:300px; . Т.е. два элемента полностью заполняют контейнер. Первому элементу укажем flex-shrink: 2; , а второму flex-shrink: 1; . Теперь уменьшим ширину контейнера на 300px, т.е. элементы должны сжаться на 300px чтобы находится внутри контейнера. Сжиматься они будут в соотношении 2:1, т.е. первый блок сожмется на 200px, а второй на 100px и новые размеры элементов станут 100px и 200px.

Заметка: в значении можно указывать дробные числа, например: 0.5 - flex-shrink:0.5

flex-basis:

Устанавливает базовую ширину элемента - ширину до того как будут высчитаны остальные условия влияющие на ширину элемента. Значение можно указать в px , % , em , rem и т.д. Итоговая ширина будет зависеть от базовой ширины и значений flex-grow, flex-shrink и контента внутри блока. В режиме auto элемент получает базовую ширину относительно контента внутри него.

По умолчанию: auto

Иногда может пригодится установить ширину элемента жестко через привычное свойство width . Например, width: 50%; будет означать, что элемент внутри контейнера будет ровно 50%, однако при этом все также будут работать свойства flex-grow и flex-shrink. Такое может быть нужно, когда элемент растягивается контентом внутри него, больше указанного во flex-basis... Пример .

flex-basis будет «жестким», если указать обнулить растяжение и сжатие: flex-basis:200px; flex-grow:0; flex-shrink:0; - коротко можно записать так flex:0 0 200px; .

flex: {grow shrink basis}

Короткая запись трех свойств: flex-grow flex-shrink flex-basis .

По умолчанию: flex: 0 1 auto

Однако можно указать и одно, и два значения:

Flex: none; /* 0 0 auto */ /* число */ flex: 2; /* flex-grow (flex-basis переходит в 0) */ /* не число */ flex: 10em; /* flex-basis: 10em */ flex: 30px; /* flex-basis: 30px */ flex: auto; /* flex-basis: auto */ flex: content; /* flex-basis: content */ flex: 1 30px; /* flex-grow и flex-basis */ flex: 2 2; /* flex-grow и flex-shrink (flex-basis переходит в 0) */ flex: 2 2 10%; /* flex-grow и flex-shrink и flex-basis */ align-self:

Позволяет изменить свойство align-items , только для отдельного элемента.

По умолчанию: от align-items контейнера

  • stretch - элемент растягиваются заполняя строку полностью
  • flex-start - элемент прижимаются к началу строки
  • flex-end - элемент прижимаются к концу строки
  • center - элемент выравниваются по центру строки
  • baseline - элемент выравниваются по базовой линии текста

order:

Позволяет менять порядок (позицию, положение) элемента в общем ряду.

По умолчанию: order: 0

По умолчанию элементы имеют order: 0 и ставятся в порядке их появления в HTML коде и направления ряда. Но если изменить значение свойства order, то элементы будут выстраиваться в порядке значений: -1 0 1 2 3 ... . Например если одному из элементов указать order: 1 , то сначала будут идти все нулевые, а потом элемент с 1.

Так можно, например, первый элемент перекинуть в конец, при этом не меняя направление движения остальных элементов или HTML код.

Заметки

Чем отличается flex-basis от width?

Ниже важные различия между flex-basis и width / height:

    flex-basis работает только для главной оси. Это значит что при flex-direction:row flex-basis контролирует ширину (width), а при flex-direction:column контролирует высоту (height). .

    flex-basis применяется только к flex элементам. А значит если отключить flex у контейнера это свойство не будет иметь эффекта.

    Абсолютные элементы контейнера не участвуют во flex конструкции... А значит, flex-basis не влияет на элементы flex контейнера, если они абсолютны position:absolute . Им нужно будет указать width / height.

  • При использовании свойства flex 3 значения (flex-grow/flex-shrink/flex-basis) можно скомбинировать и записать коротко, а для width grow или shrink нужно писать отдельно. Например: flex:0 0 50% == width:50%; flex-shrink:0; . Иногда это просто неудобно.

По возможности все же отдавайте предпочтение flex-basis . Используйте width только когда не подходит flex-basis .

Отличие flex-basis от width - баг или фича?

Контент внутри flex элемента распирает его и не может вылезти за его пределы, кроме случаев когда ширина элемента не установлена через width или max-width . flex-basis тут не справится... Смотрите пример:

Примеры Flex верстки

В примерах нигде не используются префиксы для кроссбраузерности. Сделал я так для удобного чтения css. Поэтому примеры нужно смотрите в более-менее последних версиях chrome или firefox.

#1 Простой пример с выравниванием по вертикали и горизонтали

Начнем с самого простого примера - выравнивание по вертикали и горизонтали одновременно и при любой высоте блока, даже резиновой.

Текст по середине

Или так, без блока внутри:

Текст по середине

#1.2 Разделение (разрыв) между элементами флекс блока

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

#2 Адаптивное меню на flex

Сделаем меню в самом верху страницы. На широком экране оно должно быть справа. На среднем выравниваться по середине. А на маленьком каждый элемент должен быть на новой строке.

#3 Адаптивные 3 колонки

Этот пример показывает как быстро и удобно сделать 3 колонки, которые при сужении будут превращаться в 2 и затем в 1.

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

1
2
3
4
5
6

Перейдите в jsfiddle.net и изменяйте ширину секции «результат»

#4 Адаптивные блоки на flex

Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:

1
2
3

Перейдите в jsfiddle.net и изменяйте ширину секции «результат»

#5 Галерея на flex и transition

Этот пример показывает как быстро можно сделать симпатичный аккордеон с картинками на flex. Обратите внимание на свойство transition для flex.

#6 Флекс во флекс (просто пример)

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

Для решения этой задачи, сами блоки растягиваются флексом и им установлена максимально возможная ширина. Каждый внутренний блок также является флекс конструкцией, с повернутой осью flex-direction:column; и элемент в середине (где находится текст) растягивается flex-grow:1; чтобы заполнить всё свободное пространство, так достигается результат - текст начинался с одной линии...

Еще примеры

Поддержка браузерами - 97%

Полной поддержки разумеется нет, однако все современные браузеры поддерживают flexbox конструкции. Для некоторых все еще нужно указывать префиксы. Для реальной картины заглянем в caniuse.com и видим, что без префиксов будут работать 96% используемых сегодня браузеров, с префиксами 97% - и это отличный показатель, для того чтобы во всю пользоваться flexbox.

Чтобы знать какие префиксы актуальны на сегодня (фев. 2017), приведу пример всех flex правил с нужными префиксами :

/* Контейнер */ .flex { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-flex-flow: column wrap; -ms-flex-flow: column wrap; flex-flow: column wrap; -webkit-box-pack: justify; -webkit-justify-content: space-between; -ms-flex-pack: justify; justify-content: space-between; -webkit-align-content: space-around; -ms-flex-line-pack: distribute; align-content: space-around; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } /* Элементы */ .flex-item { -webkit-box-flex: 1; -webkit-flex-grow: 1; -ms-flex-positive: 1; flex-grow: 1; -webkit-flex-shrink: 2; -ms-flex-negative: 2; flex-shrink: 2; -webkit-flex-basis: 100px; -ms-flex-preferred-size: 100px; flex-basis: 100px; -webkit-box-flex: 1; -webkit-flex: 1 2 100px; -ms-flex: 1 2 100px; flex: 1 2 100px; -webkit-align-self: center; -ms-flex-item-align: center; align-self: center; -webkit-box-ordinal-group: 3; -webkit-order: 2; -ms-flex-order: 2; order: 2; }

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

Chrome Safari Firefox Opera IE Android iOS
20- (old) 3.1+ (old) 2-21 (old) 10 (tweener) 2.1+ (old) 3.2+ (old)
21+ (new) 6.1+ (new) 22+ (new) 12.1+ (new) 11+ (new) 4.4+ (new) 7.1+ (new)
  • (new) - новый синтаксис: display: flex; .
  • (tweener) - старый неофициальный синтаксис 2011 года: display: flexbox; .
  • (old) - старый синтаксис 2009 года: display: box;

Видео

Ну и не забывайте про видео, там порой тоже интересно и понятно. Вот парочка популярных:

Полезные ссылки по Flex

    flexboxfroggy.com - игра обучающая flexbox.

    Flexplorer - наглядный конструктор flex кода.

Flexbox по праву можно назвать удачной попыткой решения огромного спектра проблем при построении лейаутов в css. Но прежде чем перейти к его описанию, давайте выясним, что же не так со способами верстки, которыми мы пользуемся сейчас?

Любой верстальщик знает несколько путей выровнять что-либо по вертикали или сделать 3-х колоночный макет с резиновой средней колонкой. Но давайте признаем, что все эти способы довольно странные, похожи на хак, подходят не во всех случаях, сложны для восприятия и не работают при несоблюдении определенных магических условий, которые сложились исторически.

Случилось так потому, что html и css развивались эволюционно. В начале веб-страницы были похожи на однопоточные текстовые документы, чуть позже разбиение страницы на блоки делали таблицами, затем стало модным верстать float-ами, а после официальной смерти ie6 добавились еще и приемы с inline-block. В итоге мы получили в наследство гремучую смесь всех этих приемов, используемую для построения лейаутов 99,9% всех существующих веб-страниц.

Многострочная организация блоков внутри flex-контейнера.

flex-wrap

Все примеры, которые мы приводили выше, были построены с учетом однострочного (одностолбцового) расположения блоков. Надо сказать, что по умолчанию flex-контейнер всегда будет располагать блоки внутри себя в одну линию. Однако, спецификацией также поддерживается многострочный режим. За многострочность внутри flex-контейнера отвечает CSS свойство flex-wrap .

Доступные значения flex-wrap :

  • nowrap (значение по умолчанию) : блоки расположены в одну линию слева направо (в rtl справа налево)
  • wrap: блоки расположены в несколько горизонтальных рядов (если не помещаются в один ряд). Они следуют друг за другом слева направо (в rtl справа налево)
  • wrap-reverse: то-же что и wrap , но блоки располагаются в обратном порядке.

flex-flow – удобное сокращение для flex-direction + flex-wrap

По сути, flex-flow предоставляет возможность в одном свойстве описать направление главной и многострочность поперечной оси. По умолчанию flex-flow: row nowrap .

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

CSS

/* т.е. ... */ .my-flex-block{ flex-direcrion:column; flex-wrap: wrap; } /* это то же самое, что... */ .my-flex-block{ flex-flow: column wrap; }

align-content

Существует также свойство align-content , которое определяет то, каким образом образовавшиеся ряды блоков будут выровнены по вертикали и как они поделят между собой все пространство flex-контейнера.

Важно: align-content работает только в многострочном режиме (т.е. в случае flex-wrap:wrap; или flex-wrap:wrap-reverse;)

Доступные значения align-content :

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

СSS свойства flex-wrap и align-content должны применяться непосредственно к flex-контейнеру, а не к его дочерним элементам.

Демо свойств многострочности в flex

CSS правила для дочерних элементов flex-контейнера (flex-блоков)

flex-basis – базовый размер отдельно взятого flex-блока

Задает изначальный размер по главной оси для flex-блока до того, как к нему будут применены преобразования, основанные на других flex-факторах. Может быть задан в любых единицах измерения длинны (px , em , % , …) или auto (по умолчанию). Если задан как auto – за основу берутся размеры блока (width, height), которые, в свою очередь, могут зависеть от размера контента, если не указанны явно.

flex-grow – “жадность” отдельно взятого flex-блока

Определяет то, на сколько отдельный flex-блок может быть больше соседних элементов, если это необходимо. flex-grow принимает безразмерное значение (по умолчанию 0)

Пример 1 :

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:1 , то они будут одинакового размера
  • Если один из них имеет flex-grow:2 , то он будет в 2 раза больше, чем все остальные

Пример 2 :

  • Если все flex-блоки внутри flex-контейнера имеют flex-grow:3 , то они будут одинакового размера
  • Если один из них имеет flex-grow:12 , то он будет в 4 раза больше, чем все остальные

Т.е абсолютное значение flex-grow не определяет точную ширину. Оно определяет его степень “жадности” по отношению к другим flex-блокам того же уровня.

flex-shrink – фактор “сжимаемости” отдельно взятого flex-блока

Определяет, насколько flex-блок будет уменьшаться относительно соседних эдементов внутри flex-контейнера в случае недостатка свободного места. По умолчанию равен 1 .

flex – короткая запись для свойств flex-grow, flex-shrink и flex-basis

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

CSS

/* т.е. ... */ .my-flex-block{ flex-grow:12; flex-shrink:3; flex basis: 30em; } /* это то же самое, что... */ .my-flex-block{ flex: 12 3 30em; }

Демо для flex-grow, flex-shrink и flex-basis

align-self – выравнивание отдельно взятого flex-блока по поперечной оси.

Делает возможным переопределять свойство flex-контейнера align-items для отдельного flex-блока.

Доступные значения align-self (те же 5 вариантов, что и для align-items)

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

order – порядок следования отдельно взятого flex-блока внутри flex-контейнера.

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

Значение order не задает абсолютную позицию элемента в последовательности. Оно определяет вес позиции элемента.

HTML

item1
item2
item3
item4
item5

В данном случае, блоки будут следовать один за другим вдоль главной оси в следующем порядке: item5, item1, item3, item4, item2

Демо для align-self и order

margin: auto по вертикали . Мечты сбываются!

Flexbox можно любить хотя бы за то, что привычное всем выравнивание по горизонтали через margin:auto здесь работает и для вертикали!

My-flex-container { display: flex; height: 300px; /* Или что угодно */ } .my-flex-block { width: 100px; /* Или что угодно */ height: 100px; /* Или что угодно */ margin: auto; /* Магия! Блок отцентрирован по вертикали и горизонтали! */ }

Вещи, которые следует помнить

  1. Не следует использовать flexbox там, где в этом нет необходимости.
  2. Определение регионов и изменение порядка контента во многих случаях все-таки полезно делать зависимым от структуры страницы. Продумывайте это.
  3. Разберитесь в flexbox и знайте его основы. Так намного легче достичь ожидаемого результата.
  4. Не забывайте про margin-ы. Они учитываются при установке выравнивания по осям. Также важно помнить, что margin-ы в flexbox не “коллапсятся”, как это происходит в обычном потоке.
  5. Значение float у flex-блоков не учитывается и не имеет значения. Это, наверно, как-то можно использовать для graceful degradation при переходе на flexbox.
  6. flexbox очень хорошо подходит для верстки веб-компонентов и отдельных частей веб-страниц, но показал себя не с лучшей стороны при верстке базовых макетов (расположение article, header, footer, navbar и т.п.). Это все еще спорный момент, но эта статья довольно убедительно показывает недостатки xanthir.com/blog/b4580

В заключение

Я думаю, что flexbox, конечно же, не вытеснит все остальные способы верстки, но, безусловно, в ближайшее время займет достойную нишу при решении огромного количества задач. И уж точно, пробовать работать с ним нужно уже сейчас. Одна из следующих статей будет посвящена конкретным примерам работы с flex-версткой. Подписывайтесь на новости;)

Привет, хабр!

Одним прекрасным вечером, не предвещающим ничего интересного, в наш чатик поступило предложение от автора публикации «Переводим в код 5 действительно полезных шаблонов адаптивной разметки» , написанной им весной 2012 года, написать статью-ремейк, но с применением FlexBox и сопутствующим пояснением что и как работает. После некоторой доли сомнений, интерес глубже разобраться в спецификации все таки победил и я благополучно сел верстать те самые примеры. В ходе погружения в эту область стало выясняться множество нюансов, что переросло в нечто большее чем просто переверстать макетики. В общем в данной статье хочу рассказать о такой чудесной спецификации, под названием «CSS Flexible Box Layout Module» и показать некоторые ее интересные особенности и примеры применения. Всех кому интересно, любезно приглашаю под хабракат.

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

Техническая часть

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

Итак. Во FlexBox есть два основных типа элементов: Гибкий Контейнер (Flex Container) и его дочерние элементы - Гибкие Элементы (Flex Item). Для инициализации контейнера достаточно присвоить, через css, элементу display: flex; или display: inline-flex; . Разница между flex и inline-flex заключается лишь в принципе взаимодействия с окружающими контейнер элементами, подобно display: block; и display: inline-block;, соответственно.

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

Направлением осей можно управлять с помощью css-свойства flex-direction . Данное свойство принимает ряд значений:
row (default): Главная ось гибкого контейнера имеет ту же ориентацию, как и инлайн ось текущего режима направления строк . Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) инлайн оси (inline-axis).
row-reverse : Все то же самое, что и в row только main-start и main-end меняются местами.
column : так же само как и row, только теперь главная ось направлена сверху вниз.
column-reverse : так же само как row-reverse, только главная ось направлена снизу вверх.
Как это работает можно посмотреть в примере на jsfiddle .

По умолчанию все гибкие элементы в контейнере укладываются в одну строку, даже если не помещаются в контейнер, они выходят за его границы. Данное поведение переключается с помощью свойства flex-wrap . У этого свойства есть три состояния:
nowrap (default): гибкие элементы выстраиваются в одну строку слева направо.
wrap : гибкие элементы строятся в многострочном режиме, перенос осуществляется по направлению кросс оси, сверху вниз.
wrap-reverse : так же как и wrap, но перенос происходит снизу вверх.
Смотрим пример .

Для удобства есть дополнительное свойство flex-flow , в котором можно одновременно указать flex-direction и flex-wrap . Выглядит это следующим образом: flex-flow:

Элементы в контейнере поддаются выравниванию при помощи свойства justify-content вдоль главной оси. Это свойство принимает целых пять разных вариантов значений.
flex-start (default): гибкие элементы выравниваются по началу главной оси.
flex-end : элементы выравниваются по концу главной оси
center : элементы выравниваются по центру главной оси
space-between : элементы занимают всю доступную ширину в контейнере, крайние элементы вплотную прижимаются к краям контейнера, а свободное пространство равномерно распределяется между элементами.
space-around : гибкие элементы выравниваются таким образом, что свободное пространство равномерно распределяется между элементами. Но стоит отметить, что пространство межу краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
Конечно же поклацать пример работы этого свойства можно .

Это еще не все, мы так же имеем возможность выравнивания элементов по кросс оси. Применив свойство align-items , которое принимает также пять разных значений, можно добиться интересного поведения. Это свойство позволяет выравнивать элементы в строке относительно друг друга.
flex-start : все элементы прижимаются к началу строки
flex-end : элементы прижимаются к концу строки
center : элементы выравниваются по центру строки
baseline : элементы выравниваются по базовой линии текста
stretch (default): элементы растягиваются заполняя полностью строку.

Еще одно похожее свойство на предыдущее это align-content . Только оно отвечает за выравнивание целых строк относительно гибкого контейнера. Оно не будет давать эффекта если гибкие элементы занимают одну строку. Свойство принимает шесть разных значений.
flex-start : все линии прижимаются к началу кросс-оси
flex-end : все линии прижимаются к концу кросс-оси
center : Все линии паком выравниваются по центру кросс оси
space-between : линии распределяются от верхнего края до нижнего оставляя свободное пространство между строками, крайние же строки прижимаются к краям контейнера.
space-around : линии равномерно распределяются по контейнеру.
stretch (default): линии растягиваются занимая все доступное пространство.
Попробовать как работают align-items и align-content можно в этом примере . Я специально два этих свойства представил в одном примере, так как они довольно плотно взаимодействуют каждый выполняя свою задачу. Обратите внимание что происходит когда элементы помещаются в одну строку и в несколько.

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

Одно из основных свойств является flex-basis . С помощью этого свойства мы можем указывать базовую ширину гибкого элемента. По умолчанию имеет значение auto . Это свойство тесно связано с flex-grow и flex-shrink , о которых я расскажу чуть позже. Принимает значение ширины в px, %, em и остальных единицах. По сути это не строго ширина гибкого элемента, это своего рода отправная точка. Относительно которой происходит растягивание или усадка элемента. В режиме auto элемент получает базовую ширину относительно контента внутри него.

flex-grow на нескольких ресурсах имеет совершенно некорректное описание. Там говорится о том, что якобы оно задает соотношение размеров элементов в контейнере. На самом деле это не так. Это свойство задает фактор увеличения элемента при наличии свободного места в контейнере. По умолчанию это свойство имеет значение 0. Давайте представим, что у нас есть гибкий контейнер, который имеет ширину 500px, внутри него есть два гибких элемента, каждый из которых имеет базовую ширину 100px. Тем самым в контейнере остается еще 300px свободного места. Если первому элементу укажем flex-grow: 2;, а второму элементу укажем flex-grow: 1;. В результате эти блоки займут всю доступную ширину контейнера, только ширина первого блока будет 300px, а второго только 200px. Что же произошло? А произошло вот что, доступные 300px свободного места в контейнере распределились между элементами в соотношении 2:1, +200px первому и +100px второму. Собственно так это и работает.

Тут мы плавно переходим к другому аналогичному свойству, а именно flex-shrink . По умолчанию имеет значение 1. Оно так же задает фактор на изменение ширины элементов, только в обратную сторону. Если контейнер имеет ширину меньше чем сумма базовой ширины элементов, то начинает действовать это свойство. Например контейнер имеет ширину 600px, а flex-basis элементов по 300px. Первому элементу укажем flex-shrink: 2;, а второму flex-shrink: 1;. Теперь сожмем контейнер на 300px. Следовательно сумма ширины элементов на 300px больше чем контейнер. Эта разница распределяется в соотношении 2:1, получается от первого блока отнимаем 200px, а от второго 100px. Новый размер элементов получается 100px и 200px, у первого и второго элемента, соответственно. Если мы устанавливаем flex-shrink в значение 0, то мы запрещаем сжиматься элементу до размеров меньше чем его базовая ширина.

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

Все три свойства можно записать в сокращенной форме при помощи выражения flex . Это имеет следующий вид:
flex: ;
А так же мы можем писать еще два сокращенных варианта, flex: auto; и flex: none; , что означает flex: 1 1 auto; и flex: 0 0 auto; соответственно.

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

Все, надоел! Примеры давай!

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

Для начала обозначим основную ширину страницы, выровняем по центру, прижмем футер к низу страницы. Как всегда в общем.

Html { background: #ccc; min-height: 100%; font-family: sans-serif; display: -webkit-flex; display: flex; flex-direction: column; } body { margin: 0; padding: 0 15px; display: -webkit-flex; display: flex; flex-direction: column; flex: auto; } .header { width: 100%; max-width: 960px; min-width: 430px; margin: 0 auto 30px; padding: 30px 0 10px; display: -webkit-flex; display: flex; flex-wrap: wrap; justify-content: space-between; box-sizing: border-box; } .main { width: 100%; max-width: 960px; min-width: 430px; margin: auto; flex-grow: 1; box-sizing: border-box; } .footer { background: #222; width: 100%; max-width: 960px; min-width: 430px; color: #eee; margin: auto; padding: 15px; box-sizing: border-box; }

За счет того что мы для.main указали flex-grow: 1; он растягивается на всю доступную высоту, тем самым прижимая футер к низу. Бонусом в этом решении является, то что футер может быть нефиксированной высоты.

Разместим теперь логотип и меню в хедере.
.logo { font-size: 0; margin: -10px 10px 10px 0; display: flex; flex: none; align-items: center; } .logo:before, .logo:after { content: ""; display: block; } .logo:before { background: #222; width: 50px; height: 50px; margin: 0 10px 0 20px; border-radius: 50%; } .logo:after { background: #222; width: 90px; height: 30px; } .nav { margin: -5px 0 0 -5px; display: -webkit-flex; display: flex; flex-wrap: wrap; } .nav-itm { background: #222; width: 130px; height: 50px; font-size: 1.5rem; color: #eee; text-decoration: none; margin: 5px 0 0 5px; display: -webkit-flex; display: flex; justify-content: center; align-items: center; }

Поскольку для хедера указано flex-wrap: wrap; и justify-content: space-between; логотип и меню раскидывает по разным сторонам хедера, при этом если места для меню будет не хватать оно элегантно сместится под логотип.

Далее мы видим большой пост или баннер, затрудняюсь сказать что это конкретно, но и не суть. У нас есть картинка справа и текст с заголовком слева. Я лично придерживаюсь идеи, что любые элементы должны быть максимально гибкими, независимо от того адаптиваная это верстка или статика. Итак у нас есть в этом посте сайд-бар в котором размещена картинка, строго говоря мы не можем точно сказать какая ширина нам нужна, ибо сегодня у нас большая картинка, завтра маленькая и каждый раз переделывать элемент с нуля неохота. Значит нам нужно, чтобы сайд-бар занял нужное ему место, а остальное место пошло на контент. Так и сделаем:

Box { font-size: 1.25rem; line-height: 1.5; font-style: italic; margin: 0 0 40px -50px; display: -webkit-flex; display: flex; flex-wrap: wrap; justify-content: center; } .box-base { margin-left: 50px; flex: 1 0 430px; } .box-side { margin-left: 50px; flex: none; } .box-img { max-width: 100%; height: auto; }

Как вы видите для.box-base, там где у нас заголовок и текст, я указал базовую ширину посредством flex-basis: 430px; , а так же запретил усадку блока при помощи flex-shrink: 0; . Этой манипуляцией мы сказали, что контент не может стать меньше чем 430px в ширину. А ввиду того что для.box я указываю flex-wrap: wrap; в тот момент, когда сайд-бар и контент не будут помещаться в контейнер.box, сайд-бар автоматически провалится под контент. И это все без применения @ media ! Я считаю это действительно очень круто.

У нас остался трехколоночный контент. Решений подобной задачи несколько, я покажу один из них, в остальных макетах есть и другой вариант.
Создаем контейнер, назовем его.content и настроим.
.content { margin-bottom: 30px; display: -webkit-flex; display: flex; flex-wrap: wrap; }

В контейнере три колонки, .banners, .posts, .comments
.banners { flex: 1 1 200px; } .posts { margin: 0 0 30px 30px; flex: 1 1 200px; } .comments { margin: 0 0 30px 30px; flex: 1 1 200px; }

Задал колонкам базовую ширину 200px, чтобы колонки не сужались прям слишком сильно, пускай лучше они по мере надобности переносятся друг под друга.

По макету, нам с контентом, обойтись без @ media не получится, поэтому еще немного настроим поведение колонок для ширины <800px и <600px.
@media screen and (max-width: 800px) { .banners { margin-left: -30px; display: -webkit-flex; display: flex; flex-basis: 100%; } .posts { margin-left: 0; } } @media screen and (max-width: 600px) { .content { display: block; } .banners { margin: 0; display: block; } .comments { margin: 0; } }

Вот и вся магия, что касается построения лейаута на FlexBox. Еще одна задача, которая мне понравилась, находится в 5-ом макете, конкретно это касается адаптации контента.

Мы видим, как на десктопном разрешении посты построены в сетку по три штуки в ряд. Когда ширина viewport становится меньше 800px, то сетка превращается в колонку с постами, где фото поста выстраивается с левой и правой стороны от контента поста, поочередно. А при ширине меньше 600px фото поста прячется вовсе.
.grid { display: -webkit-flex; display: flex; flex-wrap: wrap; justify-content: space-between; } .grid-itm { margin-bottom: 30px; flex-basis: calc(33.33% - 30px * 2/3); display: -webkit-flex; display: flex; flex-wrap: wrap; } .grid-img { margin: 0 auto 20px; flex: 0 1 80%; } .grid-cont{ flex: 0 1 100%; } .grid-title { text-align: center; } @media screen and (max-width: 800px) { .grid-itm { flex-wrap: nowrap; flex-basis: 100%; } .grid-img { flex: 0 0 auto; } .grid-itm:nth-child(even) .grid-img { margin: 0 0 0 30px; order: 2; } .grid-itm:nth-child(odd) .grid-img { margin: 0 30px 0 0; } .grid-cont { flex: 1 1 auto; } .grid-title { text-align: left; } } @media screen and (max-width: 600px) { .grid-img { display: none; } }

На самом деле это всего лишь малая часть того, что можно реализовать на FlexBox. Спецификация позволяет строить весьма сложные макеты страниц при этом применяя простой код.