Адаптивная верстка на flexbox. Выравнивание по поперечной оси: align-items и align-self. Многострочная организация блоков внутри flex-контейнера

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Flex-direction

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

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

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

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

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

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

justify-content

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

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

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

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

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

align-items

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

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

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

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

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

Flex-wrap

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

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

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

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

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

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

align-content

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

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

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

Пример align-content: center

flex-flow

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

flex-flow:

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

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

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

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

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

Order

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

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

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

Margin

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

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

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

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

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

align-self

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

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

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

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

flex

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

Flex:

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

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

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

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

flex: initial

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

flex: auto

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

flex: none

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

advanced flex

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

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

visibility

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

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

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

Заключение

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

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

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

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

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

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

Display: Flex

Вот пример страницы:

У нас есть 4 разноцветных div’а разных размеров, которые находятся внутри серого div’а. У каждого div’а есть свойство display: block . Поэтому каждый квадрат занимает всю ширину строки.

Чтобы начать работать с Flexbox, нам нужно сделать наш контейнер flex-контейнером. Делается это так:

#container { display: flex; }

Вроде бы ничего особо и не изменилось - div’ы всего лишь встали в ряд. Но вы сделали что-то действительно мощное. Вы дали вашим квадратам классное свойство, называемое «flex-контекст».

Flex Direction

У flex-контейнера есть две оси: главная ось и перпендикулярная ей.

По умолчанию все предметы располагаются вдоль главной оси: слева направо. Поэтому наши квадраты выровнялись в линию, когда мы применили display: flex . Однако flex-direction позволяет вращать главную ось.

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

Важно заметить, что flex-direction: column не выравнивает квадраты по оси, перпендикулярной главной. Главная ось сама меняет свое расположение и теперь направлена сверху вниз.

Есть еще парочка свойств для flex-direction: row-reverse и column-reverse .


Justify Content

Justify-content отвечает за выравнивание элементов по главной оси.

Вернемся к flex-direction: row .

#container { display: flex; flex-direction: row; justify-content: flex-start; }

Justify-content может принимать 5 значений:

  1. flex-start ;
  2. flex-end ;
  3. center ;
  4. space-between ;
  5. space-around .

Space-between задает одинаковое расстояние между квадратами, но не между контейнером и квадратами. Space-around также задает одинаковое расстояние между квадратами, но теперь расстояние между контейнером и квадратами равно половине расстояния между квадратами.

Align Items

Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси.

Вернемся обратно к flex-direction: row и пройдемся по командам align-items:

  1. flex-start ;
  2. flex-end ;
  3. center ;
  4. stretch ;
  5. baseline .

Стоит заметить, что для align-items: stretch высота квадратов должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится вот так:

Чтобы получше разобраться в том, как работают оси, давайте объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction:

Align Self

Align-self позволяет выравнивать элементы по отдельности.

#container { align-items: flex-start; } .square#one { align-self: center; } // Only this square will be centered.

Давайте для двух квадратов применим align-self , а для остальных применим align-items: center и flex-direction: row .

Flex-Basis

Flex-basis отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами Flexbox:

Flex-basis влияет на размер элементов вдоль главной оси.

Давайте посмотрим, что случится, если мы изменим направление главной оси:

Заметьте, что нам пришлось изменить и высоту элементов. Flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.

Flex Grow

Это свойство немного сложнее.

Для начала давайте зададим нашим квадратикам одинаковую ширину в 120px:

По умолчанию значение flex-grow равно 0. Это значит, что квадратам запрещено расти (занимать оставшееся место в контейнере).

Попробуем задать flex-grow равным 1 для каждого квадрата:

Квадраты заняли оставшееся место в контейнере. Значение flex-grow аннулирует значение ширины.

Но здесь возникает один вопрос: что значит flex-grow: 1 ?

Попробуем задать flex-grow равным 999:

И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные.

Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим квадратам:

Вначале flex-grow каждого квадрата равен 1, в сумме получится 6. Значит, наш контейнер поделен на 6 частей. Каждый квадрат будет занимать 1/6 часть доступного пространства в контейнере.

Когда flex-grow третьего квадрата становится равным 2, контейнер делится на 7 частей (1 + 1 + 2 + 1 + 1 + 1).

Теперь третий квадрат занимает 2/7 пространства, остальные - по 1/7.

Стоит помнить, что flex-grow работает только для главной оси (пока мы не поменяем ее направление).

Flex Shrink

Flex-shrink - прямая противоположность flex-grow . Оно определяет, насколько квадрату можно уменьшиться в размере.

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

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

Зададим flex-grow и flex-shrink равными 1:

Теперь давайте поменяем значение flex-shrink для третьего квадрата на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:

Стоит помнить что flex-shrink основывается на пропорциях. То есть, если у квадрата flex-shrink равен 6, а у остальных он равен 2, то, это значит, что наш квадрат будет сжиматься в три раза быстрее, чем остальные.

Flex

Flex заменяет flex-grow , flex-shrink и flex-basis .

Значения по умолчанию: 0 (grow) 1 (shrink) и auto (basis) .

Создадим два квадрата:

Square#one { flex: 2 1 300px; } .square#two { flex: 1 2 300px; }

У обоих квадратов одинаковый flex-basis . Это значит, что они оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding).

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

Как вещи растут и сжимаются

Когда увеличивается первый квадрат, он не становится в два раза больше второго квадрата, и когда уменьшается второй квадрат, он не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.

Немного математики

Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding, и у нас останется 600px, как раз для двух квадратов.

Когда ширина контейнера становится равной 430px (потеря в 210px), первый квадрат (flex-shrink: 1) теряет 70px. Второй квадрат (flex-shrink: 2) теряет 140px.

Когда контейнер сжимается до 340px, мы теряем 300px. Первый квадрат теряет 100px, второй - 200px.

Тоже самое происходит и с flex-grow .

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; }

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то