Выравнивание элементов во Flex контейнере
=========================================

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

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство `align-items`. Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство `justify-content`.

![A containing element with another box centered inside it.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align1.png)

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

Свойства управления выравниванием
---------------------------------

В этом руководстве рассматриваются следующие свойства:

* `justify-content` — управляет выравниванием элементов по главной оси.
* `align-items` — управляет выравниванием элементов по перекрёстной оси.
* `align-self` — управляет выравниванием конкретного flex элемента по перекрёстной оси.
* `align-content` — описывается в спецификации как "упаковка flex строк"; управляет промежутками между flex строками по перекрёстной оси.

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

**Примечание:** Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

Перекрёстная ось
----------------

Свойства `align-items` и `align-self` управляют выравниванием flex элементов по перекрёстной оси: вертикальной для `flex-direction` установленным в `row,` и горизонтальной для `flex-direction` установленным в `column`.

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить `display: flex` у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

![Three items, one with additional text causing it to be taller than the others.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align2.png)

![Three items stretched to 200 pixels tall](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align3.png)

Все элементы становятся одной высоты, т.к. по умолчанию свойство `align-items` имеет значение `stretch`.

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

* `align-items: flex-start`
* `align-items: flex-end`
* `align-items: center`
* `align-items: stretch`
* `align-items: baseline`

В примере ниже значение свойств `align-items` установлено в `stretch`. Попробуйте другие значения для понимания их действия.

### Выравнивание одного элемента при помощи `align-self`

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

В следующем примере, у flex контейнера установлено `align-items: flex-start`, означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью селектора `first-child` установлено `align-self: stretch`; у следующего элемента с классом `selected` установлено `align-self: center`. Можно изменять значение `align-items` на контейнере или `align-self` на элементе для изучения их работы.8н

### Изменение основной оси

До сего момента мы изучали поведение при `flex-direction` установленном в `row`, в языке, использующем написание сверху вниз. Это означает, что основная ось идёт горизонтально, а выравнивание по перекрёстной оси сдвигает элементы вверх или вниз.

![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align4.png)

Если изменить `flex-direction` на column, `align-items` и `align-self` будут сдвигать элементы влево или вправо.

![Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align5.png)

Можно попробовать пример ниже, где установлено `flex-direction: column`.

Выравнивание содержимого по перекрёстной оси — свойство align-content
---------------------------------------------------------------------

До сих пор мы выравнивали элементы внутри flex-контейнера. Если содержимое вашего flex контейнера переносится на несколько строк, используйте свойство `align-content` для управления свободным пространством между строками. В спецификации это описано как упаковка flex-строк.

Чтобы свойство `align-content` работало, необходимо, чтобы в flex-контейнере было больше места, что требуется для отображения всего содержимого. Оно применяется ко всем элементам как группе, и управляет распределением свободного места и положением всей группы элементов внутри контейнера.

Свойство `align-content` принимает следующие значения:

* `align-content: flex-start`
* `align-content: flex-end`
* `align-content: center`
* `align-content: space-between`
* `align-content: space-around`
* `align-content: stretch`
* `align-content: space-evenly` (не описано в спецификации Flexbox)

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение `align-content` установлено в `space-between`, означающее, что свободное пространство разделено *между* строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

Попробуйте другие значения `align-content` для понимания принципа их работы.

Также можно сменить значение `flex-direction` на `column` и увидеть, как наше свойство работает в режиме колонок. Как и ранее, что увидеть работу свойства, у контейнера должно быть больше свободного места, чем требуется содержимому.

**Примечание:** значение `space-evenly` не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

В документации по `justify-content` на MDN приведено больше деталей о всех значениях и поддержке браузерами.

Выравнивание содержимого по главной оси
---------------------------------------

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — `justify-content`. Это обусловлено тем, что с элементами на главной оси мы работаем только как с группой. Используя свойство `justify-content`, мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

В нашем первом примере с использованием свойства `display: flex`, применённым к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство `justify-content` имеет начальное значение `flex-start`. Все свободное место располагается в конце контейнера.

![Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align6.png)

Свойство `justify-content` может принимать те же самые значения, что и `align-content`.

* `justify-content: flex-start`
* `justify-content: flex-end`
* `justify-content: center`
* `justify-content: space-between`
* `justify-content: space-around`
* `justify-content: stretch`
* `justify-content: space-evenly` (не определено в спецификации Flexbox)

В примере ниже, свойству `justify-content` задано значение `space-between`. Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

Если свойство `flex-direction` имеет значение `column`, то свойство `justify-content` распределит доступное пространство в контейнере между элементами.

### Выравнивание и режим записи

Необходимо помнить, что при использовании свойств `flex-start` и `flex-end` элементы позиционируются в режиме записи. Если свойству `justify-content` задано значение `start` и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

![Three items lined up on the left](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics5.png)

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

![Three items lined up from the right](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics6.png)

В примере ниже свойству `property` задано значение `rtl`, которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства `justify-content`, чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

Выравнивание и гибкое-направление
---------------------------------

Начальное положение элементов поменяется, если вы измените значение свойства `flex-direction` — например установите `row-reverse` вместо `row`.

В следующем примере заданы следующие свойства: `flex-direction: row-reverse` и `justify-content: flex-end`. В языках с параметром записи `ltr` все элементы будут отображаться с левой стороны. Попробуйте изменить свойство `flex-direction: row-reverse` на `flex-direction: row`. Вы увидите, что теперь элементы отображаются реверсивно.

Может показаться немного запутанным, но главное правило, которое необходимо запомнить – до тех пор, пока вы не измените свойство `flex-direction`, элементы контейнера выстраиваются в режиме записи вашего языка (`ltr` или `rtl`).

![Diagram showing start on the left and end on the right.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align8.png)

Вы можете сделать отображение элементов контейнера блочным, задав свойству `flex-direction` значение `column`. Свойство `flex-start` будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

![Diagram showing start at the top and end at the bottom.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align10.png)

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

![Diagram showing start on the right and end on the left.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align9.png)

![Diagram showing end at the top and start at the bottom](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align11.png)

Использование авто отступов для выравнивания по главной оси
-----------------------------------------------------------

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

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

На первый взгляд может показаться, что этот пример использования свойства `justify-self`. Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать `justify-self` на элементе *d*, это также изменило бы выравнивание следующего элемента — *e*, что может противоречить первоначальному замыслу.

![Five items, in two groups. Three on the left and two on the right.](/ru/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align7.png)

Вместо этого мы можем выбрать четвёртый элемент (*d*) и отделить его от первых трёх, задав ему значение `auto` для `margin-left`. Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом работает `margin-right`. Оба свойства со значениями `auto` отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс `push` с заданным `margin-left: auto`. Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод.

Будущие функции выравнивания для Flexbox
----------------------------------------

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения `space-evenly` для свойств `align-content` и `justify-content`.

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как `column-gap` and `row-gap`, как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать `column-gap` и `row-gap` во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

Моё предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

Смотрите Также

* Выравнивание Коробки
* Выравнивание Коробки в Flexbox (Гибкая Коробка)
* Выравнивание Коробки в Grid Layout (Макет Сетки)