web-разработка

CSS flexbox

CSS flexbox (Flexible Box Layout Module) — модуль макета гибкого контейнера — представляет собой способ компоновки элементов, в основе лежит идея оси.
Flexbox состоит из гибкого контейнера (flex container) и гибких элементов (flex items).
Гибкие элементы могут выстраиваться в строку или столбик, а оставшееся свободное пространство распределяется между ними различными способами.
Модуль flexbox позволяет решать следующие задачи:
  1. Располагать элементы в одном из четырех направлений: слева направо, справа налево, сверху вниз или снизу вверх;
  2. Переопределять порядок отображения элементов;
  3. Автоматически определять размеры элементов таким образом, чтобы они вписывались в доступное пространство;
  4. Решать проблему с горизонтальным и вертикальным центрированием;
  5. Переносить элементы внутри контейнера, не допуская его переполнения;
  6. Создавать колонки одинаковой высоты;
  7. Создавать прижатый к низу страницы подвал сайта.
Основная идея flexbox состоит в том, чтобы дать контейнеру возможность изменять ширину / высоту его элементов (и порядок), чтобы наилучшим образом заполнить доступное пространство (главным образом, для отображения на всех типах устройств с любым размером экрана).
Flex контейнер расширяет элементы, чтобы заполнить доступное свободное пространство, или сжимает их, чтобы предотвратить переполнение.

Основные понятия

FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).
Главная ось — главное направление движения элементов внутри контейнера. Направление главной оси можно изменить с помощью свойства flex-direction.

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

Начало и конец главной оси — элементы располагаются от начала и до конца контейнера.

Поперечная ось — направление движения элементов, когда они не умещаются в контейнер по направлению главной оси. Поперечная ось всегда перпендикулярна (⊥) главной.

Начало и конец поперечной оси — по поперечной оси заполняются ряды от начала и до конца контейнера.

Размер (главный и поперечный) — базовая величина по которой высчитывается ширина или высота внутренних элементов, если размер указан не точно (указан в процентах или не указан вообще, а элемент должен растянуться или сжаться).

Для включения flexbox, любому HTML элементу достаточно присвоить CSS свойство display:flex; или display:inline-flex;. Пример:
<style>
	.flex{ display: flex; }
</style>
<div class="flex">
	<div class="item">1</div>
	<div class="item">2</div>
</div>
После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси.
По умолчанию главная ось горизонтальная и имеет направление слева направо (→), а кросс ось соответственно вертикальная и направлена сверху вниз (↓).

Flex-контейнер

Flex-контейнер устанавливает новый гибкий контекст форматирования для его содержимого. Flex-контейнер не является блочным контейнером, поэтому для дочерних элементов не работают такие CSS-свойства, как float, clear, vertical-align.
Также, на flex-контейнер не оказывают влияние свойства column-*, создающие колонки в тексте и псевдоэлементы ::first-line и ::first-letter.

Flex-элементы

Flex-элементы — блоки, представляющие содержимое flex-контейнера в потоке. Flex-контейнер устанавливает новый контекст форматирования для своего содержимого, который обуславливает следующие особенности:
1. Для flex-элементов блокируется их значение свойства display. Значение display: inline-block; и display: table-cell; вычисляется в display: block;.
2. Пустое пространство между элементами исчезает: оно не становится своим собственным flex-элементом, даже если межэлементный текст обернут в анонимный flex-элемент. Для содержимого анонимного flex-элемента невозможно задать собственные стили, но оно будет наследовать их (например, параметры шрифта) от flex-контейнера.
3. Абсолютно позиционированный flex-элемент не участвует в компоновке гибкого макета.
4. Поля margin соседних flex-элементов не схлопываются.
5. Процентные значения margin и padding вычисляются от внутреннего размера содержащего их блока.
6. margin: auto; расширяются, поглощая дополнительное пространство в соответствующем измерении. Их можно использовать для выравнивания или раздвигания смежных flex-элементов.
7. Автоматический минимальный размер flex-элементов по умолчанию является минимальным размером его содержимого, то есть min-width: auto;. Для контейнеров с прокруткой автоматический минимальный размер обычно равен нулю.

CSS свойства Flexbox

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

Для контейнера

display:

Включает flex свойство для элемента. Под это свойство попадает сам элемент и вложенные в него элементы: затрагиваются только потомки первого уровня — они станут элементами flex контейнера.
  1. flex — элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
  2. inline-flex — элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный.
Пример:
.container {
  display: flex;
}

flex-direction:

Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.
  1. row (default) — направление элементов слева направо (→);
  2. column — направление элементов сверху вниз (↓);
  3. row-reverse — направление элементов справа налево (←);
  4. column-reverse — направление элементов снизу вверх (↑).
Пример:
.container {
  flex-direction: row | row-reverse | column | column-reverse;
}

flex-wrap:

Управляет переносом непомещающихся в контейнер элементов.
  1. nowrap (default) — вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет;
  2. wrap — включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси;
  3. wrap-reverse — тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).
Пример:
.container{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

flex-flow: direction wrap

Объединяет оба свойства flex-direction и flex-wrap. Они часто используются вместе, поэтому чтобы писать меньше кода было создано свойство flex-flow.
flex-flow принимает значения двух этих свойств, разделенные пробелом. Или можно указать одно значение любого свойства. Пример:
/* только flex-direction */
flex-flow: row;
flex-flow: row-reverse;
flex-flow: column;
flex-flow: column-reverse;

/* только flex-wrap */
flex-flow: nowrap;
flex-flow: wrap;
flex-flow: wrap-reverse;

/* сразу оба значения: flex-direction и flex-wrap */
flex-flow: row nowrap;
flex-flow: column wrap;
flex-flow: column-reverse wrap-reverse;

justify-content:

Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.
  1. flex-start (default) — элементы будут идти с начала (в конце может остаться место);
  2. flex-end — элементы выравниваются по концу (место останется в начале);
  3. center — по центру (место останется слева и права);
  4. space-between — крайние элементы прижимаются к краям (место между элементами распределяется равномерно);
  5. space-around — свободное пространство равномерно распределяется между элементами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда;
  6. space-evenly — тоже что space-around, только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
Пример:
.container {
  justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}

align-content:

Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что justify-content только для противоположной оси. Работает только когда высота контейнера фиксированная (выше чем ряды внутри него).
  1. stretch (default) — ряды растягиваются заполняя строку полностью;
  2. flex-start — ряды группируются в верхней части контейнера (в конце может остаться место);
  3. flex-end — ряды группируются в нижней части контейнера (место останется в начале);
  4. center — ряды группируются по центру контейнера (место останется по краям);
  5. space-between — крайние ряды прижимаются к краям (место между рядами распределяется равномерно);
  6. space-around — свободное пространство равномерно распределяется между рядами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда;
  7. space-evenly — тоже что space-around, только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
Пример:
.container {
  align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}

align-items:

Выравнивает элементы по поперечной оси внутри ряда (невидимой строки). Т.е. сами ряды выравниваются через align-content, а элементы внутри этих рядов (строк) через align-items и все это по поперечной оси.
По главной оси такого разделения нет, там нет понятия рядов и элементы выравниваются через justify-content.
  1. stretch (default) — элементы растягиваются заполняя строку полностью;
  2. flex-start — элементы прижимаются к началу ряда;
  3. flex-end — элементы прижимаются к концу ряда;
  4. center — элементы выравниваются по центру ряда;
  5. baseline — элементы выравниваются по базовой линии текста.
Пример:
.container {
  align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}

Для элементов контейнера

flex-grow:

Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию flex-grow: 0 т.е. никакой из элементов не должен увеличиваться и заполнять свободное место в контейнере.
Рассмотрим примеры:
  1. Если всем элементам указать flex-grow:1, то все они растянуться одинаково и заполнять все свободное место в контейнере;
  2. Если одному из элементов указать flex-grow:1, то он заполнит все свободное место в контейнере и выравнивания через justify-content работать уже не будут: свободного места нет выравнивать нечего…;
  3. При flex-grow:1. Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные;
  4. Если все flex-блоки внутри flex-контейнера имеют flex-grow:3, то они будут одинакового размера;
  5. При flex-grow:3. Если один из них имеет flex-grow:12, то он будет в 4 раза больше, чем все остальные.
Пример:
.item {
  flex-grow: <number>; /* по умолчанию 0 */
}

flex-shrink:

Задает коэффициент уменьшения элемента. Свойство противоположное flex-grow и определяет как элемент должен сжиматься, если в контейнере не остается свободного места.
т.е. свойство начинает работать, когда сумма размеров всех элементов больше чем размер контейнера.
Пример:
.item {
  flex-shrink: <number>; /* по умолчанию 1 */
}

flex-basis:

Устанавливает базовую ширину элемента — ширину до того как будут высчитаны остальные условия влияющие на ширину элемента.
Значение можно указать в px, em, rem, %, vw, vh и т.д. Итоговая ширина будет зависеть от базовой ширины и значений flex-grow, flex-shrink и контента внутри блока.
При auto элемент получает базовую ширину относительно контента внутри него. Пример:
.item {
  flex-basis: <length> | auto; /* по умолчанию auto */
}

flex: {grow shrink basis}

Короткая запись трех свойств: flex-grow flex-shrink flex-basis. Пример:
.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

align-self:

Позволяет изменить свойство align-items, только для отдельного элемента.
  1. stretch — элемент растягиваются заполняя строку полностью;
  2. flex-start — элемент прижимаются к началу строки;
  3. flex-end — элемент прижимаются к концу строки;
  4. center — элемент выравниваются по центру строки;
  5. baseline — элемент выравниваются по базовой линии текста.
Пример:
.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

order:

Позволяет менять порядок (позицию, положение) элемента в общем ряду.
По умолчанию элементы имеют order: 0 и ставятся в порядке их появления в HTML коде и направления ряда. Но если изменить значение свойства order, то элементы будут выстраиваться в порядке значений: -1 0 1 2 3.
Например если одному из элементов указать order: 1, то сначала будут идти все нулевые, а потом элемент с 1. Пример:
.item {
  order: <integer>; /* по умолчанию 0 */
}
Самоучитель по CSS