Абсолютное горизонтальное и вертикальное центрирование

Сколько уже было сломано копий о задачу выравнивания элементов на странице. Предлагаю вашему вниманию перевод отличной статьи с решением этой проблемы от Стефана Шоу (Stephen Shaw) для Smashing Magazine — Absolute Horizontal And Vertical Centering In CSS.

Все мы знали о margin: 0 auto; для горизонтального центрирования, но margin: auto; не работало для вертикального. Это можно легко исправить, просто задав высоту и применив следующие стили:

.Absolute-Center {
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

Я не первый, кто предложил это решение, однако такой подход редко применяется при вертикальном выравнивании. В комментариях к статье How to Center Anything With CSSSimon ссылается на пример jsFiddle, где приводится отличное решение для вертикального центрирования. Вот еще несколько источников на эту тему.

Рассмотрим способ поближе.

Достоинства

 

  • Кроссбраузерность (включая IE 8-10)
  • Никакой дополнительной разметки, минимум стилей
  • Адаптивность
  • Независимость от padding (без box-sizing!)
  • Работает для изображений

 

Недостатки

 

  • Должна быть задана высота (см. Variable Height)
  • Рекомендуется задать overflow: auto, чтобы контент не расползался
  • Не работает на Windows Phone

 

Совместимость с браузерами

Метод был протестирован, и прекрасно работает в Chrome, Firefox, Safari, Mobile Safari и даже IE 8-10. Один пользователь упоминал, что контент не выравнивается по вертикали на Windows Phone.

Внутри контейнера

Контент, размещенный в контейнер с position: relative будет прекрасно выравниваться:

.Absolute-Center {
  width: 50%;
  height: 50%;
  overflow: auto;
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

b8d5fe2c0f67953966f5401aced50d05

С использованием viewport

Установим для контента position: fixed и зададим z-index:

.Absolute-Center.is-Fixed {
  width: 50%;
  height: 50%;
  overflow: auto;
  margin: auto;
  position: fixed;
  top: 0; left: 0; bottom: 0; right: 0;
  z-index: 999;
}

 

Смотреть демонстрацию

Адаптивность

Главное преимущество описываемого способа — это прекрасная работа, когда высота или ширина задана в процентах, да еще и понимание min-width/max-width и min-height/max-height.

.Absolute-Center.is-Responsive {
  width: 60%; 
  height: 60%;
  min-width: 400px;
  max-width: 500px;
  padding: 40px;
  overflow: auto;
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

64786322b38b78957079185032614aea

Смещения

Если на сайте присутствует фиксированная шапка или требуется сделать какой-то другой отступ, просто нужно добавить в стили код вроде top: 70px; Пока задан margin: auto; блок с контентом будет корректно центрироваться по высоте.

Еще можно выравнивать контент по нужной стороне, оставляя центрирование по высоте. Для этого нужно использовать right: 0; left: auto; для выравнивания справа или left: 0; right: auto; для выравнивания слева.

.Absolute-Center.is-Right {
  width: 50%;
  height: 50%;
  margin: auto;
  overflow: auto;
  position: absolute;
  top: 0; left: auto; bottom: 0; right: 20px;
  text-align: right;
}

 

2df0ad83cdb149c30a16156594b5b669

Много контента

Для того, чтобы большое количество контента не позволяло верстке разъезжаться, используем overflow: auto. Появится вертикальная прокрутка. Также можно добавитьmax-height: 100%; если у контента нет дополнительных отступов.

.Absolute-Center.is-Overflow {
  width: 50%;
  height: 300px;
  max-height: 100%;
  margin: auto;
  overflow: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

06d0b9ad95aa8739df02356b205a0d75

Изображения

Способ отлично работает и для изображений! Добавим стиль height: auto; тогда картинка будет масштабироваться вместе с контейнером.

.Absolute-Center.is-Image {
  width: 50%;
  height: auto;
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

b0b34a830cd1fb9d76bb7985fdc823b3

Изменяемая высота

Описываемый способ требует заданной высоты блока, которая может быть указана в процентах и контролироваться с помощью max-height, что делает метод идеальным для адаптивных сайтов. Один из способов не задавать высоту — использование display: table. При этом блок контента центрируется независимо от размера.

Могут возникнуть проблемы с кроссбраузерностью, возможно следует использовать способ с table-cell (описан ниже).

  • Firefox/IE8: использование display: table выравнивает блок вертикально по верхней границе документа.
  • IE9/10: использование display: table выравнивает блок по левому верхнему углу страницы.
  • Mobile Safari: если ширина задана в процентах, страдает горизонтальное центрирование

 

.Absolute-Center.is-Variable {
  display: table;
  width: 50%;
  overflow: auto;
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

 

fb2fbac61cdc1316969ea02cea2f1028

Другие способы

Описанный способ отлично работает в большинстве случаев, но есть и другие методы, которые могут быть применимы для решения специфических задач.

Отрицательный margin

Наверное, самый популярный способ. Подходит, если известны размеры блока.

.is-Negative {
        width: 300px;
        height: 200px;
        padding: 20px;
        position: absolute;
        top: 50%; left: 50%;
        margin-left: -170px; /* (width + padding)/2 */
        margin-top: -120px; /* (height + padding)/2 */
}

 

Преимущества:

  • Кроссбраузерность
  • Минимальный код

Недостатки:

  • Не адаптивный
  • Ползет верстка, если в контейнере слишком много контента
  • Приходится компенсировать отступы или использовать box-sizing: border-box

Использование transform

Один из самых простых способов, поддерживает изменение высоты. Есть подробная статья на эту тему — «Centering Percentage Width/Height Elements» от CSS-Tricks.

.is-Transformed { 
    width: 50%;
    margin: auto;
    position: absolute;
    top: 50%; left: 50%;
    -webkit-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
        transform: translate(-50%,-50%);
}

 

Преимущества:

  • Изменяемая высота
  • Минимальный код

Недостатки:

  • Не работает в IE 8
  • Использование префиксов
  • Может мешать работе других эффектов с transform
  • В некоторых случаях при рендеринге размываются края блока и текст

Table-cell

Возможно один из самых лучших и простых способов. Подробно описан в статье «Flexible height vertical centering with CSS, beyond IE7» от 456bereastreet. Главный недостаток — дополнительная разметка: требуется аж три элемента:

<div class="Pos-Container is-Table">
  <div class="Table-Cell">
    <div class="Center-Block">
    <!-- CONTENT -->
    </div>
  </div>
</div>

 

CSS:

.Pos-Container.is-Table { display: table; }
.is-Table .Table-Cell {
  display: table-cell;
  vertical-align: middle;
}
.is-Table .Center-Block {
  width: 50%;
  margin: 0 auto;
}

 

Преимущества:

  • Изменяемая высота
  • Верстка не едет при большом количестве текста в блоке
  • Кроссбраузерность

Недостатки:

  • Сложная структура

Flexbox

Будущее CSS, flexbox будет решать множество сегодняшних проблем верстки. Подробно об этом написано в статье Smashing Magazine, которая называется Centering Elements with Flexbox.

.Pos-Container.is-Flexbox {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
     -moz-box-align: center;
     -ms-flex-align: center;
  -webkit-align-items: center;
          align-items: center;
  -webkit-box-pack: center;
     -moz-box-pack: center;
     -ms-flex-pack: center;
  -webkit-justify-content: center;
          justify-content: center;
}

 

Преимущества:

  • Контаент может быть любой высоты или ширины
  • Может использоваться в более сложных случаях

Недостатки:

Итог

Каждый способ имеет преимущества и недостатки. По сути, выбор сводится к выбору браузеров, которые должны поддерживаться