Просто о Flexbox в css
Посмотрим как работать с гибкой сеткой flexbox. Разберем свойства и научимся их применять
Что такое flexbox
flexbox
это способ позиционирования элементов в CSS.
С помощью flexbox
можно быстро и легко описывать, как будет располагаться тот или иной блок на странице.
Элементы выстраиваются по заданной оси и автоматически распределяются согласно настройкам.
flexbox
определяет способность гибкого элемента растягиваться или сжиматься для заполнения собой доступного пространства.
Базовое поведение
По умолчанию все блочные элементы располагаются друг под другом. Это стандартное поведение для блочных элементов.
Базовый пример без использования flexbox
Container
Контейнер - это элемент которому задано css свойство display:flex
или display: inline-flex
.
С этого момента элемент приобретает свойства контейнера.
Особенности
- Контейнеры могут вложены друг в друга.
- Каждый контейнер имеет точки начала и точки конца.
- Дочерние элементы контейнера начинают подчиниться свойствам флекса, но это касается только прямых потомков.
- При
display:flex
снаружи контейнер обычный блочный элемент, который занимает всю ширину родительского элемента. - При
display:inline-flex
снаружи контейнер это строчный элемент, его размеры зависят от его контента.
Основная ось (горизонтальная)
По умолчанию все элементы контейнера располагаются вдоль основной оси слева направо.
Это ось по которой выстраивается поток элементов.
Поперечная ось (перпендикулярная, вертикальная, вспомогательная)
Нужна для того, чтобы понимать куда переносить элементы.
Размер элементов поперечной оси всегда перпендикулярен основному размеру.
Если основной размер - ширина, то поперечный размер - высота, и наоборот.
flex-direction
Свойство управляет направлением элементов основной row
и поперечной осей column
.
Можно менять расположение элементов на оси, но привязка к ней все равно остается.
row
Элементы располагаются слева направо вдоль основной оси как они идут в разметке.
Является значением по умолчанию
row-reverse
Элементы располагаются справа налево вдоль основной оси как они идут в разметке.
column
Элементы располагаются сверху вниз вдоль поперечной оси
column-reverse
Элементы располагаются снизу вверх вдоль поперечной оси
flex-wrap
Определяет как переносятся элементы когда в родительском контейнере закончилось место.
no-wrap
Значение по умолчанию no-wrap
, говорит о том, что даже если элементы не помещаются в контейнер, они не переносятся на новый ряд, а вмещаются максимально в строку.
При этом размеры родителя не имеют никакого значения.
Ниже мы задали размер для каждого элемента 250px
, но как видим размер существенно меньше.
Является значением по умолчанию
wrap
Элементы будут переноситься на новый ряд, если не влезают в родительскую строку.
В данном случае, не поместились три элемента, они и перенеслись на следующую строку.
Размеры каждого элемента при этом, как мы и указали 250px
.
То есть при изменении экрана элементы будут максимально заполнять всю имеющиеся область. В случае если элемент не влезает
Перенос элементов на следующую строку
wrap-reverse
Расположение элементов снизу вверх, сначала заполняются нижние ряды родителя, потом что не влезло переноситься наверх.
Меняется направление дополнительной оси или вспомогательной оси
flex-flow
Свойство, которое позволяет сразу задать и flex-direction
и flex-wrap
.
Сочетания:
flex-flow: column nowrap;
- колонка не переноситьflex-flow: column wrap;
- колонка переноситьflex-flow: column-reverse nowrap;
- перевернутая колонка не переноситьflex-flow: column-reverse wrap;
- перевернутая колонка не переноситьflex-flow: row wrap;
- ряд переноситьflex-flow: row nowrap;
- ряд не переноситьflex-flow: row-reverse wrap;
- перевернутый ряд не переносить
Используется если точно известно параметры сетки.
Работают так же как и свойства описанные выше:
justify-content
Выравнивание элементов внутри контейнера по основной оси. По умолчанию она идет слева направо.
flex-start и start
Элементы контейнера прижимаются к краю от которого начинается основная ось.
Для row
это левый край, а для column
это верх
Значение по умолчанию
flex-start и flex-end будут менять направление чтения текста на сайте в отличии от свойств left и right
flex-end и end
Элементы контейнера будут прижаты к краю у которого заканчивается основная ось.
Для row
это правый край, а для column
это низ
Значения start и end в большинстве браузеров идентичны flex-start и flex-end
center
Элементы контейнера выстраиваются по центру.
left
Выравнивание элементов по левому краю контейнера.
Отличие left от flex-start в том, что при flex-direction:row-reverse элементы всегда будут с левой стороны
right
Выравнивание элементов по правому краю контейнера.
space-between
Прижимать крайние элементы к левому и правому краям, а элементы между ними распределять равномерно.
При flex-direction:row-reverse
элементы пойдут в обратном направлении.
space-around
Свободное пространство делится между всеми элементами. Но от крайних элементов слева и справа будет половина этого расстояния.
space-evenly
Настояние между всеми элементами будет одинаковым.
Главное здесь понять как элементы должны располагаться на странице
Если flex-direction:column
и высота контейнера будет больше контета в нем то justify-content
будет так же работать как и при flex-direction:row
justify-content и flex-direction:column
align-items
Выравнивание элементов по вертикальной(поперечной) оси.
Напомню при row
основная ось идет слева направо, а поперечная сверху вниз.
При column
основная ось сверху вниз, а поперечная слева направо
stretch
Элементы по максимуму заполняют всего родителя.
Значение по умолчанию
flex-start и start
Элементы выстраиваются в начале поперечной оси
align-items:flex-start и start
flex-end и end
Элементы выстраиваются в конце поперечной оси
Значения start и end учитывают направление текста в браузере пользователя
center
Элементы выстраиваются по центру поперечной оси
baseline
Элементы выстраиваются по “базовой линии” текста, то есть по низу.
Например, если поменять размер шрифта, то элементы будут выстроены по нижней его части, то есть по базовой линии текста.
align-content
Распределяет элементы по поперечной оси. Можем управлять их поведением
Имеет значение только элементы располагаются в несколько рядов
То есть какие должны быть вводные для срабатывания свойства:
flex-wrap: wrap;
width: 50%;
ширина на самом элементе
Позиционирование будет применено в рамках нескольких строк
stretch
Ряды будут растянуты одинаково для того, чтобы занять все пространство родителя.
Значение по умолчанию
flex-start и start
Элементы располагаются у начала второстепенной оси
align-content:flex-start и start
flex-end и end
Элементы располагаются у конца поперечной оси
center
Элементы будут выстроены по центру контейнера
space-between
Первый и последний элементы встают к краям поперечной оси, остальные элементы распределяются так, чтобы между ними были равномерные отступы.
space-around
У первого и последнего элемента оступы по поперечной оси вдвое меньше отступов между другими элементами. При этом между остальными элементами отступы равнозначны.
space-evenly
Отступы от всех элементов одинаковые
gap
Расстояние между строками и столбцами.
Можно указывать два значения, но если указано одно, оно и будет использоваться для колонок и столбцов.
- Первое значение устанавливает отступ между рядами
row
row-gap
- Второе значение устанавливает отступ между колонками
column
column-gap
Примеры:
gap: 30px calc(10rem - 10px);
динамические промежутки между ячейками сеткиgap: 10px 5px;
row-gap и column-gap используются как отдельные свойства
Item
Прямые дочерние элементы контейнера.
- Все элементы вложенные в элемент уже не являются flex item и их нужно снова сделать контейнерами.
Свойства ниже управляют непосредственно самими элементами.
order
Меняем порядок отображение элементов внутри контейнера.
По умолчанию элементы отобраться как они идут в разметке.
Значение всех элементов по умолчанию = 0
.
Каждый элемент можно двигать как нам нужно меняя значение order
на положительное или отрицательное число.
order
влияет на визуальное отображение элементов.
Примеры значений:
0
-1
7
Рассмотрим пример:
В примере выше у каждого элемента есть свой класс. Зададим значение order
для некоторых из них
1
2
3
4
5
6
7
8
9
.item1 {
order: 1;
}
.item10 {
order: 2;
}
.item9 {
order: -1;
}
Напоминаю все элементы имеют по умолчанию значение order=0
- Элемент 10 идет в самый конец, так как у него
order:2
- Элемент 1 идет в след элементу 10, так как у него
order:1
- Элемент 9 идет в начало, так как у него
order:-1
Использовать order можно например при перемещении элементов при адаптивной верстке например переместить шапку сайта вниз на небольших экранах
align-self
По сути align-self
переопределяет align-items
но для одного элемента по текущей линии.
По умолчанию значение auto
это значит наследует значение элемента из align-items
В примере выше мы выставили разные значения align-self
для каждого элемента:
- 1
align-self: auto;
- значение по умолчанию - 2
align-self: start;
- в начало строки - 3
align-self: end;
- в конец строки - 4
align-self: flex-start;
- в начало строки - 5
align-self: flex-end;
- в конец строки - 6
align-self: center;
- посередине строки - 7
align-self: baseline;
- по базовой линии шрифта
Работает одинаково для flex-direction:row
и flex-direction:column
flex-basis
Базовое пространство которое будет занимать элемент, до того как оно будет заполнено.
При расчете размеров элемента принимается во внимание свойства высоты, ширины элемента.
Если размеры не заданы, тогда элемент занимает столько пространства сколько ему нужно для отображения контента.
В примере выше мы задали значение по умолчанию для 1 элемента в 200px
а для 6 100px
.
Значение по умолчанию для всех элементов auto, это значит отображение размеров по контенту
flex-grow
Управляет расширением отдельного элемента по частям.
Если есть свободное пространство элемент может заполнить это пространство.
Если задать всем элементам значение больше 0, то свободное пространство будет распределено между всеми элементами.
Если кратко flex-grow
говорит сколько частей свободного пространства нужно занять элементу.
Например, распределим все свободное пространство между 10 элементами, для этого элементам укажем всем элементам flex-grow:1
Теперь увеличим первый элемент на 5 частей.
Важно понимать элементы заполняют именно свободное пространство
Значение по умолчанию для всех элементов 0 частей
flex-shrink
Управляет сжатием отдельно взятого элемента.
Насколько сильнее сжать один элемент относительно другого.
Как мы должны сжиматься если у нас нет свободного пространства.
Значение по умолчанию для всех элементов 1
flex
Универсальное свойство для задания сразу трех значений
flex-grow
flex-shrink
flex-basis
Какие могут быть значения:
flex: 0 1 auto
- значение по умолчанию для всех элементовflex: 1
- Одно число интерпретируется какflex-grow
. Означает что элемент будет одну фракцию от всех элементов.flex: 1em
- Значение высоты интерпретируется какflex-basics
flex: 1 30px;
- Два значенияflex-grow
иflex-basics
flex: 2 2;
- Два значения без размераflex-grow
иflex-shrink
flex: 2 2 10%;
- Три значенияflex-grow
затемflex-shrink
и далееflex-basics
Примеры
Расстановка элементов друг под другом
Задача расположить 10 элементов с заданным размером в выставленной высоте родителя друг под другом в два ряда.
1
2
3
4
5
6
7
8
9
10
11
12
<div class="container">
<div class="item item1">1</div>
<div class="item item2">2</div>
<div class="item item3">3</div>
<div class="item item4">4</div>
<div class="item item5">5</div>
<div class="item item6">6</div>
<div class="item item7">7</div>
<div class="item item8">8</div>
<div class="item item9">9</div>
<div class="item item0">10</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
* {
box-sizing: border-box;
}
.container {
font-size: 35px; /* Размер шрифта для контейнера */
text-align: center;
display: flex;
height: 130px; /* Высота контейнера */
flex-direction: column; /* Расположение элементов друг под другом */
flex-wrap: wrap; /* Разрешеаем переносить элементы на следующую строку */
}
.item {
background-color: rgba(117,180,157,0.27);
border: #000066 1px solid;
padding: 8px;
width: 200px; /* Фиксированная ширина каждого элемента */
}
Получаем такой результат
Расстановка элементов друг под другом
Обратный порядок элементов, но не перемещая их
Задача не меняя позицию элементов поменять их порядок.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container {
font-size: 35px;
text-align: center;
display: flex;
flex-direction: row-reverse; /* делаем порядок элементов обратным */
justify-content: left; /* жестко говорим располагай по левой стороне */
}
/* или */
.container {
font-size: 35px;
text-align: center;
display: flex;
flex-direction: row-reverse;
justify-content: left;
}
В итоге, если жестко заданы left
или right
, элементы будут строго располагаться по нужную сторону.
Обратный порядок элементов, но не перемещая их left
Обратный порядок элементов, но не перемещая их right
Колонки с одинаковым расстоянием между ними
Задача сделать адаптивные колонки с одинаковым расстоянием между ними.
1
2
3
4
5
6
7
8
9
.container {
font-size: 35px;
height: 100vh; /* растягиваем колонки на всю высоту вьюпорта*/
text-align: center;
display: flex;
flex-direction: row;
justify-content: space-evenly; /* равномерное расстояние между колонками */
align-items: stretch;
}
Колонки с одинаковым расстоянием между ними
Адаптивные колонки
Задача сделать 10 простейших адаптивных колонок
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
font-size: 35px;
height: 100vh;
text-align: center;
display: flex;
flex-direction: row;
justify-content: center; /* выравнивание по центру по основной оси */
align-items: stretch;
}
.item {
background-color: rgba(117,180,157,0.27);
border: #000066 1px solid;
padding: 8px;
width: 10%; /* так как у нас 10 колонок делаем им ширину в % */
}
В результате получаем такую красоту
Элемент строго по центру
Задача. Допустим есть элемент с фиксированными значениями, его нужно выставить по центру, нет ничего проще
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.container {
font-size: 35px;
height: 100vh;
text-align: center;
display: flex;
flex-direction: row;
justify-content: center; /* центрирование по основной оси */
align-items: center; /* центрирование по вспомогательной оси */
}
.item {
background-color: rgba(117,180,157,0.27);
border: #000066 1px solid;
padding: 8px;
}
.item1 {
width: 200px;
height: 200px;
}
Полный адаптив
Задача. Есть набор блоков с заданными размерами, нужно сделать их адаптивными.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container {
font-size: 35px;
text-align: center;
display: flex;
flex-direction: row;
flex-wrap: wrap; /* Разрешаем переносить */
justify-content: start;
align-items: stretch;
align-content: stretch;
}
.item {
background-color: rgba(117,180,157,0.27);
border: #000066 1px solid;
padding: 8px;
flex-basis: 300px; /* По умолчанию все элементы равны 300px */
flex-grow: 1; /* Разрешаем расти всем элементам */
}
В итоге получаем полная адаптивная верстка.
Итог
- Чаще всего используется значения
justify-content
этоspace-between
иcenter
. - Рекомендуется проверять поддержку свойств браузерами на сайте https://caniuse.com/
- Если необходимо прижать элемент к левой или правой части, то необходимо элементу указать
margin-left: auto
- Если меняем расположение элементов, например свойством
flex-direction: row-reverse
, то нужно понимать, что изменения только визуальные, в самомhtml
они остались в том же порядке в котором и были - Основная ось выстраивается слева направо, а поперечная сверху вниз.
- flex элементы по умолчанию сжимаются под свое содержимое, это полезно когда есть блоки с динамическим контентом.
- Внешние отступы в отличие от блочной модели не схлопываются и не выпадают
- flex элементы умеют перераспределять свободное пространство вокруг себя, таким образом меняя ширину и высоту
- Отступы можно задать не только по горизонтали, но и по вертикали.
Что в планах
По отношению к флексам в этой статье рассмотрел не все, что хотел. В планах сделать отдельные заметки на темы:
- flexbox во фреймворках
- Что же использовать
flexbox
илиgrid
. Почему grid не заменит flex
Подписывайтесь на телеграмм канал lexusalextg, чтобы оперативно узнавать о новых статьях, дополнениях и полезных материалах.