Что такое flex css. Что такое flexbox

О том, как просто работать с Flexbox на примере верстки шаблона новостного сайта.

Поверьте, нет никакой необходимости в детальном разборе всех аспектов работы с Flexbox, если вы хотите начать им пользоваться уже сейчас. В этом руководстве автор собирается познакомить вас с некоторыми свойствами Flexbox и сделать «новостной лейаут» наподобие того, который вы могли видеть на сайте The Guardian .

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

Ну, поехали!

1. Начинаем с создания двух столбцов

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

В свою очередь, Flexbox упрощает этот процесс, обладая рядом таких преимуществ, как:

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

Давайте начнем работу с создания двух столбцов, один из которых будет занимать 2/3 ширины нашего контейнера, а еще один - 1/3 его часть.

2/3 column
1/3 column

Здесь присутствуют два элемента:

Контейнер columns;
- два дочерних элемента column , один из которых имеет дополнительный класс main-column , который мы используем позже для того, чтобы сделать столбец шире.

Columns { display: flex; } .column { flex: 1; } .main-column { flex: 2; }
Поскольку main-column имеет значение flex равное 2 , то этот столбец займет в два раза больше места, чем второй.

Добавим немного визуального оформления и, в итоге, получим:

Кликните для просмотра в действии

2. Делаем каждый столбец flexbox-контейнером

Каждый из двух столбцов будет содержать несколько вертикально расположенных статей, поэтому из этих двух элементов мы, в свою очередь, также должны сделать flexbox-контейнеры.

Итак, нам необходимо, чтобы статьи:

Располагались вертикально внутри столбца-контейнера;
- занимали все доступное место.

Правило flex-direction: column , указанное для контейнера, вместе с правилом flex: 1 , указанным для дочернего элемента, позволяет статье заполнить все свободное место по вертикали, при этом высота первых двух столбцов останется неизменной.


Кликните для просмотра в действии

3. Делаем контейнер из статьи

Теперь, чтобы еще больше расширить наши возможности, давайте представим каждую статью в виде flexbox-контейнера. Каждый такой контейнер будет содержать:

Заголовок;
- параграф;
- информационную панель с именем автора и количеством комментариев;
- какую-нибудь адаптивную картинку.

Здесь мы используем Flexbox для того, чтобы «прижать» информационную панель к низу элемента. Вот, посмотрите, какой результат мы ожидаем получить.

А вот и сам код:


.article { display: flex; flex-direction: column; flex-basis: auto; /* Устанавливает начальный размер элемента в зависимости от его содержимого */ } .article-body { display: flex; flex: 1; flex-direction: column; } .article-content { flex: 1; /* Содержимое заполняет все оставшееся место, тем самым прижимая информационную панель к нижней части */ }
Элементы внутри статьи расположены вертикально благодаря использованию правила flex-direction: column .

Также мы применили свойство flex: 1 к элементу article-content , тем самым растянув его на все свободное место и прижав article-info к низу. Высота столбцов в этом случае не имеет значения.


Кликните для просмотра в действии

4. Добавляем несколько вложенных столбцов

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


Поскольку мы хотим, чтобы первый вложенный столбец был шире, добавим к элементу класс nested-column , а в CSS укажем:

Nested-column { flex: 2; }
Теперь этот столбец будет вдвое шире второго.


Кликните для просмотра в действии

5. Делаем первую статью с горизонтальным лейаутом

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

First-article { flex-direction: row; } .first-article .article-body { flex: 1; } .first-article .article-image { height: 300px; order: 2; padding-top: 0; width: 400px; }
Свойство order в данном случае играет большую роль, поскольку оно позволяет изменять очередность HTML-элементов без изменения HTML-разметки. В действительности, article-image в коде идет перед элементом article-body , но ведет себя так, будто стоит после него.


Кликните для просмотра в действии

6. Делаем адаптивный лейаут

Теперь все выглядит так, как мы хотели, хотя и немного сплющено. Давайте исправим это, добавив нашему лейауту гибкости.

Одной из замечательных вещей в Flexbox является то, что достаточно удалить правило display: flex в контейнере для того, чтобы полостью отключить его (Flexbox), в то время, как остальные его свойства (такие, как align-items или flex ) останутся рабочими.

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

Итак, мы собираемся удалить display: flex из селекторов .columns и .column , вместо этого «запаковав» их в медиа-запрос:

@media screen and (min-width: 800px) { .columns, .column { display: flex; } }
Вот и все! На экранах с маленьким разрешением все статьи будут располагаться друг над другом, а на экранах с разрешением свыше 800 пикселей - в два столбца.

7. Добавляем завершающие штрихи

Для того, чтобы лейаут выглядел более привлекательно на больших экранах, давайте добавим кое-какие CSS-твики:

@media screen and (min-width: 1000px) { .first-article { flex-direction: row; } .first-article .article-body { flex: 1; } .first-article .article-image { height: 300px; order: 2; padding-top: 0; width: 400px; } .main-column { flex: 3; } .nested-column { flex: 2; } }
Содержимое первой статьи выровнено по горизонтали: текст расположен по левой стороне, а картинка - по правой. Также, главный столбец теперь стал шире (75%). То же самое касается и вложенного столбца (66%).

А вот и финальный результат!


Кликните для просмотра в действии

Вывод

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

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

Одним прекрасным вечером, не предвещающим ничего интересного, в наш чатик поступило предложение от автора публикации «Переводим в код 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. Спецификация позволяет строить весьма сложные макеты страниц при этом применяя простой код.

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

Одним прекрасным вечером, не предвещающим ничего интересного, в наш чатик поступило предложение от автора публикации , написанной им весной 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. Спецификация позволяет строить весьма сложные макеты страниц при этом применяя простой код.

CSS flexbox (Flexible Box Layout Module) — модуль макета гибкого контейнера — представляет собой способ компоновки элементов, в основе лежит идея оси.

Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items) . Гибкие элементы могут выстраиваться в строку или столбик, а оставшееся свободное пространство распределяется между ними различными способами.

Модуль flexbox позволяет решать следующие задачи:

  • Располагать элементы в одном из четырех направлений: слева направо, справа налево, сверху вниз или снизу вверх.
  • Переопределять порядок отображения элементов.
  • Автоматически определять размеры элементов таким образом, чтобы они вписывались в доступное пространство.
  • Решать проблему с горизонтальным и вертикальным центрированием.
  • Переносить элементы внутри контейнера, не допуская его переполнения.
  • Создавать колонки одинаковой высоты.
  • Создавать прижатый к низу страницы .

Flexbox решает специфические задачи — создание одномерных макетов, например, навигационной панели, так как flex-элементы можно размещать только по одной из осей.

Что такое flexbox

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

IE: 11.0, 10.0 -ms-
Firefox: 28.0, 18.0 -moz-
Chrome: 29.0, 21.0 -webkit-
Safari: 6.1 -webkit-
Opera: 12.1 -webkit-
iOS Safari: 7.0 -webkit-
Opera Mini: 8
Android Browser: 4.4, 4.1 -webkit-
Chrome for Android: 44

1. Основные понятия


Рис. 1. Модель flexbox

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

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

Main start и main end — линии, которые определяют начальную и конечную стороны flex-контейнера, относительно которых выкладываются flex-элементы (начиная с main start по направлению к main end).

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

Поперечная ось (cross axis) — ось, перпендикулярная главной оси. Она простирается в поперечном измерении.

Cross start и cross end — линии, которые определяют начальную и конечную стороны поперечной оси, относительно которых выкладываются flex-элементы.

Поперечный размер (cross size) — ширина или высота flex-контейнера или flex-элементов, в зависимости от того, что находится в поперечном измерении, являются их поперечным размером.


Рис. 2. Режим строки и колонки

2. Flex-контейнер

Flex-контейнер устанавливает новый гибкий контекст форматирования для его содержимого. Flex-контейнер не является блочным контейнером, поэтому для дочерних элементов не работают такие CSS-свойства, как float , clear , vertical-align . Также, на flex-контейнер не оказывают влияние свойства column-* , создающие колонки в тексте и псевдоэлементы::first-line и::first-letter .

Модель flexbox-разметки связана с определенным значением CSS-свойства display родительского html-элемента, содержащего внутри себя дочерние блоки. Для управления элементами с помощью этой модели нужно установить свойство display следующим образом:

Flex-container { /*генерирует flex-контейнер уровня блока*/ display: -webkit-flex; display: flex; } .flex-container { /*генерирует flex-контейнер уровня строки*/ display: -webkit-inline-flex; display: inline-flex; }

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

Рис. 3. Выравнивание элементов в модели flexbox

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

3. Flex-элементы

Flex-элементы — блоки, представляющие содержимое flex-контейнера в потоке. Flex-контейнер устанавливает новый контекст форматирования для своего содержимого, который обуславливает следующие особенности:

  • Для flex-элементов блокируется их значение свойства display . Значение display: inline-block; и display: table-cell; вычисляется в display: block; .
  • Пустое пространство между элементами исчезает: оно не становится своим собственным flex-элементом, даже если межэлементный текст обернут в анонимный flex-элемент. Для содержимого анонимного flex-элемента невозможно задать собственные стили, но оно будет наследовать их (например, параметры шрифта) от flex-контейнера.
  • Абсолютно позиционированный flex-элемент не участвует в компоновке гибкого макета.
  • Поля margin соседних flex-элементов не схлопываются.
  • Процентные значения margin и padding вычисляются от внутреннего размера содержащего их блока.
  • margin: auto; расширяются, поглощая дополнительное пространство в соответствующем измерении. Их можно использовать для выравнивания или раздвигания смежных flex-элементов.
  • Автоматический минимальный размер flex-элементов по умолчанию является минимальным размером его содержимого, то есть min-width: auto; . Для контейнеров с прокруткой автоматический минимальный размер обычно равен нулю.

4. Порядок отображения flex-элементов и ориентация

Содержимое flex-контейнера можно разложить в любом направлении и в любом порядке (переупорядочение flex-элементов внутри контейнера влияет только на визуальный рендеринг).

4.1. Направление главной оси: flex-direction

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

flex-direction
Значения:
row Значение по умолчанию, слева направо (в rtl справа налево). Flex-элементы выкладываются в строку. Начало (main-start) и конец (main-end) направления главной оси соответствуют началу (inline-start) и концу (inline-end) инлайн-оси (inline-axis).
row-reverse Направление справа налево (в rtl слева направо). Flex-элементы выкладываются в строку относительно правого края контейнера (в rtl — левого).
column Направление сверху вниз. Flex-элементы выкладываются в колонку.
column-reverse Колонка с элементами в обратном порядке, снизу вверх.
initial
inherit

Рис. 4. Свойство flex-direction для left-to-right языков

Синтаксис

Flex-container { display: -webkit-flex; -webkit-flex-direction: row-reverse; display: flex; flex-direction: row-reverse; }

4.2. Управление многострочностью flex-контейнера: flex-wrap

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

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


Рис. 5. Управление многострочностью с помощью свойства flex-wrap для LTR-языков

Синтаксис

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

4.3. Краткая запись направления и многострочности: flex-flow

Свойство позволяет определить направления главной и поперечной осей, а также возможность переноса flex-элементов при необходимости на несколько строк. Представляет собой сокращённую запись свойств flex-direction и flex-wrap . Значение по умолчанию flex-flow: row nowrap; . свойство не наследуется.

Синтаксис

Flex-container { display: -webkit-flex; -webkit-flex-flow: row wrap; display: flex; flex-flow: row wrap; }

4.4. Порядок отображения flex-элементов: order

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

Первоначально все flex-элементы имеют order: 0; . При указании значения от -1 для элемента он перемещается в начало сроки, значение 1 — в конец. Если несколько flex-элементов имеют одинаковое значение order , они будут отображаться в соответствии с исходным порядком.

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-order: 1; order: 1; }
Рис. 6. Порядок отображения flex-элементов

5. Гибкость flex-элементов

Определяющим аспектом гибкого макета является возможность «сгибать» flex-элементы, изменяя их ширину / высоту (в зависимости от того, какой размер находится на главной оси), чтобы заполнить доступное пространство в основном измерении. Это делается с помощью свойства flex . Flex-контейнер распределяет свободное пространство между своими дочерними элементами (пропорционально их коэффициенту flex-grow) для заполнения контейнера или сжимает их (пропорционально их коэффициенту flex-shrink), чтобы предотвратить переполнение.

Flex-элемент будет полностью «негибок», если его значения flex-grow и flex-shrink равны нулю, и «гибкий» в противном случае.

5.1. Задание гибких размеров одним свойством: flex

Свойство является сокращённой записью свойств flex-grow , flex-shrink и flex-basis . Значение по умолчанию: flex: 0 1 auto; . Можно указывать как одно, так и все три значения свойств. Свойство не наследуется.

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex: 3 1 100px; -ms-flex: 3 1 100px; flex: 3 1 100px; }

5.2. Коэффициент роста: flex-grow

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

Рис. 7. Управление свободным пространством в панели навигации с помощью flex-grow

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-grow: 3; flex-grow: 3; }

5.3. Коэффициент сжатия: flex-shrink

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


Рис. 8. Сужение flex-элементов в строке

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-shrink: 3; flex-shrink: 3; }

5.4. Базовый размер: flex-basis

Свойство устанавливает начальный основной размер flex-элемента до распределения свободного пространства в соответствии с коэффициентами гибкости. Для всех значений, кроме auto и content , базовый гибкий размер определяется так же, как width в горизонтальных режимах записи. Процентные значения определяются относительно размера flex-контейнера, а если размер не задан, используемым значением для flex-basis являются размеры его содержимого. Не наследуется.

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-flex-basis: 100px; flex-basis: 100px; }

6. Выравнивание

6.1. Выравнивание по главной оси: justify-content

Свойство выравнивает flex-элементы по главной оси flex-контейнера, распределяя свободное пространство, незанятое flex-элементами. Когда элемент преобразуется в flex-контейнер, flex-элементы по умолчанию сгруппированы вместе (если для них не заданы поля margin). Промежутки добавляются после расчета значений margin и flex-grow . Если какие-либо элементы имеют ненулевое значение flex-grow или margin: auto; , свойство не будет оказывать влияния. Свойство не наследуется.

Значения:
flex-start Значение по умолчанию. Flex-элементы выкладываются в направлении, идущем от начальной линии flex-контейнера.
flex-end Flex-элементы выкладываются в направлении, идущем от конечной линии flex-контейнера.
center Flex-элементы выравниваются по центру flex-контейнера.
space-between Flex-элементы равномерно распределяются по линии. Первый flex-элемент помещается вровень с краем начальной линии, последний flex-элемент — вровень с краем конечной линии, а остальные flex-элементы на линии распределяются так, чтобы расстояние между любыми двумя соседними элементами было одинаковым. Если оставшееся свободное пространство отрицательно или в строке присутствует только один flex-элемент, это значение идентично параметру flex-start .
space-around Flex-элементы на линии распределяются так, чтобы расстояние между любыми двумя смежными flex-элементами было одинаковым, а расстояние между первым / последним flex-элементами и краями flex-контейнера составляло половину от расстояния между flex-элементами.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.

Рис. 9. Выравнивание элементов и распределение свободного пространства с помощью свойства justify-content

Синтаксис

Flex-container { display: -webkit-flex; -webkit-justify-content: flex-start; display: flex; justify-content: flex-start; }

6.2. Выравнивание по поперечной оси: align-items и align-self

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

6.2.1. Align-items

Свойство выравнивает flex-элементы, в том числе и анонимные flex-элементы по поперечной оси. Не наследуется.

Значения:
flex-start
flex-end
center
baseline Базовые линии всех flex-элементов, участвующих в выравнивании, совпадают.
stretch
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.
Рис. 10. Выравнивание элементов в контейнере по вертикали

Синтаксис

Flex-container { display: -webkit-flex; -webkit-align-items: flex-start; display: flex; align-items: flex-start; }

6.2.2. Align-self

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

Значения:
auto Значение по умолчанию. Flex-элемент использует выравнивание, указанное в свойстве align-items flex-контейнера.
flex-start Верхний край flex-элемента помещается вплотную с flex-линией (или на расстоянии, с учетом заданных полей margin и рамок border элемента), проходящей через начало поперечной оси.
flex-end Нижний край flex-элемента помещается вплотную с flex-линией (или на расстоянии, с учетом заданных полей margin и рамок border элемента), проходящей через конец поперечной оси.
center Поля flex-элемента центрируется по поперечной оси в пределах flex-линии.
baseline Flex-элемент выравнивается по базовой линии.
stretch Если поперечный размер flex-элемента вычисляется как auto и ни одно из поперечных значений margin не равно auto , элемент растягивается. Значение по умолчанию.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.

Рис. 11. Выравнивание отдельных flex-элементов

Синтаксис

Flex-container { display: -webkit-flex; display: flex; } .flex-item { -webkit-align-self: center; align-self: center; }

6.3. Выравнивание строк flex-контейнера: align-content

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

Значения:
flex-start Строки укладываются по направлению к началу flex-контейнера. Край первой строки помещается вплотную к краю flex-контейнера, каждая последующая — вплотную к предыдущей строке.
flex-end Строки укладываются по направлению к концу flex-контейнера. Край последней строки помещается вплотную к краю flex-контейнера, каждая предыдущая — вплотную к последующей строке.
center Строки укладываются по направлению к центру flex-контейнера. Строки расположены вплотную друг к другу и выровнены по центру flex-контейнера с равным расстоянием между начальным краем содержимого flex-контейнера и первой строкой и между конечным краем содержимого flex-контейнера и последней строкой.
space-between Строки равномерно распределены в flex-контейнере. Если оставшееся свободное пространство отрицательно или в flex-контейнере имеется только одна flex-линия, это значение идентично flex-start . В противном случае край первой строки помещается вплотную к начальному краю содержимого flex-контейнера, край последней строки — вплотную к конечному краю содержимого flex-контейнера. Остальные строки распределены так, чтобы расстояние между любыми двумя соседними строками было одинаковым.
space-around Строки равномерно распределены в flex-контейнере с половинным пробелом на обоих концах. Если оставшееся свободное пространство отрицательно, это значение идентично цент center . В противном случае строки распределяются таким образом, чтобы расстояние между любыми двумя соседними строками было одинаковым, а расстояние между первой / последней строками и краями содержимого flex-контейнера составляло половину от расстояния между строками.
stretch Значение по умолчанию. Строки flex-элементов равномерно растягиваются, заполняя все доступное пространство. Если оставшееся свободное пространство отрицательно, это значение идентично flex-start . В противном случае свободное пространство будет разделено поровну между всеми строками, увеличивая их поперечный размер.
initial Устанавливает значение свойства в значение по умолчанию.
inherit Наследует значение свойства от родительского элемента.
Рис. 12. Многострочное выравнивание flex-элементов

Синтаксис

Flex-container { display: -webkit-flex; -webkit-flex-flow: row wrap; -webkit-align-content: flex-end; display: flex; flex-flow: row wrap; align-content: flex-end; height: 100px; }

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. Будущее этой модели действительно потрясающее.