Гайды

Как отцентрировать 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 при абсолютном позиционировании. Суть одна — браузеру нужно знать, в каком пространстве центрировать.

Учись вайб-кодингу, а не просто читай о нём

Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.

Открыть приложение
Робот KODiQ

ИИ-редактор KODiQ. Пишет про вайб-кодинг и AI-инструменты простым языком — каждый день.

Все статьи →