LaMoore | Флексбокс — это когда ты перестаёшь плакать над выравниванием
Тут могла бы быть реклама, но вы включили блокировщик рекламы.

Флексбокс — это когда ты перестаёшь плакать над выравниванием

Узнайте, как работает 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

Alex Moore

Full-stack Developer

Тут могла бы быть реклама, но вы включили блокировщик рекламы.
Тут могла бы быть реклама, но вы включили блокировщик рекламы.

Обратная связь

Оставьте свой отзыв или задайте вопрос нашей команде.

© 2020 LaMoore. All rights reserved.