Подкаст CSS – 010: Flexbox
Шаблон дизайна, который может оказаться непростым в адаптивном дизайне, — это боковая панель, встроенная в некоторый контент. Там, где есть пространство области просмотра, этот шаблон работает отлично, но там, где пространство ограничено, такая жесткая компоновка может стать проблематичной.
Модель макета гибкого блока (flexbox) — это модель макета, предназначенная для одномерного контента. Он отлично справляется с получением набора элементов разного размера и возвращением наилучшего макета для этих элементов.
Это идеальная модель макета для данного шаблона боковой панели. Flexbox не только помогает разместить боковую панель и контент внутри строки, но и там, где осталось недостаточно места, боковая панель перейдет на новую строку. Вместо установки жестких размеров, которым должен следовать браузер, с помощью flexbox вы можете предоставить гибкие границы, чтобы указать, как может отображаться контент.
Что можно сделать с помощью гибкого макета?
Гибкие макеты имеют следующие функции, которые вы сможете изучить в этом руководстве.
- Они могут отображаться как строка или столбец.
- Они соблюдают режим написания документа.
- По умолчанию они однострочные, но их можно перенести на несколько строк.
- Порядок элементов в макете можно визуально изменить, отличаясь от их порядка в DOM.
- Пространство внутри элементов можно распределить так, чтобы они становились больше и меньше в зависимости от пространства, доступного в их родителе.
- Пространство можно распределить вокруг элементов и гибких линий в обернутом макете с помощью свойств Box Alignment.
- Сами элементы можно выравнивать по поперечной оси.
Главная ось и поперечная ось
Ключом к пониманию флексбокса является понимание концепции главной оси и поперечной оси. Основная ось — это та, которая задается вашим свойством flex-direction
. Если это row
ваша главная ось расположена вдоль строки, если это column
ваша главная ось расположена вдоль столбца.
Гибкие элементы перемещаются группой по главной оси. Помните: у нас есть куча вещей, и мы пытаемся создать для них наилучшее расположение как группы.
Поперечная ось проходит в направлении, противоположном главной оси, поэтому, если flex-direction
— row
поперечная ось проходит вдоль столбца.
Вы можете сделать две вещи на поперечной оси. Вы можете перемещать элементы по отдельности или группой, чтобы они выровнялись друг относительно друга и гибкого контейнера. Кроме того, если вы обернули гибкие линии, вы можете рассматривать эти строки как группу, чтобы контролировать, как этим строкам назначается пространство. В этом руководстве вы увидите, как все это работает на практике, а пока просто имейте в виду, что главная ось следует за вашим 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-direction
— row
. Если вам нужна строка, вам не нужно добавлять свойство. Чтобы изменить направление, добавьте свойство и одно из четырех значений:
-
row
: элементы располагаются в ряд. -
row-reverse:
элементы располагаются в ряд от конца гибкого контейнера. -
column
: элементы располагаются в виде столбца. -
column-reverse
: элементы располагаются в виде столбца с конца гибкого контейнера.
Вы можете опробовать все значения, используя нашу группу элементов в демо-версии ниже.
Изменение потока предметов и доступности
Вы должны быть осторожны при использовании любых свойств, которые изменяют порядок визуального отображения в отличие от того, как все упорядочено в HTML-документе, поскольку это может отрицательно повлиять на доступность. Хорошим примером этого являются значения row-reverse
и column-reverse
. Изменение порядка происходит только для визуального, а не логического порядка. Это важно понимать, поскольку логический порядок — это порядок, в котором программа чтения с экрана будет считывать содержимое, и которому будет следовать любой, кто использует клавиатуру.
В следующем видео вы можете увидеть, как в макете с обратными строками переход между ссылками отключается, поскольку навигация с помощью клавиатуры следует за DOM, а не за визуальным отображением.
Все, что может изменить порядок элементов в flexbox или сетке, может вызвать эту проблему. Поэтому любое изменение порядка должно включать тщательное тестирование, чтобы убедиться, что оно не затруднит использование вашего сайта некоторыми людьми.
Для получения дополнительной информации см.:
Режимы и направление письма
По умолчанию гибкие элементы располагаются в виде строки. Строка движется в направлении движения предложений в вашем режиме письма и направлении сценария. Это означает, что если вы работаете на арабском языке, который имеет направление письма справа налево (rtl), элементы будут выстраиваться справа. Порядок табуляции также будет начинаться справа, поскольку именно так предложения читаются на арабском языке.
Если вы работаете с вертикальным режимом письма, как в некоторых японских шрифтах, то строка будет идти вертикально, сверху вниз. Попробуйте изменить flex-direction
в этой демонстрации, в которой используется режим вертикального письма.
Поэтому поведение гибких элементов по умолчанию связано с режимом записи документа. Большинство руководств написаны на английском языке или в другом горизонтальном режиме письма слева направо. Это позволило бы легко предположить, что гибкие элементы располагаются слева и располагаются горизонтально .
Учитывая основную и поперечную ось, а также режим письма, тот факт, что во флексбоксе мы говорим о начале и конце, а не о верхе, низу, левом и правом, может быть легче понять. Каждая ось имеет начало и конец. Начало главной оси называется главным стартом . Таким образом, наши гибкие элементы изначально выстраиваются в линию от основного начала. Конец этой оси — main-end . Начало поперечной оси является поперечным началом , а конец поперечной осью .
Обертывание гибких элементов
Начальное значение свойства flex-wrap
— nowrap
. Это означает, что если в контейнере недостаточно места, элементы переполнятся.
Элементы, отображаемые с использованием начальных значений, будут уменьшаться до 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
по умолчанию:
column
row
По умолчанию гибкий контейнер оборачивает дочерние элементы.
Гибкий дочерний элемент выглядит сплющенным. Какое гибкое свойство помогает это исправить?
flex-basis
flex-shrink
flex-grow
Обзор выравнивания Flexbox
Flexbox принес с собой набор свойств для выравнивания элементов и распределения пространства между ними. Эти свойства были настолько полезны, что с тех пор были вынесены в отдельную спецификацию, и вы встретите их и в Grid Layout. Здесь вы можете узнать, как они работают при использовании flexbox.
Набор свойств можно разделить на две группы. Свойства распределения пространства и свойства выравнивания. Свойства, которые распределяют пространство:
-
justify-content
: распределение пространства по главной оси. -
align-content
: распределение пространства по поперечной оси. -
place-content
: сокращение для установки обоих вышеуказанных свойств.
Свойства, используемые для выравнивания во flexbox:
-
align-self
: выравнивает один элемент по поперечной оси. -
align-items
: выравнивает все элементы в группу по поперечной оси.
Если вы работаете с главной осью, свойства начинаются с justify-
. На поперечной оси они начинаются с align-
.
Распределение пространства по главной оси
В HTML, использованном ранее, гибкие элементы расположены в виде строки, на главной оси есть место. Элементы недостаточно велики, чтобы полностью заполнить гибкий контейнер. Элементы выстраиваются в начале гибкого контейнера, поскольку начальное значение justify-content
— flex-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-content
— stretch
. Добавьте свойство 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-self
— stretch
, поэтому элементы 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
. Если вы хотите, чтобы размер содержимого использовался для дочерних элементов, какой из следующих стилей вы бы использовали?
height: auto
justify-content: flex-start
align-content: start
align-items: flex-start
Ресурсы
- MDN CSS Flexible Box Layout включает в себя серию подробных руководств с примерами.
- Руководство по CSS-трюкам во Flexbox
- Что происходит, когда вы создаете Flexbox-контейнер Flexbox
- Все, что вам нужно знать о выравнивании во Flexbox
- Насколько велика эта гибкая коробка?
- Варианты использования Flexbox
- Проверка и отладка макетов CSS Flexbox в Chrome DevTools