Flex-элементы

Часть 2

| Категории: CSS
Eleonora Pavlova


Иллюстрация блокнота


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

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

order

Иллюстрация блокнота

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

1
2
3
.item {
order: <integer>; /*любое ваше число*/
}

flex-grow

Иллюстрация блокнота

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

1
2
3
.item {
flex-grow: <число>; /* по умолчанию 0 */
}

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

flex-shrink

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

1
2
3
.item {
flex-shrink: <число>; /* по умолчанию 1 */
}

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

flex-basis

Определяет размер элемента по умолчанию до распределения свободного места в контейнере. Задаёт ширину или высоту элемента — в зависимости от указанного направления flex-direction.

1
2
3
.item {
flex-basis: <величина> | auto; /* по умолчанию auto */
}

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

flex

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

1
2
3
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'> || <'flex-basis'> ]
}

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

align-self

Иллюстрация блокнота

Это свойство задаёт выравнивание по перпендикулярной оси конкретному flex-элементу — и переопределяет указанное ранее для контейнера свойство align-items (возможные значения такие же - см. в разделе «Свойства flex-контейнера»).

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

Имейте в виду, что свойства float, clear и vertical-align не работают для flex-элементов.

Перейдём к примерам

Начнём с примера, решаюшего тривиальную задачу — идеальное центрирование. С flexbox это просто:

1
2
3
4
5
6
7
8
9
10
.parent {
display: flex;
height: 300px; /* любое ваше значение */
}
.child {
width: 100px; /* любое ваше значение */
height: 100px; /* любое ваше значение */
margin: auto; /* магия! */
}

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

Другой пример. Рассмотрим список из 6 элементов, в эстетических целях всем заданы фиксированные размеры, хотя они могли быть и не указаны. Нам нужно, чтобы элементы были красиво выравнены по горизонтальной оси так, чтобы при изменении размера браузера, всё оставалось по-прежнему красивым (без @media queries):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.flex-container {
/* Создаём flex контекст */
display: flex;
/* Определяем направление и указываем, могут ли блоки переноситься
* Помните, это короткий вариант записи, то же самое, что отдельно указать
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Далее указываем, как будет распределяться свободное пространство */
justify-content: space-around;
}

Готово. Остальное — вопрос дизайна. Ниже вставлен пример с codepen с данным кодом. Не поленитесь, сходите на Codepen, и поиграйтесь с размерами вашего браузера:

See the Pen Demo Flexbox 1 by Hugo Giraudel (@HugoGiraudel) on CodePen.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* большие экраны */
.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 {
/* Указываем направление column для выстраивания элементов в столбик*/
flex-direction: column;
}
}

See the Pen Demo Flexbox 2 by Hugo Giraudel (@HugoGiraudel) on CodePen.

Поиграемся с гибкостью flex-элементов. Нам нужен макет из трёх колонок, с полноразмерным header и footer, и порядком, отличным от указанного в html-коде. Выстраиваем макет по принципу mobile-first:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
.wrapper {
display: flex;
flex-flow: row wrap;
}
/* Задаём всем элементам ширину 100% */
.header, .main, .nav, .aside, .footer {
flex: 1 100%;
}
/* В подходе mobile-first порядок следования элементов совпадает с указанным в html-документе
* в нашем случае:
* 1. header
* 2. nav
* 3. main
* 4. aside
* 5. footer
*/
/* средние экраны */
@media all and (min-width: 600px) {
/* Указываем свойство flex, чтобы оба сайдбара выстроились в один ряд */
.aside { flex: 1 auto; }
}
/* большие экраны */
@media all and (min-width: 800px) {
/* Меняем порядок следования первого сайдбара и main
* И задаём элементу main ширину в два раза больше ширины сайдбаров
*/
.main { flex: 2 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}

See the Pen Demo Flexbox 3 by Hugo Giraudel (@HugoGiraudel) on CodePen.

Префиксы для Flexbox

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

Проще всего обойти это неудобство, используя новый (и окончательный) синтаксис в связке с Autoprefixer .

Или, в качестве альтернативы, можно использовать приведённый ниже Sass @mixin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}

Баги

Есть у Flexbox и ошибки. Наиболее полный их перечень можно найти у Филиппа Уолтона и Грега Витворта по ссылке.

Браузерная поддержка

разбита по «версиям» flexbox:

новая (подразумевает последний синтаксис спецификации — напр., display: flex;)
промежуточная (неофициальный синтаксис 2011 года — напр., display: flexbox;)
старая (старый синтаксис 2009 года — напр., display: box;)

Иллюстрация блокнота

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

Более полная информация о том, какой синтаксис лучше использовать для наиболее полной поддержки, можно изучить эту и эту статьи.

Дополнительная информация (англ источники)

Flexbox in the CSS specifications

Flexbox at MDN

Flexbox at Opera

Diving into Flexbox by Bocoup

Mixing syntaxes for best browser support on CSS-Tricks

Flexbox by Raphael Goetter (FR)

Flexplorer by Bennett Feely