Как работать с Flexbox в HTML и CSS
Больше вкусностей найдешь на моем канале - https://t.me/emotional_robotИтак, мы быстренько познакомились с таким понятием, как Flexbox, краем зацепили еще парочку вещей, о которых, конечно же, подробнее поговорим, но попозже. Самое важное на текущий момент - изучить CSS, которые отвечают за отрисовку Flexbox, а также понять, как правильно размещать флексбоксовые элементы в HTML коде. Постараемся уловить суть Flexbox, потому что полное понимание придет только с практикой. Готовы? Погнали!
Flex контейнер и его содержимое
Flexbox является полноценным модулем, а не простым свойством, он включает в себя множество интересного, а в частности полный набор рабочих свойств. Некоторые из них созданы для использования в контейнере (родительский элемент, известный как flex-container), в то время как другие должны помогать исполнять свои роли дочерним элементам.
Надеюсь, вы запомнили, что элементы в HTML формируются согласно потоку документа сверху вниз, из которого их можно "вырвать" с помощью свойства float (плавающие элементы) и свойства position (позиционирование элементов). У Flexbox совершенно другой подход. Если обычный шаблон основан как на блочных, так и на инлайновых элементах, формирующих поток, то flex-шаблон основан на нескольких потоках. Краткая схема этой идеи представлена на картинке ниже:
Элементы в Flexbox могут располагаться вдоль основной оси (от main-start до main-end) или вдоль поперечной оси (от cross-start до cross-end). Рассмотрим чуть подробнее эту схему:
- Main axis — основная ось flex контейнера, вдоль которой располагаются flex элементы. Её направление может быть слева направо и справа налево.
- Main-start и main-end — flex элементы расположены в рамках контейнера, начиная от main-start и заканчивая main-end.
- Main-size — высота или ширина flex элемента, что зависит от того, в каком направлении идёт основная ось.
- Cross axis — поперечная ось, перпендикулярная главной оси. Её направление зависит от направления главной оси.
- Cross-start и cross-end — flex линии, которые заполнены элементами и расположены в контейнере от cross-start до cross-end.
- Cross-size — ширина или высота flex-элемента, в зависимости от направления главной оси.
Раз мы говорим об элементе-контейнере и элементах, являющихся дочерними по отношению к нему, сразу должна нарисоваться картинка в голове, как это выглядит в HTML коде:
Должен присутствовать один родительский тег, который станет flex-контейнером, а его дети будут flex-элементами. Тут пока проблем нет. Они начинаются в CSS.
CSS свойства контейнеров
Давайте аккуратно пойдем по всем свойствам, которые, во-первых, превращают обычный элемент во flex-контейнер, во-вторых, управляют его содержимым:
1) display. Это свойство создаёт сам flex-контейнер, инлайновый или блочный, в зависимости от заданного значения. Также оно задает flex-контекст каждому прямому потомку:
.flex-container {
display: flex; /* или inline-flex */
}
Мы пока не будем разбирать разницу между flex и inline-flex, потому что это тянет на отдельную статью. Пока запомните, что для создания flex-контейнера используем свойство "display: flex".
2) flex-direction. Устанавливает направление главной оси и определяет направление flex-элементов, размещенных во flex-контейнере. Flexbox - это односторонняя концепция представления шаблонизации. Поэтому flex-элементы располагаются, в основном, вдоль горизонтальной или поперечной линии:
.flex-container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row (по умолчанию) - слева направо;
- row-reverse - справа налево;
- column - сверху вниз;
- column-reverse - снизу вверх;
3) flex-wrap. Изначально все flex-элементы будут пытаться уместиться в одну строку. Вы можете поменять это и дать возможность этим элементам переходить на другую строку, при необходимости:
.flex-container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap (по умолчанию) - все элементы выстраиваются в одну линию;
- wrap - flex-элементы будут переноситься на несколько строк, от верха к низу;
- wrap-reverse - flex-элементы будут переноситься на несколько строк снизу вверх;
4) flex-flow. Это сокращение flex-direction и flex-wrap свойств, которые вместе определяют направление главной и поперечной оси. По умолчанию оно имеет значение "row nowrap".
5) justify-content. Свойство определяет выравнивание вдоль главной оси. Оно помогает распределить лишнее свободное пространство, когда или все flex-элементы в линии имеют фиксированный размер, или же нет, но уже достигли своего максимального размера. Оно также влияет на выравнивание элементов, когда те переполнят строку:
.flex-container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
- flex-start (по умолчанию) - элементы расставляются от начала строки;
- flex-end - элементы размещаются с конца строки;
- center - элементы центрированы вдоль строки;
- space-between - элементы равномерно распределены по строке, первый элемент находится в начале строки, последний в конце;
- space-around - элементы равномерно распределены по строке с равным местом вокруг них. Учтите, что визуально пробелы не равномерны, так как все элементы имеют одинаковые пробелы с двух сторон. Первый элемент получит одну единицу свободного места от границы контейнера, но получит две единицы свободного места от следующего элемента, так как у него тоже есть одна единица свободного места с каждой из сторон (это можно сравнить с удвоенной границей между ячейками таблицы);
- space-evenly - элементы распределены таким образом, что свободное пространство между любыми двумя элементами равномерно, как и место до границы края контейнера;
6) align-items. Это свойство определяет стандартное поведение того, как flex-элементы будут располагаться вдоль поперечной оси на заданной строке. Это своебразная версия justify-content, но только для поперечной оси, которая перпендикулярна главной:
.flex-container {
align-items: stretch | flex-start | flex-end | center | baseline;
}
- flex-start - всё размещается с начала поперечной оси;
- flex-end - всё размещается с конца поперечной оси;
- center - элементы центрируются по поперечной оси;
- baseline - элементы выравниваются по базовой линии;
- stretch (по умолчанию) - элементы заполняют контейнер (растягиваются) с учетом min-width и max-width.
7) align-content. Это свойство выравнивает и распределяет строки контейнера, когда есть свободное пространство в поперечной оси, подобно тому как justify-content выравнивает элементы по главной оси. Учтите, что это свойство не приносит эффекта, когда есть только одна строка flex-элементов:
.flex-container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
- flex-start - строки расположены от начала контейнера;
- flex-end - строки расположены от конца контейнер;
- center - строки расположены от центра контейнера;
- space-between - строки равномерно распределены, первая строка находится в начале контейнера, тогда как последняя находится в конце;
- space-around - строки равномерно распределены с равным местом вокруг каждой строки;
- stretch (по умолчанию) - строки растягиваются на все оставшееся место.
CSS свойства дочерних элементов
Теперь пройдемся по CSS свойствам дочерних элементов flex-контейнера:
1) order. По умолчанию, flex-элементы располагаются в исходном порядке: 1, 2, 3 и т.д. Однако, свойство "order" контролирует порядок, в котором элементы могут располагаться внутри контейнера:
.flex-item {
order: <любое целое число>; /* по умолчанию 0 (ноль) */
}
2) flex-grow. Определяет способность flex-элемента при необходимости становиться больше. Оно принимает безразмерное значение, которое служит пропорцией или долей, а также указывает, какое количество свободного места внутри контейнера элемент должен взять.
Если все элементы в контейнере имеют flex-grow со значением 1, то оставшееся место в нём распределено в равной мере среди потомков. Также оно не принимает негативных значений:
.flex-item {
flex-grow: <число>; /* по умолчанию 0 (ноль) */
}
Это свойство само по себе сложное, поэтому мы подробно разберем его в отдельной статье.
3) flex-shrink. Определяет способность flex-элемента сокращаться при необходимости. Оно также не принимает отрицательных значений:
.flex-item {
flex-shrink: <число>; /* по умолчанию 1 */
}
Тоже сложное свойство, требующее отдельного внимания.
4) flex-basis. Определяет стандартный размер элемента перед тем, как оставшееся место будет распределено. Это может быть длина (20%, 5em и т.п.) или ключевое значение.
Ключевое значение auto означает «посмотрите на мои свойства ширины (width) и высоты (height)». Значение content говорит, что размер основывается на контенте элемента — это свойство пока что не очень хорошо поддерживается, поэтому его тяжело протестировать и сложно понять, что делают его собратья, такие как max-content, min-content и fit-content:
.flex-item {
flex-basis: <длина> | auto; /* по умолчанию auto */
}
Если выставить значение на 0 (ноль), то дополнительное место вокруг контента не будет учтено. Если выставить на auto, то дополнительное свободное место будет распространяться, основываясь на его flex-grow значении:
Как вы поняли, это тоже сложное свойство, с которым мы будем отдельно разбираться. Чувствуете? Это запах боли и страданий.
5) flex. Это сокращение для flex-grow, flex-shrink и flex-basis - все вместе взятые. Второй и третий параметры необязательны, то есть flex-shrink и flex-basis. По умолчанию оно имеет значение 0 1 auto:
.flex-item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
Рекомендуется использовать сокращенное свойство, вместо набора индивидуальных свойств. Оно выставляет другие значения должным образом.
6) align-self. Позволяет стандартному выравниванию (которое "align-items") элементов быть перезаписанным для определенного flex-элемента. Чтобы увидеть все значения align-self, посмотрите их в align-items:
.flex-item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
Напомню, что раз flex-элементы имеют особое расположение в потоке документа, на них не действуют свойства float, clear и vertical-align.
В принципе, это все CSS свойства, отвечающие за Flexbox. Их много, они сложны для понимания, но они позволяют делать крутые макеты, которые подстраиваются под разные размеры экранов. Поэтому, как ни крути, с Flexbox нужно разобраться основательно - значит, мы тут задержимся. Благо, Flexbox действительно интересный инструмент - скучать не придется.
Итого
Мы изучили работу с Flexbox в HTML и CSS. Со стороны HTML все прозрачно, а вот со стороны CSS веселуха. Первая сложность - это хотя бы запомнить все эти флексбоксовые свойства, вторая - понять, как именно все это добро работает. Если бы можно было разобрать это за одну практику, но нет. В следующих статьях у нас будет совмещенная теория и практика. Мы будем подробно изучать по несколько свойств, потому что у многих из них есть довольно существенные нюансы работы, без понимания которых вы будете безуспешно сражаться со сложным макетом. Не переключайтесь.