Узнайте, как работает CSS Flexbox и как легко и гибко управлять расположением элементов на веб-страницах в нашем наглядном введении.
Флексбокс появился в CSS в тот момент, когда веб-разработчики устали объяснять, почему вертикальное центрирование — это не просто margin: auto, а целый квест с флоатами, таблицами и position: absolute с отрицательными марджинами. Система флексбокса решила проблему радикально: она предложила браузеру самому думать, как расположить элементы. И знаете что? Браузер справляется лучше нас.
Суть флекса в том, что родительский контейнер получает возможность управлять расположением своих детей не через прямые координаты, а через правила распределения пространства. Ты говоришь не «поставь этот блок на 200 пикселей левее», а «распредели детей равномерно» или «растяни их по высоте». Браузер слушается и делает это красиво даже на экранах, о существовании которых ты не подозревал.
Чтобы включить флекс, достаточно написать display: flex на родителе. Всё. С этого момента его дети становятся flex-элементами и начинают вести себя иначе. Они выстраиваются в ряд, игнорируют вертикальные марджины между собой и готовы сжиматься или растягиваться по команде. Вот простейший пример:
.container {
display: flex;
}Три дива внутри .container теперь встанут в горизонтальную линию, даже если раньше были блочными и занимали всю ширину. Это первое магическое свойство флекса — он меняет природу элементов. Блочные становятся гибкими, инлайновые получают возможность иметь размеры. Всё подчиняется новой логике.
Флекс живёт в двух измерениях — в главной оси и поперечной. По умолчанию главная ось горизонтальна, а поперечная вертикальна. Главная ось — это направление, в котором элементы выстраиваются друг за другом. Поперечная — это перпендикуляр к ней. Можно поменять направление главной оси через flex-direction: column, и тогда элементы пойдут сверху вниз, а поперечная ось станет горизонтальной. Это важно понимать, потому что дальше все свойства будут работать относительно этих осей.
Свойство justify-content управляет распределением элементов по главной оси. Хочешь прижать всё к началу — flex-start. К концу — flex-end. В центр — center. Между элементами пустое пространство должно распределиться равномерно — space-between. Или чтобы пространство было и по краям тоже — space-around. Или вообще везде одинаковое, включая края — space-evenly. Вот как это выглядит:
.container {
display: flex;
justify-content: space-between;
}Три блока внутри разлетятся: первый к левому краю, последний к правому, средний ровно посередине. Без математики, без вычислений, без calc(). Браузер сам посчитал свободное пространство и распределил его между элементами. Это работает на любой ширине экрана.
Теперь про align-items — оно отвечает за выравнивание по поперечной оси. Если главная ось горизонтальна, то align-items управляет вертикальным выравниванием. Значение stretch растянет элементы на всю высоту контейнера (это по умолчанию). Значение center поставит их ровно посередине по высоте. flex-start прижмёт к верху, flex-end — к низу. И да, вертикальное центрирование действительно работает одной строчкой:
.container {
display: flex;
align-items: center;
justify-content: center;
}Всё. Контент в центре. По горизонтали и вертикали. Можешь наконец перестать гуглить «css vertical align center».
Есть ещё align-self — это как align-items, но для конкретного ребёнка. Если все элементы должны быть растянуты, а один конкретный — прижат к верху, пишешь align-self: flex-start на этом элементе. Он проигнорирует общее правило и сделает по-своему.
Самое интересное начинается с flex-grow, flex-shrink и flex-basis. Это свойства для детей, которые управляют их гибкостью. flex-basis — это базовый размер элемента до того, как начнётся распределение свободного пространства. По умолчанию это auto, то есть «размер контента». Можешь задать конкретное значение, например flex-basis: 200px.
flex-grow — это коэффициент роста. Если в контейнере осталось свободное место, оно распределится между элементами пропорционально их flex-grow. Значение 0 (по умолчанию) означает «не расти». Значение 1 — «забирай свою долю». Значение 2 — «забирай в два раза больше, чем у тех, у кого 1». Пример:
.item-1 {
flex-grow: 1;
}
.item-2 {
flex-grow: 2;
}Если в контейнере 300 пикселей свободного пространства, первый элемент получит 100, второй — 200. Никаких процентов, никаких жёстких значений — просто пропорции.
flex-shrink работает наоборот — это коэффициент сжатия. Если места не хватает, элементы сжимаются пропорционально этому значению. По умолчанию 1, то есть все сжимаются одинаково. Если поставишь 0, элемент откажется сжиматься и предпочтёт вылезти за границы контейнера. Если поставишь 2, он будет сжиматься в два раза активнее остальных.
Все три свойства можно записать коротко через flex: это сокращение для flex-grow, flex-shrink и flex-basis. Например, flex: 1 0 auto означает «расти с коэффициентом 1, не сжиматься, базовый размер по контенту». Часто пишут просто flex: 1, и это раскрывается в flex: 1 1 0, то есть элемент и растёт, и сжимается, и базовый размер обнуляется — элемент становится полностью гибким.
Есть ещё flex-wrap. По умолчанию флекс-элементы стараются уместиться в одну линию, даже если им тесно. Но если написать flex-wrap: wrap, они начнут переноситься на следующую строку, когда места не хватит. Это превращает флекс в подобие сетки, но без жёсткой структуры — элементы просто переходят на новую линию, когда нужно.
И последнее — gap. Это современное свойство, которое задаёт отступы между флекс-элементами. Раньше приходилось городить марджины и отрицательные марджины на контейнере, чтобы крайние элементы не имели лишних отступов. Теперь просто gap: 20px, и между всеми элементами ровно 20 пикселей, а по краям — ничего. Работает и по горизонтали, и по вертикали, если элементы переносятся.
Флексбокс не идеален. Он одномерный — хорошо работает в одном направлении, но для настоящих двумерных сеток лучше использовать Grid. Но для большинства задач раскладки — навигации, карточек, выравнивания контента, адаптивных блоков — флекс закрывает всё. И делает это так естественно, что через месяц работы с ним ты забываешь, как вообще раньше обходился без него.
Alex Moore
Full-stack Developer