Как центрировать элемент в CSS по вертикали и горизонтали: Flexbox

Чтобы центрировать элемент сразу по вертикали и горизонтали, родителю достаточно трёх строк: display: flex, justify-content: center и align-items: center. Родителю при этом нужна реальная высота, отличная от высоты содержимого, иначе центрировать будет негде.

Попробуй прямо сейчас: измени width и height у .box на любые другие числа - блок останется ровно по центру контейнера без единой правки в самом .container.

Почему центрирование элемента в CSS долго было сложной задачей

margin: 0 auto центрирует блочный элемент по горизонтали, но только если у него есть явная ширина - без ширины блок и так занимает всю строку, центрировать нечего. А по вертикали margin: auto в обычном потоке документа не работает вообще. До flexbox для вертикального центрирования применяли обходные приёмы: position: absolute с отрицательным margin, равным половине высоты элемента (для этого нужно было заранее точно знать эту высоту), либо position: absolute с transform: translate(-50%, -50%) (размер знать было не нужно, но элемент выпадал из потока документа и переставал занимать место среди других элементов). Задача была настолько неудобной, что вокруг неё сложился отдельный жанр программистских мемов про "как отцентрировать div".

.box { width: 200px; margin: 0 auto; } - центрирует по горизонтали блок с известной шириной.

.box { position: absolute; top: 50%; left: 50%; margin-top: -30px; margin-left: -100px; } - работает, но требует точно знать высоту (60px) и ширину (200px) элемента заранее; при изменении размера придётся вручную пересчитывать оба отрицательных отступа.

Готовое решение: display: flex, justify-content и align-items на родителе

display: flex превращает родителя в flex-контейнер (см. урок про то, что такое Flexbox), justify-content: center собирает элементы по центру главной оси, а align-items: center - по центру поперечной. Вместе, при направлении по умолчанию (row), это даёт центрирование сразу по обеим осям - и работает для элемента ЛЮБОГО размера без единой правки в самом контейнере. Важное условие: у контейнера должна быть реальная высота, отличная от высоты содержимого (явный height, либо, например, min-height: 100vh для центрирования на весь экран) - если высота контейнера и так равна высоте элемента внутри, свободного места по вертикали просто не останется и align-items: center ничего не изменит визуально. Этот же приём центрирует не только один элемент, а целую группу flex-элементов сразу - они окажутся по центру контейнера как единое целое, сохраняя порядок относительно друг друга.

.container { display: flex; justify-content: center; align-items: center; height: 300px; } - элемент внутри окажется точно по центру, независимо от его размера.

.container { display: flex; justify-content: center; align-items: center; } без height - если высота контейнера равна высоте содержимого, центрировать по вертикали будет негде.

Из истории Задача одновременного центрирования элемента по вертикали и горизонтали была настолько неудобной до flexbox, что вокруг нее сложился отдельный жанр программистских мемов. Фронтенд-разработчик Josh W. Comeau прямо пишет, что пару десятилетий назад центрирование элемента сразу по обеим осям было одной из самых неприятных вещей в CSS - "it spawned a ton of memes". С flexbox задача, которая раньше требовала точно знать размеры элемента или выводить его из потока документа через position: absolute, свелась к трём строкам CSS на родителе.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Ждут вертикального центрирования от margin: 0 auto Элемент центрируется только по горизонтали, по вертикали остаётся на месте Для вертикального центрирования нужен display: flex и align-items: center на родителе
Не задают контейнеру высоту align-items: center не даёт видимого эффекта - высота контейнера равна высоте содержимого Задать контейнеру явный height или min-height (например, 100vh для центрирования на весь экран)
Продолжают использовать старый приём с отрицательными margin и заранее известным размером При изменении размера элемента приходится вручную пересчитывать отступы Использовать flexbox - центрирование работает для любого размера элемента без пересчёта
Пишут justify-content и align-items на самом центрируемом элементе, а не на родителе Свойства не действуют Оба свойства задаются на контейнере с display: flex, а не на дочернем элементе

Шпаргалка

Что нужноКак сделать
Центрировать по горизонтали (блок с известной шириной)margin: 0 auto;
Центрировать по вертикали и горизонтали сразуdisplay: flex; justify-content: center; align-items: center;
Центрировать на весь экрандобавить контейнеру min-height: 100vh;
Центрировать несколько элементов как группуте же 3 строки на общем контейнере
Обязательное условие для вертикалиу контейнера должна быть высота, отличная от высоты содержимого

Коротко: отвечаем на вопросы

Обязательно ли задавать высоту контейнеру для вертикального центрирования?

Да, контейнеру нужна реальная высота, отличная от высоты его содержимого - например, явный height или min-height: 100vh для центрирования на весь экран. Если высота контейнера и так равна высоте элемента внутри, свободного места по вертикали не остаётся, и align-items: center ничего не меняет визуально.

Можно ли центрировать так сразу несколько элементов, а не один?

Да, те же display: flex, justify-content: center и align-items: center на общем контейнере центрируют сразу всю группу flex-элементов как единое целое - элементы окажутся по центру контейнера, сохранив свой порядок и расположение относительно друг друга.

Категория
css
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×