justify-content выравнивает flex-элементы вдоль главной оси контейнера: прижимает их к началу, к концу, к центру или распределяет между ними свободное место с помощью space-between, space-around и space-evenly. Какая ось главная - зависит от flex-direction: при row это горизонталь, при column - вертикаль.
В этом уроке
Попробуй прямо сейчас: замени space-between на space-around, а затем на space-evenly - присмотрись, как меняется отступ именно у левого и правого края контейнера относительно промежутков между блоками.
Шесть значений justify-content: flex-start, flex-end, center, space-between, space-around, space-evenly
В уроке про flex-direction уже говорилось, что у flex-контейнера есть главная ось, и что именно flex-direction определяет, какая это ось - горизонтальная или вертикальная. justify-content работает именно вдоль этой оси. flex-start (по умолчанию) прижимает элементы к началу оси, flex-end - к концу, center - собирает их в середине, оставляя свободное место поровну по краям. Остальные три значения распределяют свободное место МЕЖДУ элементами: space-between не оставляет отступа по краям контейнера, space-around и space-evenly - оставляют, но по-разному считают его размер (подробнее в следующем разделе).
.container { display: flex; justify-content: center; } - элементы соберутся в середине контейнера вдоль главной оси.
.item { justify-content: center; } на отдельном элементе - justify-content, как и flex-direction, действует только будучи заданным на самом контейнере.
Чем space-between отличается от space-around и space-evenly
Все три значения распределяют свободное место между элементами, но по-разному обращаются с краями контейнера. space-between вообще не даёт отступа по краям - первый элемент прижат к самому началу, последний - к самому концу, а свободное место делится поровну только между соседними элементами. space-around выдаёт КАЖДОМУ элементу одинаковый отступ со всех сторон - но так как два соседних отступа складываются между элементами, а крайний отступ ни с чем не складывается, зазор у самого края контейнера оказывается вдвое меньше зазора между элементами. space-evenly устраняет и эту разницу - здесь абсолютно все промежутки одинаковы, включая расстояние от краёв контейнера до первого и последнего элемента.
justify-content: space-evenly; - все промежутки, включая крайние, одинаковой ширины.
justify-content: space-around;, ожидая, что отступ у края будет равен отступу между элементами - на самом деле отступ у края будет вдвое меньше.
Почему justify-content иногда как будто не работает
justify-content распределяет только СВОБОДНОЕ место в контейнере. Если хотя бы у одного flex-элемента задан flex-grow, отличный от 0, этот элемент растянется и займёт всё свободное место сам - тогда распределять между элементами будет уже нечего, и justify-content визуально перестанет быть заметен, хотя в коде всё написано верно. Если нужно и растягивать элемент, и одновременно управлять свободным местом через justify-content - эти две задачи противоречат друг другу: свободное место не может одновременно быть занято растяжением и распределено выравниванием.
.container { display: flex; justify-content: space-between; } без flex-grow у элементов - всё свободное место действительно распределяется между ними.
.item { flex-grow: 1; } у элемента внутри контейнера с justify-content: center - элемент займёт всё свободное место сам, и центрирование станет незаметным.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Путают space-around и space-evenly | Ожидают одинаковые отступы у края и между элементами при space-around | Помнить: у space-around отступ по краю вдвое меньше; одинаковые отступы везде даёт только space-evenly |
| Не понимают, почему justify-content не действует, если задан flex-grow | Свободного места для распределения не остаётся - элемент с flex-grow забирает его себе | Убрать flex-grow у элементов, если нужно именно распределение через justify-content |
| Пишут justify-content на дочернем элементе вместо контейнера | Свойство не действует | justify-content всегда пишется на элементе с display: flex |
| Пытаются "оторвать" один элемент от группы, меняя justify-content всего контейнера | Меняется расположение ВСЕХ элементов, а не одного нужного | Для одного элемента использовать margin-left: auto именно на нём, а justify-content контейнера не трогать |
Шпаргалка
| Что нужно | Как сделать |
|---|---|
| Прижать к началу (по умолчанию) | justify-content: flex-start; |
| Прижать к концу | justify-content: flex-end; |
| Собрать в середине | justify-content: center; |
| Без отступов по краям, равные между элементами | justify-content: space-between; |
| Отступ по краю вдвое меньше, чем между элементами | justify-content: space-around; |
| Все отступы одинаковые, включая края | justify-content: space-evenly; |
| Оторвать один элемент от остальных | margin-left: auto; на этом элементе |
Коротко: отвечаем на вопросы
Почему justify-content не работает, хотя код написан правильно?
Самая частая причина - у одного из flex-элементов задан flex-grow, отличный от 0. justify-content распределяет только свободное место в контейнере, а такой элемент сам забирает это место себе на растяжение. В результате распределять становится нечего, и justify-content визуально перестаёт быть заметен, хотя в коде всё написано верно.
Как расположить один элемент слева, а остальные - справа, в одном flex-контейнере?
Не нужно менять justify-content всего контейнера - для этого случая на самом отделяемом элементе задаётся margin-left: auto. Такой элемент займёт всё доступное свободное место слева от себя и окажется прижатым к правому краю, а остальные элементы останутся на месте. Этот приём часто используют для навигации, где логотип должен быть слева, а пункты меню - справа.