Флексбокс

Подкаст CSS – 010: Flexbox

Шаблон дизайна, который может оказаться непростым в адаптивном дизайне, — это боковая панель, встроенная в некоторый контент. Там, где есть пространство области просмотра, этот шаблон работает отлично, но там, где пространство ограничено, такая жесткая компоновка может стать проблематичной.

Модель макета гибкого блока (flexbox) — это модель макета, предназначенная для одномерного контента. Он отлично справляется с получением набора элементов разного размера и возвращением наилучшего макета для этих элементов.

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

Что можно сделать с помощью гибкого макета?

Гибкие макеты имеют следующие функции, которые вы сможете изучить в этом руководстве.

  • Они могут отображаться как строка или столбец.
  • Они соблюдают режим написания документа.
  • По умолчанию они однострочные, но их можно перенести на несколько строк.
  • Порядок элементов в макете можно визуально изменить, отличаясь от их порядка в DOM.
  • Пространство внутри элементов можно распределить так, чтобы они становились больше и меньше в зависимости от пространства, доступного в их родителе.
  • Пространство можно распределить вокруг элементов и гибких линий в обернутом макете, используя свойства Box Alignment.
  • Сами элементы можно выравнивать по поперечной оси.

Главная ось и поперечная ось

Ключом к пониманию флексбокса является понимание концепции главной и поперечной осей. Основная ось — это та, которая задается вашим свойством flex-direction . Если это row , ваша главная ось расположена вдоль строки, если это column ваша главная ось расположена вдоль столбца.

Три ящика рядом друг с другом со стрелкой, указывающей слева направо. Стрелка обозначена «Главная ось».

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

Поперечная ось проходит в направлении, противоположном главной оси, поэтому, если flex-directionrow , поперечная ось проходит вдоль столбца.

Три коробки разной высоты, расположенные рядом друг с другом со стрелкой, указывающей слева направо. Стрелка обозначена «Главная ось». Есть еще одна стрелка, указывающая сверху вниз. Этот называется «Перекрестная ось».

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

Создание гибкого контейнера

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

<div class="container" id="container">
  <div>One</div>
  <div>Item two</div>
  <div>The item we will refer to as three</div>
</div>

Чтобы использовать flexbox, вам необходимо объявить, что вы хотите использовать контекст гибкого форматирования, а не обычный блок и встроенный макет. Сделайте это, изменив значение свойства display на flex .

.container {
  display: flex;
}

Как вы узнали из руководства по макету , это даст вам блок уровня блока с дочерними элементами. Гибкие элементы сразу же начинают проявлять некоторое поведение флексбокса, используя свои начальные значения .

Начальные значения означают, что:

  • Элементы отображаются в виде строки.
  • Они не заворачиваются.
  • Они не растут, чтобы заполнить контейнер.
  • Они выстраиваются в линию в начале контейнера.

Контроль направления предметов

Даже если вы еще не добавили свойство flex-direction , элементы отображаются в виде строки, поскольку начальное значение flex-directionrow . Если вам нужна строка, вам не нужно добавлять свойство. Чтобы изменить направление, добавьте свойство и одно из четырех значений:

  • row : элементы располагаются в ряд.
  • row-reverse: элементы располагаются в ряд от конца гибкого контейнера.
  • column : элементы располагаются в виде столбца.
  • column-reverse : элементы располагаются в виде столбца с конца гибкого контейнера.

Вы можете опробовать все значения, используя нашу группу элементов в демо-версии ниже.

Изменение потока предметов и доступности

Вы должны быть осторожны при использовании любых свойств, которые изменяют порядок визуального отображения в отличие от того, как все упорядочено в HTML-документе, поскольку это может отрицательно повлиять на доступность. Хорошим примером этого являются значения row-reverse и column-reverse . Изменение порядка происходит только для визуального, а не логического порядка. Это важно понимать, поскольку логический порядок — это порядок, в котором программа чтения с экрана будет считывать содержимое, и которому будет следовать любой, кто использует клавиатуру.

В следующем видео вы можете увидеть, как в макете с обратными строками переход между ссылками отключается, поскольку навигация с помощью клавиатуры следует за DOM, а не за визуальным отображением.

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

Для получения дополнительной информации см.:

Режимы и направление письма

По умолчанию гибкие элементы располагаются в виде строки. Строка идет в направлении движения предложений в вашем режиме письма и направлении сценария. Это означает, что если вы работаете на арабском языке, который имеет направление письма справа налево (rtl), элементы будут выстраиваться справа. Порядок табуляции также будет начинаться справа, поскольку именно так предложения читаются на арабском языке.

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

Поэтому поведение гибких элементов по умолчанию связано с режимом записи документа. Большинство руководств написаны на английском языке или в другом горизонтальном режиме письма слева направо. Это позволит легко предположить, что гибкие элементы располагаются слева и располагаются горизонтально .

Учитывая основную и поперечную ось, а также режим письма, тот факт, что во флексбоксе мы говорим о начале и конце , а не о верхе, низу, левом и правом, может быть легче понять. Каждая ось имеет начало и конец. Начало главной оси называется главным стартом . Таким образом, наши гибкие элементы изначально выстраиваются в линию от основного начала. Конец этой оси — main-end . Начало поперечной оси — это перекрестное начало , а конец — перекрестное начало .

Маркированная диаграмма вышеуказанных терминов

Обертывание гибких элементов

Начальное значение свойства flex-wrapnowrap . Это означает, что если в контейнере недостаточно места, элементы переполнятся.

Гибкий контейнер с девятью элементами внутри. Элементы уменьшились, поэтому одно слово находится в строке, но недостаточно места, чтобы показать их рядом, поэтому гибкие элементы выдвинулись за пределы контейнера.
Как только они достигнут минимального размера содержимого, гибкие элементы начнут переполнять свой контейнер.

Элементы, отображаемые с использованием начальных значений, будут уменьшаться до min-content размера, прежде чем произойдет переполнение.

Чтобы элементы были перенесены, добавьте flex-wrap: wrap в гибкий контейнер.

.container {
  display: flex;
  flex-wrap: wrap;
}

Когда гибкий контейнер обертывается, он создает несколько гибких строк . С точки зрения распределения пространства каждая строка действует как новый гибкий контейнер. Поэтому, если вы переносите строки, невозможно заставить что-то из строки 2 совпадать с чем-то над ним в строке 1. Именно это подразумевается под одномерностью флексбокса. Вы можете управлять выравниванием по одной оси, строке или столбцу, а не по обеим вместе, как мы можем это сделать в сетке.

Сокращение гибкого потока

Вы можете установить свойства flex-direction и flex-wrap используя сокращенную запись flex-flow . Например, чтобы установить flex-direction для column и разрешить перенос элементов:

.container {
  display: flex;
  flex-flow: column wrap;
}

Управление пространством внутри гибких элементов

Предполагая, что в нашем контейнере больше места, чем необходимо для отображения элементов, элементы выстраиваются в линию в начале и не увеличиваются, чтобы заполнить пространство. Они перестают расти при максимальном размере контента. Это связано с тем, что начальное значение свойств flex- :

  • flex-grow: 0 : элементы не растут.
  • flex-shrink: 1 : элементы могут сжиматься меньше, чем их flex-basis .
  • flex-basis: auto : элементы имеют базовый размер auto .

Это может быть представлено значением ключевого слова flex: initial . Сокращенное свойство flex или сокращенные версии flex-grow , flex-shrink и flex-basis применяются к дочерним элементам гибкого контейнера.

Чтобы заставить элементы расти, позволяя при этом большим элементам иметь больше места, чем маленьким, используйте flex:auto . Вы можете попробовать это, используя демо выше. Это устанавливает свойства:

  • flex-grow: 1 : элементы могут вырасти больше, чем их flex-basis .
  • flex-shrink: 1 : элементы могут сжиматься меньше, чем их flex-basis .
  • flex-basis: auto : элементы имеют базовый размер auto .

Использование flex: auto будет означать, что элементы будут иметь разные размеры, поскольку пространство, разделяемое между элементами, распределяется после того, как каждый элемент размещается как максимальный размер содержимого. Так крупный предмет получит больше места. Чтобы заставить все элементы иметь одинаковый размер и игнорировать размер содержимого, измените flex:auto на flex: 1 в демо-версии.

Это распаковывается в:

  • flex-grow: 1 : элементы могут вырасти больше, чем их flex-basis .
  • flex-shrink: 1 : элементы могут сжиматься меньше, чем их flex-basis .
  • flex-basis: 0 : элементы имеют базовый размер 0 .

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

Разрешение предметам расти с разной скоростью

Вам не обязательно присваивать всем элементам коэффициент flex-grow , равный 1 . Вы можете присвоить своим гибким элементам разные факторы flex-grow . В приведенной ниже демонстрации первый элемент имеет flex: 1 , второй flex: 2 и третий flex: 3 . По мере того, как эти элементы увеличиваются с 0 , доступное пространство в гибком контейнере делится на шесть. На первый предмет отдается одна часть, на второй — две части, на третий — три части.

Вы можете сделать то же самое, используя flex-basis auto , хотя вам нужно будет указать три значения. Первое значение — flex-grow , второе flex-shrink и третье flex-basis .

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

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

Изменение порядка гибких элементов

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

Пример ниже демонстрирует этот порядок.

Проверьте свое понимание

Проверьте свои знания flexbox

flex-direction по умолчанию:

row
По умолчанию flexbox помещает элементы в ряд, выстраивая их в начале. Если включена переноска, она продолжит создавать строки, в которых могут перемещаться дочерние элементы.
column
Установка flex-direction для столбца — отличный способ складывать элементы, но это не значение по умолчанию.

По умолчанию гибкий контейнер оборачивает дочерние элементы.

истинный
Перенос должен быть включен.
ЛОЖЬ
Используйте flex-wrap: wrap с display: flex для обертывания дочерних элементов

Гибкий дочерний элемент выглядит сплющенным. Какое гибкое свойство помогает это исправить?

flex-grow
Это свойство описывает, могут ли элементы вырасти за пределы базового размера, а не то, как они должны вести себя под базисом.
flex-shrink
Да, это свойство описывает, как обрабатывать размеры, если ширина становится ниже основания.
flex-basis
Это обеспечивает отправную точку определения размера, но не объясняет, как обрабатывать сценарии изменения размера, когда ширина оказывается ниже базовой, как в сжатом сценарии.

Обзор выравнивания Flexbox

Flexbox принес с собой набор свойств для выравнивания элементов и распределения пространства между ними. Эти свойства были настолько полезны, что с тех пор были вынесены в отдельную спецификацию, и вы встретите их и в Grid Layout. Здесь вы можете узнать, как они работают при использовании flexbox.

Набор свойств можно разделить на две группы. Свойства распределения пространства и свойства выравнивания. Свойства, которые распределяют пространство:

  • justify-content : распределение пространства по главной оси.
  • align-content : распределение пространства по поперечной оси.
  • place-content : сокращение для установки обоих вышеуказанных свойств.

Свойства, используемые для выравнивания во flexbox:

  • align-self : выравнивает один элемент по поперечной оси.
  • align-items : выравнивает все элементы в группу по поперечной оси.

Если вы работаете с главной осью, свойства начинаются с justify- . На поперечной оси они начинаются с align- .

Распределение пространства по главной оси

В HTML, использованном ранее, гибкие элементы расположены в виде строки, на главной оси есть место. Элементы недостаточно велики, чтобы полностью заполнить гибкий контейнер. Элементы выстраиваются в начале гибкого контейнера, поскольку начальное значение justify-contentflex-start . Элементы выстраиваются в линию в начале, а все дополнительное пространство находится в конце.

Добавьте свойство justify-content в flex-контейнер, присвойте ему значение flex-end , и элементы выстроятся в конец контейнера, а свободное пространство разместится в начале.

.container {
  display: flex;
  justify-content: flex-end;
}

Вы также можете распределить пространство между элементами с помощью justify-content: space-between .

Попробуйте некоторые значения в демо-версии и посмотрите полный набор возможных значений в MDN .

С flex-direction: column

Если вы изменили flex-direction на column , то justify-content будет работать с столбцом. Чтобы иметь свободное место в контейнере при работе в качестве столбца, вам нужно указать контейнеру height или block-size . В противном случае у вас не будет свободного места для распространения.

Попробуйте разные значения, на этот раз с макетом столбца flexbox.

Распределение пространства между гибкими линиями

С обернутым гибким контейнером у вас может быть место для распределения по поперечной оси. В этом случае вы можете использовать свойство align-content с теми же значениями, что и justify-content . В отличие от justify-content , который по умолчанию выравнивает элементы по flex-start , начальное значение align-contentstretch . Добавьте свойство align-content в гибкий контейнер, чтобы изменить поведение по умолчанию.

.container {
  align-content: center;
}

Попробуйте это в демо-версии. В примере строки гибких элементов заключены в обертку, а контейнер имеет block-size , чтобы у нас было немного свободного места.

Сокращение place-content

Чтобы установить как justify-content , так и align-content вы можете использовать place-content с одним или двумя значениями. Для обеих осей будет использоваться одно значение, если вы укажете, что первое используется для align-content , а второе — для justify-content .

.container {
  place-content: space-between;
  /* sets both to space-between */
}

.container {
  place-content: center flex-end;
  /* wrapped lines on the cross axis are centered,
  on the main axis items are aligned to the end of the flex container */
}

Выравнивание элементов по поперечной оси

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

Начальное значение align-selfstretch , поэтому элементы flex в строке по умолчанию растягиваются до высоты самого высокого элемента. Чтобы изменить это, добавьте свойство align-self к любому из ваших гибких элементов.

.container {
  display: flex;
}

.item1 {
  align-self: flex-start;
}

Используйте любое из следующих значений для выравнивания элемента:

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

Полный список значений смотрите на MDN .

В следующей демонстрации есть одна строка flex-элементов с flex-direction: row . Последний элемент определяет высоту гибкого контейнера. Первый элемент имеет свойство align-self со значением flex-start . Попробуйте изменить значение этого свойства, чтобы увидеть, как оно перемещается в своем пространстве по поперечной оси.

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

.container {
  display: flex;
  align-items: flex-start;
}

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

Почему во flexbox нет оправдания?

Гибкие элементы действуют как группа на главной оси. Таким образом, не существует концепции выделения отдельного элемента из этой группы.

В макете сетки свойства justify-self и justify-items работают на встроенной оси, обеспечивая выравнивание элементов на этой оси в пределах их области сетки. Из-за того, что гибкие макеты рассматривают элементы как группу, эти свойства не реализуются в гибком контексте.

Стоит знать, что flexbox очень хорошо работает с автоматическими полями. Если вы столкнулись с необходимостью отделить один элемент от группы или разделить группу на две группы, вы можете применить для этого поле. В примере ниже последний элемент имеет левое поле auto . Автоматическое поле поглощает все пространство в том направлении, в котором оно применяется. Это означает, что он сдвигает элемент вправо, разделяя группы.

Как центрировать элемент по вертикали и горизонтали

Свойства выравнивания можно использовать для центрирования элемента внутри другого блока. Свойство justify-content выравнивает элемент по главной оси, то есть по строке. Свойство align-items на поперечной оси.

.container {
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Проверьте свое понимание

Проверьте свои знания flexbox

.container {
  display: flex;
  direction: ltr;
}

Чтобы выровнять по вертикали с помощью flexbox, используйте

выровнять ключевые слова
Хороший
обосновать ключевые слова
Извини
.container {
  display: flex;
  direction: ltr;
}

Чтобы выровнять по горизонтали с помощью flexbox, используйте

выровнять ключевые слова
Извини
обосновать ключевые слова
Хороший
.container {
  display: flex;
  direction: ltr;
}

По умолчанию гибкие элементы выравниваются по stretch . Если вы хотите, чтобы размер содержимого использовался для дочерних элементов, какой из следующих стилей вы бы использовали?

justify-content: flex-start
Свойство justify предназначено для горизонтального выравнивания, а не вертикального.
align-content: start
content выравнивает гибкие линии, а не выравнивание дочерних элементов.
height: auto
Это не будет иметь никакого эффекта.
align-items: flex-start
Да, мы хотим выровнять их по вертикали по «верху» или по началу, что удаляет значение растягивания по умолчанию и вместо этого использует высоту содержимого.

Ресурсы