В этой статье мы подробно рассмотрим, что на самом деле происходит при добавлении правила 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  – наоборот. Но все не так просто!

В модели Flexbox строки не всегда идут слева направо, а столбцы – снизу вверх.

Направление письма

Английский язык (как и русский) имеет горизонтальное направление письма. Это значит, что флексбокс-ряд соответствует обычной горизонтальной строке. В этом случае 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 комментарий

Оставить комментарий

*Доступные HTML-теги: a, abbr, blockquote, code, pre, del, i, em, strong, b, strike
*Не будет опубликован