Как исправить неработающий margin: 0 auto

Браузер центрирует блочный элемент через margin: 0 auto, если по бокам остается свободное место. В обычном потоке ограничьте ширину блока. Если прием не сработал, пройдите четыре проверки: найдите правило, посмотрите вычисленные стили, оцените размеры родителя и отключите переопределения.

margin 0 auto что это и как работают автоматические отступы

Запись margin: 0 auto задает нулевые верхний и нижний отступы. Браузер распределяет свободное горизонтальное место между левым и правым отступами со значением auto.

Базовый пример выглядит так:

.card {
  width: 600px;
  margin: 0 auto;
}

Родитель оставляет карточке свободное место по бокам. Браузер рассчитывает одинаковые значения margin-left и margin-right, поэтому карточка оказывается по центру.

Ширина может быть относительной. Такой вариант ограничивает карточку шириной контейнера на узком экране:

.card {
  width: min(600px, 100%);
  margin: 0 auto;
}

Для автоматических отступов вдоль строки используйте margin-inline: auto. При горизонтальном направлении письма это левый и правый отступы. Подробности о расчете отступов описывает документация MDN по margin.

Почему margin 0 auto не работает: блок не центрируется по горизонтали

Проверьте причины в этом порядке.

  1. Откройте инструменты разработчика браузера и выберите нужный элемент. В панели стилей найдите правило с margin: 0 auto.
  2. Посмотрите вычисленные значения display, width, margin-left и margin-right.
  3. Проверьте размеры родителя в схеме модели блока. Если свободной ширины нет, автоматические отступы не смогут сдвинуть элемент.
  4. Отключите подозрительные правила по одному. Если декларация зачеркнута, найдите правило, которое ее переопределяет.

После исправления левый и правый отступы должны стать одинаковыми. Сам элемент при этом должен занимать меньше ширины родителя. Чтобы вернуть временно отключенные правила, включите их обратно в панели стилей.

Проверьте display и width

Автоматические горизонтальные отступы центрируют блоковый элемент, когда его ширина меньше ширины контейнера. Строчный элемент идет внутри строки текста, поэтому такой прием не дает ожидаемого перемещения. Запрос «margin left css» обычно относится к свойству margin-left.

Для ссылки или другого строчного элемента задайте блочное отображение:

.link {
  display: block;
  width: 240px;
  margin: 0 auto;
}

У обычного div значение width: auto обычно растягивает элемент на доступную ширину. Свободного места по бокам тогда не остается, и автоматические отступы вычисляются как 0.

Значение width: 100% растягивает элемент на всю доступную ширину контейнера. Уменьшите ширину или ограничьте ее через max-width:

.content {
  width: 100%;
  max-width: 720px;
  margin-inline: auto;
}

Изображение часто остается строчным заменяемым элементом. Чтобы центрировать его через margin, задайте display: block и ограничьте ширину:

img.logo {
  display: block;
  width: 240px;
  max-width: 100%;
  margin: 0 auto;
}

Если ширину изображения менять не нужно, оставьте его естественный размер и используйте те же display и margin.

Проверьте контекст и позиционирование

Родительский элемент может менять правила размещения дочернего блока. В flex-строке два автоматических боковых отступа делят свободное место и центрируют одиночный элемент. Автоматический отступ только с одной стороны забирает свободное место и прижимает элемент к противоположному краю.

.toolbar {
  display: flex;
}

.toolbar .button {
  margin-left: auto;
}

В этом примере автоматический левый отступ забирает свободное место и прижимает кнопку вправо.

В flex-колонке главная ось проходит вертикально. Два автоматических боковых отступа центрируют элемент по горизонтали при свободной ширине. Верхний и нижний отступы остаются нулевыми, поэтому вертикального центрирования эта запись не создает.

Для центрирования всех дочерних элементов по главной оси задайте контейнеру выравнивание:

.stage {
  display: flex;
  justify-content: center;
}

.card {
  width: 600px;
}

Grid-контейнер также предлагает отдельные свойства выравнивания. Для центрирования содержимого ячеек по двум осям используйте place-items у контейнера. Чтобы выровнять отдельный элемент вдоль строки сетки, задайте ему justify-self: center.

.stage {
  display: grid;
  place-items: center;
}

.card {
  width: min(600px, 100%);
}

Не задавайте position: absolute только ради горизонтального центрирования. Абсолютный элемент выпадает из обычного потока, поэтому соседние блоки перестают учитывать его размер.

Для уже позиционированного элемента задайте все условия явно:

.popup {
  position: absolute;
  inset: 0;
  width: 320px;
  height: 180px;
  margin: auto;
}

Родитель popup должен задавать область позиционирования, например через position: relative. Если контейнер больше блока, inset: 0 оставляет свободное место со всех сторон. Заданные размеры позволяют margin: auto центрировать блок по двум осям.

Для абсолютно позиционированного элемента браузер распределяет автоматические отступы, когда заданы размеры и границы позиционирования оставляют свободное место. Для горизонтали задайте left, width и right, а для вертикали – top, height и bottom. Значение auto у всех трех параметров одной оси не создает центрирование: браузер сначала выбирает положение по правилам абсолютного позиционирования.

Почему автоматические отступы не центрируют блок по вертикали

В обычном блочном потоке автоматические верхний и нижний отступы вычисляются как 0. Поэтому margin: auto сама по себе не ставит блок по центру высоты родителя.

У обычных блоков соседние вертикальные отступы могут сливаться. Такое слияние меняет видимый промежуток между элементами и не превращает margin-top: auto или margin-bottom: auto в способ вертикального центрирования.

Для вертикального центрирования используйте flexbox:

.stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 300px;
}

.card {
  width: 320px;
}

Сетка решает ту же задачу короче:

.stage {
  display: grid;
  place-items: center;
  min-height: 300px;
}

Свойство transform подходит для других сценариев: например, когда нужно сдвинуть уже позиционированный элемент на половину собственной ширины. Для обычного блока flexbox или grid обычно дают более понятную структуру.

Подробнее о выборе способа выравнивания рассказывает документация MDN по выравниванию во flexbox.

Минимальный пример для проверки

Начните с рабочего минимального примера. Уберите лишние правила и оставьте контейнер, ширину блока и автоматические отступы.

<div class="wrapper">
  <div class="card">Карточка</div>
</div>
.wrapper {
  border: 1px solid #ccc;
}

.card {
  width: 600px;
  max-width: 100%;
  margin: 0 auto;
}

При ширине контейнера больше 600px карточка окажется посередине между его границами. В более узком контейнере она займет всю доступную ширину.

Если пример работает, возвращайте стили исходного проекта по одному. Сначала проверьте переопределение width и margin, затем display, float, position и правила родителя.

Если элемент должен занимать всю строку, центрировать его через margin бессмысленно. Ограничьте ширину через max-width или центрируйте строчное содержимое внутри него свойством text-align: center.

Совет от нашей редакции: для горизонтального блока начните с max-width и margin-inline: auto, а для центрирования по двум осям сразу берите flexbox или grid. Такой код проще проверить и поддерживать.

Комментарии

Оставьте свой комментарий
M
MxM5835

Отличная статья! Спасибо за шпаргалку!