Не работает flexbox. Как работает CSS Flexbox: наглядное введение в систему компоновки элементов на веб-странице. Выравниваем вертикально во всех строках align-content

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

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

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

Значения

.flex-item { order: <целое число>; }

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

Значение по умолчанию : 0.

flex-grow

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

Значения

.flex-item { flex-grow: <число>; }

Если все flex-элементы имеют одинаковое значение flex-grow , то все элементы будут иметь и одинаковый размер в контейнере.

Второй flex-элемент занимает больше места относительно размера других flex-элементов.

Значение по умолчанию : 0.

flex-shrink

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

Значения

.flex-item { flex-shrink: <число>; }

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

Значение по умолчанию : 1.

Отрицательные числа недопустимы.

flex-basis

Это свойство принимает те же значения, что и свойства width и height , и определяет начальный основной размер flex-элемента, до того, как свободное пространство распределяется в соответствии с коэффициентами.

Значения

.flex-item { flex-basis: auto | <ширина>; }

flex-basis указан для четвёртого flex-элемента и диктует его начальный размер.

Значение по умолчанию : auto.

flex

Это свойство является сокращением для свойств flex-grow , flex-shrink и flex-basis . Крое других значений также можно установить auto (1 1 auto ) и none (0 0 auto ).

Значения

.flex-item { flex: none | auto | [ ? || ]; }

Значение по умолчанию : 0 1 auto .

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

align-self

Свойство align-self позволяет переопределить выравнивание по умолчанию (или значение, указанное через align-items ) для отдельных flex-элементов. Для понимания доступных значений обратитесь к описанию align-items для flex-контейнера.

Значения

.flex-item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }

Для третьего и четвёртого flex-элементов переопределено выравнивание через свойство align-self .

Модуль Flexbox Layout (Flexible Box) направлен на то чтобы предоставить более эффективный способ расположения, выравнивания и распределения свободного пространства между элементами в контейнере, даже когда их размер заранее неизвестен и/или динамичен (поэтому слово "flex").

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

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

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

Основы и терминология

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

Если обычная система компоновки основана на блочных и строковых направлениях, то Flexbox основан на "flex-flow направлениях". Пожалуйста взгляните на этот рисунок из спецификации, объясняющий основную идею Flexbox.

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

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

CSS Flexible Box Layout Module

Chrome for Android

Браузер Blackberry начиная с 10 версии поддерживает новый синтаксис.

Свойства для контейнера

Свойства для элементов

Свойства для родительского элемента (Flex-контейнера)

display

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

Container { display: flex; /* или inline-flex */ }

Обратите внимание, что CSS колонки не влияют на flex-контейнер.

flex-direction


Устанавливает основную ось, таким образом определяет направление элементов расположенных в контейнере. Flexbox (помимо опциональной обёртки) представляет собой концепцию однонаправленного макета. Думайте о flex-элементах, прежде всего как горизонтальных строках или вертикальных колонках.

Container { flex-direction: row | row-reverse | column | column-reverse; }

  • row (по умолчанию) - слева направо в ltr ; справа налево в rtl ;
  • row-reverse - справа налево в ltr ; слева направо в rtl ;
  • column - тоже самое что row , только сверху вниз;
  • column-reverse - тоже самое что row-reverse , только снизу вверх;

flex-wrap


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

Container{ flex-wrap: nowrap | wrap | wrap-reverse; }

  • nowrap (по умолчанию) - все flex-элементы будут расположены на одной строке;
  • wrap - flex-элементы будут расположены на нескольких строках, сверху вниз;
  • wrap-reverse - flex-элементы будут расположены на нескольких строках, снизу вверх;

justify-content


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

Container { justify-content: flex-start | flex-end | center | space-between | space-around; }

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

align-items


Это свойство определяет поведение flex-элементов вдоль поперечной оси на текущей строке. Думайте о нём как о , только для поперечной оси (перпендикулярной основной оси).

Container { align-items: flex-start | flex-end | center | baseline | stretch; }

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

align-content


Примечание. Это свойство не действует, когда есть только одна строка flex-элементов.

Container { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }

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

Свойства для дочерних элементов (Flex элементов)

order


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

Item { order: ; }

flex-grow


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

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

Item { flex-grow: ; /* по умолчанию 0 */ }

Нельзя указывать отрицательные числа.

flex-basis

Определяет размер элемента по умолчанию, до распределения оставшегося пространства. Это может быть длина (20%, 5rem и т.д.) или ключевое слово. Ключевое слово auto означает "выглядеть как моё свойство width или height ". Ключевое слово content означает что "размер основан на содержимом элемента" - это ключевое слово пока не очень хорошо поддерживается, поэтому его трудно проверить, а ещё труднее узнать что делают его братья min-content , max-content и fit-content .

Item { flex-basis: | auto; /* по умолчанию auto */ }

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

flex

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

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

align-self


Это свойство позволяет переопределить выравнивание по умолчанию (или заданное с помощью свойства ) для отдельных flex-элементов.

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

Item { align-self: auto | flex-start | flex-end | center | baseline | stretch; } .item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }

Обратите внимание, что float , clear и vertical-align не оказывают никакого влияния на flex-элемент.

Примеры

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

Parent { display: flex; height: 300px; } .child { width: 100px; height: 100px; margin: auto; }

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

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

Flex-container { display: flex; flex-flow: row wrap; justify-content: space-around; }

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

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

Navigation { display: flex; flex-flow: row wrap; justify-content: flex-end; } @media all and (max-width: 800px) { .navigation { justify-content: space-around; } } @media all and (max-width: 500px) { .navigation { flex-direction: column; } }

Давайте попробуем сделать что-нибудь ещё лучше, играясь с гибкостью наших flex-элементов! Как насчёт трёхколоночного mobile-first макета с шапкой и футером на всю ширину экрана, и чтобы не было зависимости от исходного порядка элементов.

Wrapper { display: flex; flex-flow: row wrap; } .header, .main, .nav, .aside, .footer { flex: 1 100%; } @media all and (min-width: 600px) { .aside { flex: 1 auto; } } @media all and (min-width: 800px) { .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } }

Связанные свойства

Ошибки

Безусловно Flexbox не без ошибок. Лучшая коллекция, которую я видел представлена Philip Walton и Greg Whitworth"s Flexbugs . Это Open Source место для отслеживания всех ошибок, поэтому я думаю, что лучше всего просто оставить ссылку.

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-версткой. Подписывайтесь на новости;)