В этой статье мы подробно рассмотрим, что на самом деле происходит при добавлении правила display: flex
в таблицу стилей.
Flex-контейнер, пожалуйста!
Чтобы использовать флексбоксы, необходимо сначала создать флекс-контейнер. Для этого используется инструкция display: flex
.
See the Pen Smashing Flexbox Series 1: display: flex; by rachelandrew (@rachelandrew) on CodePen.
Что же на самом деле значит display: flex
. В спецификации Display Module Level 3 каждое значение свойства display
описывается как комбинация двух моделей поведения: внутренней и внешней. Когда мы устанавливаем display: flex
, на самом деле это значит display: block flex
. То есть внешний тип отображения контейнера block
, и он ведет себя как обычный блочный элемент в нормальном потоке. Внутренний тип отображения – flex
, поэтому его прямые потомки придерживаются правил флекс-раскладки.
Можно также определить тип отображения inline-flex
, что будет означать display: inline flex
, то есть сам элемент будет вести себя как строчный, а внутри ничего не изменится. Дети инлайн-флексового контейнера ведут себя точно так же, как дети блочно-флексового.
See the Pen Smashing Flexbox Series 1: display: inline-flex; by rachelandrew (@rachelandrew) on CodePen.
Ряды или колонки?
С контейнером определились, теперь поговорим о некоторых стартовых значениях. Если не устанавливать никакие дополнительные свойства, то флекс-элементы выстраиваются в ряд. Это происходит из-за того, что значением по умолчанию для свойства flex-direction
является row
— ряд.
Свойство flex-direction
устанавливает направление главной оси контейнера. Другие значение, которые оно может принимать:
column
row-reverse
column-reverse
Значение row
заставляет элементы выстраиваться один за другим (как в html-коде). По сути ряд ведет себя как обычная строка, идущая слева направо. Место начала строки в спецификации называется main-start
:

Если использовать значение column
, элементы сформируют колонку, которая идет сверху вниз. Это нормальный поток блоков в документе. Соответственно main-start
перемещается наверх.

row-reverse
меняет main-start
и main-end
местами, и элементы выстраиваются в обратном порядке.

columnn-reverse
делает то же самое. Важно запомнить, что эти значения не изменяют порядок элементов, хотя мы видим именно это. Они изменяют место начала потока – main-start
. Таким образом, элементы располагаются в обратном порядке, но это происходит только из-за того, что они стартуют с другого конца контейнера.
Этот эффект чисто визуальный. Как бы ни размещались элементы на экране, объявленный в коде порядок сохраняется и именно он будет использоваться скринридерами.
Две оси
Мы уже раскрыли важную особенность flexbox-системы: возможность переключения главной оси из строки в столбец. Во флексбокс-модели многое зависит от того, с какой именно осью вы работаете.
Главную ось, которую определяет flex-direction
, мы уже видели. Поперечная ось – это другое измерение. Если установлено flex-direction: row
, то главная ось идет горизонтально, а поперечная – вертикально. При flex-direction: column
– наоборот. Но все не так просто!
Направление письма
Английский язык (как и русский) имеет горизонтальное направление письма. Это значит, что флексбокс-ряд соответствует обычной горизонтальной строке. В этом случае main-start
будет слева – там, где в английском (и русском) начинаются предложения.
Если вы работаете с арабским языком (направление письма справа налево), то строка (а вместе с ней и флексбокс-ряд) будет начинаться справа:
See the Pen Smashing Flexbox Series 1: row with rtl text by rachelandrew (@rachelandrew) on CodePen.
В языках с вертикальным направлением письма строки идут сверху вниз и флексбокс-ряды тоже. Попробуйте добавить флекс-контейнеру свойство writing-mode: vertical-lr
и установите flex-direction: row
– вы получаете вертикальный столбец элементов.
See the Pen Smashing Flexbox Series 1: row with a vertical writing mode by rachelandrew (@rachelandrew) on CodePen.
Таким образом, ряд может идти горизонтально, слева или справа, а также вертикально сверху. И это все еще flex-direction: row
, даже если нам, привыкшим к горизонтальному тексту, сложно это понять!
Это измерение строки, а еще есть измерение блоков. Оно соответствует тому, как в тексте размещаются абзацы. В английском, русском и арабском языке – сверху вниз. Расположить флекс-элементы в этом измерении можно с помощью значений column
или column-reverse
для свойства flex-direction
.
При вертикальном направлении письма блочное измерение проходит по горизонтали. Если вы создадите столбец в режиме vertical-lr
, то элементы будут отображаться слева направо:
See the Pen Smashing Flexbox Series 1: column in vertical-lr writing mode by rachelandrew (@rachelandrew) on CodePen.
Независимо от того, как отображаются блоки, если вы работаете со значением column
, вы работаете в блочном измерении.
Очень важно понимать, что расположение флекс-элементов определяется направлением письма конкретного языка.
Узнать о других свойствах CSS, связанных с направлением письма, вы можете в этой статье.
Запомните следующее:
- flex-direction: row
- главная ось — строчное измерение
main-start
— место, где начинается предложение- поперечная ось — блочное измерение
- flex-direction: column
- главная ось — блочное измерение
main-start
— место, где начинаются блоки- поперечная ось — инлайновое измерение
Начальное выравнивание
При установке display: flex
, происходят и другие вещи, например, выравнивание элементов.
Примечание:
Хотя свойства выравнивания появились в спецификации Flexbox, их в конечном итоге заменит Box Alignment specification.
Выравнивание по главной оси
Значение по умолчанию justify-content: flex-start
.
.container {
display: flex;
justify-content: flex-start;
}
Из-за этого флекс-элементы размещаются с начала флекс-контейнера, а если задано row-reverse
– с конца.
Когда вы видите свойство выравнивания, которое начинается с justify-
, знайте, что оно применяется к главной флекс-оси.
Другие возможные значения justify-content
:
flex-end
;center
;space-around
;space-between
;space-evenly
(добавлено в Box Alignment).
Это свойство распределяет свободное место, если оно есть. Но если флекс-контейнер уже плотно упакован, то justify-content
вообще ничего не делает.
Можно увидеть это, если переключить flex-direction
на значение column
. Если не указывать высоту специально, то свободного места на главной оси нет, поэтому установка justify-content: space-between
ничего не даст. Если увеличить высоту, то эффект виден:
See the Pen Smashing Flexbox Series 1: column with a height by rachelandrew (@rachelandrew) on CodePen.
Выравнивание по поперечной оси
Элементы в однострочном контейнере также выравниваются по поперечной оси друг относительно друга. В следующем примере один из блоков содержит больше содержимого, чем все остальные. Что-то подсказывает другим растянуться на ту же высоту. Это свойство align-items
, которое имеет начальное значение stretch
:
See the Pen Smashing Flexbox Series 1: align-items by rachelandrew (@rachelandrew) on CodePen.
Если вы видите свойство выравнивания, которое начинается с align-
, знайте, что оно имеет дело с поперечной осью. Другие значения align-items
:
flex-start
;flex-end
;center
;baseline
;
Если вы не хотите, чтобы элементы растягивались, установите align-items: flex-start
, и они выровняются по началу поперечной оси.
See the Pen Smashing Flexbox Series 1: align-items: flex-start by rachelandrew (@rachelandrew) on CodePen.
Начальные значения для флекс-элементов
И наконец, флекс-элементы имеют следующие значения по умолчанию:
flex-grow: 0
flex-shrink: 0
flex-basis: auto
Это означает, что они не растягиваются, чтобы занять все доступное пространство по главной оси. Если установить для flex-grow
положительное значение, то элементы смогут увеличиваться и занимать больше места.
Также они могут сжиматься, если свойство flex-shrink
имеет положительное значение. При слишком маленькой ширине контейнера блоки уменьшатся, чтобы поместиться в нем. Это логичное поведение, ведь обычно мы хотим, чтобы элементы оставались внутри и не переполняли своего родителя.
flex-basis
по умолчанию имеет значение auto, что значит «достаточно большая ширина, чтобы вмещать контент». Вот как будет выглядеть макет, если один из флекс-элементов имеет больше контента, чем другие:
See the Pen Smashing Flexbox Series 1: initial values of flex items by rachelandrew (@rachelandrew) on CodePen.
Это гибкость Flexbox-системы в действии. Если flex-basis
равен auto
и размер элемента не указан, то его ширина равна max-content
– максимальной ширине контента. Детали механизма распределения свободного пространства можно найти в спецификации.

Flexbox, в конечном итоге, позволяет разумно распределять пространство. Вместо того, чтобы при нехватке места равномерно уменьшить все блоки и получить очень высокий элемент с парой слов в каждой строке, этому элементу выделяется больше места для размещения.
Резюме
Гибкие флекс-макеты поддерживают различные направления письма и позволяют выравнивать элементы на главной и поперечной оси, а также сжимать и растягивать их, перераспределяя пространство контейнера. Модель flex понимает, насколько велик контент, и пытается отобразить его как можно более адаптивно.
1 комментарий