We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

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

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

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

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

A containing element with another box centered inside it.

 

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

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

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

  • 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.

Three items stretched to 200 pixels tall

Все элементы становятся одной высоты, т.к. по умолчание свойство 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-items: stretch; у следующего элемента с классом selected установлено align-self: center. Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.

 

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

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

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

Если изменить 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.

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

Aligning content on the main axis

Now that we have seen how alignment works on the cross axis, we can take a look at the main axis. Here we only have one property available to us — justify-content. This is because we are only dealing with items as a group on the main axis. With justify-content we control what happens with available space, should there be more space than is needed to display the items.

In our initial example with display: flex on the container, the items display as a row and all line up at the start of the container. This is due to the initial value of justify-content being flex-start. Any available space is placed at the end of the items.

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

The justify-content property accepts the same values as 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 (not defined in the Flexbox specification)

In the example below, the value of justify-content is space-between. The available space after displaying the items is distributed between the items. The left and right item line up flush with the start and end.

 

If the main axis is in the block direction because flex-direction is set to column, then justify-content will distribute space between items in that dimension as long as there is space in the flex container to distribute.

 

Alignment and Writing Modes

Remember that with all of these alignment methods, the values of flex-start and flex-end are writing mode-aware. If the value of justify-content is start and the writing mode is left-to-right as in English, the items will line up starting at the left side of the container.

Three items lined up on the left

However if the writing mode is right-to-left as in Arabic, the items will line up starting at the right side of the container.

Three items lined up from the right

The live example below has the direction property set to rtl to force a right-to-left flow for our items. You can remove this, or change the values of justify-content to see how flexbox behaves when the start of the inline direction is on the right.

 

Alignment and flex-direction

The start line will also change if you change the flex-direction property — for example using row-reverse instead of row.

In this next example I have items laid out with flex-direction: row-reverse and justify-content: flex-end. In a left to right language the items all line up on the left. Try changing flex-direction: row-reverse to flex-direction: row. You will see that the items now move to the right hand side.

 

While this may all seem a little confusing, the rule to remember is that unless you do something to change it, flex items lay themselves out in the direction that words are laid out in the language of your document along the inline, row axis. flex-start will be where the start of a sentence of text would begin.

Diagram showing start on the left and end on the right.

You can switch them to display in the block direction for the language of your document by selecting flex-direction: column. Then flex-start will then be where the top of your first paragraph of text would start.

Diagram showing start at the top and end at the bottom.

If you change flex-direction to one of the reverse values, then they will lay themselves out from the end axis and in the reverse order to the way words are written in the language of your document. flex-start will then change to the end of that axis — so to the location where your lines would wrap if working in rows, or at the end of your last paragraph of text in the block direction.

Diagram showing start on the right and end on the left.

Diagram showing end at the top and start at the bottom

Using auto margins for main axis alignment

We don’t have a justify-items or justify-self property available to us on the main axis as our items are treated as a group on that axis. However it is possible to do some individual alignment in order to separate an item or a group of items from others by using auto margins along with flexbox.

A common pattern is a navigation bar where some key items are aligned to the right, with the main group on the left. You might think that this should be a use case for a justify-self property, however consider the image below. I have three items on one side and two on the other. If I were able to use justify-self on item d, it would also change the alignment of item e that follows, which may or may not be my intention.

Five items, in two groups. Three on the left and two on the right.

Instead we can target item 4 and separate it from the first three items by giving it a margin-left value of auto. Auto margins will take up all of the space that they can in their axis — it is how centering a block with margin auto left and right works. Each side tries to take as much space as it can, and so the block is pushed into the middle.

In this live example, I have flex items arranged simply into a row with the basic flex values, and the class push has margin-left: auto. You can try removing this, or adding the class to another item to see how it works.

 

Future alignment features for Flexbox

At the beginning of this article I explained that the alignment properties currently contained in the Level 1 flexbox specification are also included in Box Alignment Level 3, which may well extend these properties and values in the future. We have already seen one place where this has happened, with the introduction of the space-evenly value for align-content and justify-content properties.

The Box Alignment module also includes other methods of creating space between items, such as the column-gap and row-gap feature as seen in CSS Grid Layout. The inclusion of these properties in Box Alignment means that in future we should be able to use column-gap and row-gap in flex layouts too. This will mean you won’t need to use margins to space out flex items.

My suggestion when exploring flexbox alignment in depth is to do so alongside looking at alignment in Grid Layout. Both specifications use the alignment properties as detailed in the Box Alignment specification. You can see how these properties behave when working with a grid in the MDN article Box Alignment in Grid Layout, and I have also compared how alignment works in these specifications in my Box Alignment Cheatsheet.

Метки документа и участники

Внесли вклад в эту страницу: dubtar
Обновлялась последний раз: dubtar,