Как отцентрировать div — 4 способа и когда какой брать

«Как отцентрировать div» — самый старый мем фронтенда. Смешно, что сегодня проблема не в том, что способа нет, а в том, что их пять и непонятно, какой твой.
И ещё одна новость, которую многие пропустили: вертикально центрировать теперь можно без flexbox вообще — прямо в обычном блоке. Это доехало до всех браузеров в 2024-м, и половина туториалов о нём ещё не знает.
Пойдём по возрастанию сложности задачи. Бери первый способ, который закрывает твой случай.
1. Только по горизонтали: margin
Самый простой случай — блок с заданной шириной надо прижать к центру строки.
.box {
width: 320px;
margin-inline: auto;
}
margin-inline: auto — современная запись привычного margin: 0 auto. Браузер делит свободное место поровну слева и справа.
Два условия, без которых не сработает: у блока должна быть ширина (иначе он и так занимает всё) и он должен быть блочным. Для span сначала display: block.
Что получится: блок по центру по горизонтали, вертикаль не тронута.
2. Универсальный способ: flex
Когда нужно и по горизонтали, и по вертикали, и содержимое одно:
.parent {
display: flex;
justify-content: center; /* по горизонтали */
align-items: center; /* по вертикали */
min-height: 100vh; /* родителю нужна высота */
}
Главная ловушка тут — последняя строка. align-items: center центрирует внутри высоты родителя, а если у родителя высоты нет, он ровно по содержимому — и центрировать не в чем. Именно поэтому «не работает align-items» почти всегда означает «у родителя нет высоты».
Запомни соответствие: justify-content — вдоль главной оси, align-items — поперёк. При flex-direction: column они меняются местами, и это второй источник путаницы.
Что получится: содержимое ровно в центре родителя по обеим осям.
3. Одной строкой: grid
То же самое, но короче:
.parent {
display: grid;
place-items: center;
min-height: 100vh;
}
place-items — сокращение для align-items и justify-items сразу. Если детей несколько и их надо центрировать как группу, а не каждого в своей ячейке — бери place-content: center.
Это мой способ по умолчанию для «экран-заглушка»: страница 404, спиннер загрузки, форма входа по центру пустого экрана. Разницу между двумя раскладками разбираем в Flexbox или Grid.
Что получится: то же, что в способе 2, но на две строки меньше.
4. Без flex и grid: align-content в обычном блоке
Свежее. Раньше единственной причиной писать display: flex часто было «надо подвинуть текст по вертикали». Теперь align-content работает и в обычном блочном контейнере:
.box {
height: 120px;
align-content: center; /* вертикаль */
text-align: center; /* горизонталь */
}
Никакого flex — дети остаются обычными блоками и ведут себя как обычно (не сжимаются, переносятся как в тексте). Особенно приятно для кнопок и ячеек фиксированной высоты, где flexbox был из пушки по воробьям.
Поддержка: Chrome 123, Firefox 125, Safari 17.4 — то есть весна 2024 года. Для старых браузеров это деградирует мягко: текст просто прижмётся к верху, ничего не сломается.
Что получится: содержимое по центру по вертикали, вёрстка внутри осталась блочной.
5. Поверх всего: абсолютное позиционирование
Нужно, когда блок должен лечь поверх чего-то — оверлей, модалка, подпись на картинке.
.parent { position: relative; }
.overlay {
position: absolute;
inset: 0;
display: grid;
place-items: center;
}
inset: 0 — короткая запись для top: 0; right: 0; bottom: 0; left: 0: слой растягивается на весь родитель, а grid центрирует содержимое внутри.
Старый приём с top: 50%; left: 50%; transform: translate(-50%, -50%) тоже жив и полезен, когда размер блока заранее неизвестен. Только помни: transform создаёт контекст наложения — и потом удивляться, почему подсказка уехала под соседний блок, уже не надо.
Что получится: блок точно по центру родителя и поверх его содержимого.
Частая засада: центрируешь не то, что думаешь
Половина «не центрируется» — это путаница между двумя разными задачами.
text-align: center центрирует содержимое внутри блока: текст, картинки, инлайновые элементы. Сам блок при этом стоит где стоял и по-прежнему занимает всю ширину родителя.
margin-inline: auto центрирует сам блок внутри родителя, но не трогает то, что у него внутри.
Проверь себя вопросом: тебе нужно подвинуть коробку или её начинку? Часто нужны обе строки сразу. Увидеть, что именно происходит, проще всего в инструментах разработчика: наведи на элемент — браузер подсветит его настоящие границы, и сразу станет видно, растянут он на всю ширину или нет. Про сами слои — в блочной модели CSS.
Как выбрать за пять секунд
- Нужна только горизонталь, ширина известна — способ 1.
- Нужны обе оси, детей несколько, в ряд или столбиком — способ 2.
- Нужны обе оси, ребёнок один — способ 3.
- Нужна только вертикаль внутри блока известной высоты — способ 4.
- Нужно лечь поверх — способ 5.
Правило: сначала спроси «по какой оси и есть ли у родителя высота». Половина проблем с центрированием — это вторая половина вопроса.
Почему align-items: center не работает?
В 9 случаях из 10 у родителя нет высоты: он ровно по содержимому, и центрировать не в чем. Задай min-height (или height) — заработает сразу. Проверить это можно за секунду через инструменты разработчика: посмотри вычисленную высоту родителя.
Почему текст в кнопке стоит чуть выше центра?
Обычно виноват не способ центрирования, а неравные отступы или line-height больше, чем ты думаешь. Посмотри блочную модель в панели Computed — там видно, что padding-top и padding-bottom разные. Подробнее про слои — в блочной модели.
Можно ли центрировать без задания высоты родителю?
Да, если высоту даёт что-то другое: min-height: 100vh у секции, высота от сетки-родителя или inset: 0 при абсолютном позиционировании. Суть одна — браузеру нужно знать, в каком пространстве центрировать.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.





