Центрирование элементов на странице.

Достаточно частой задачей, является размещение html-элементов по центру родительского элемента как по вертикали, так и по горизонтали. Отбросим варианты с использованием JS, хотя бывает, что без них не обойтись, и рассмотрим пару примеров того, как это можно сделать только средствами CSS. Первый способ многим хорошо знаком, но будет полезен начинающим. Основывается он на абсолютном позиционировании элемента, который собираемся центрировать:

HTML

<div class="parent">
  <div class="child"></div>
</div>

CSS

.parent {
  position: relative;
  width: 300px;
  height: 300px;
  background: #ccc;
}
.child {
  position: absolute;
  width: 250px;
  height: 250px;
  left: 50%;
  top: 50%;
  margin-left: -125px;
  margin-top: -125px;
  background: #060;
}

Свойствами top и left, мы устанавливаем расстояние от верхней и левой границы родительского элемента (.parent) до верхней и левой границы дочернего (.child). При этом по центру будет только его верхний левый угол. Для того, чтобы совместить центр родительского блока с центром дочернего, мы смещаем последний на половину его ширины влево и на половину его высоты вверх, используя отрицательные значения свойств установки отступов: margin-left и margin-top соответственно. Аналогично действуем, если ширина и высота дочернего элемента, будет выставлена в процентах. Только в таком случае, отступы задаём так же в процентах.

.child {
  position: absolute;
  width: 50%;
  height: 50%;
  left: 50%;
  top: 50%;
  margin-left: -25%;
  margin-top: -25%;
  background: #060;
}

Хочу обратить внимание на одну особенность. Если у родительского элемента (.parent) присутствует свойство position со значением "relative", "absolute" или "fixed", то вычисления для дочернего происходят относительно "родителя". Но если мы уберём это свойство, то родительский элемент примет значение по умолчанию - "static" и вычисления уже будут относительно окна браузера (его видимой области).
Следующий способ - это "псевдотаблицы". Все хорошо знают, что отцентрировать элементы в таблице проще простого, но не всегда таблицы уместны при верстке. Есть способ, с помощью которого, мы можем заставить обычные html-элементы, вести себя, как табличные. Тут нам потребуется CSS свойство "display" и его значения: "table", "table-row" и "table-cell". В общем-то, названия значений сами говорят за себя. Но для решения нашей задачи, потребуется только значение "table-cell". Сложности могут возникнуть с Safari 3.1, для которого требуются два дополнительных элемента с "display: table;" и "display: table-row;", но случай этот редкий и (на мой взгляд) сегодня не очень актуальный, т.к. по статистике, начиная с июня 2011 года, процент пользователе с версией 3 - практически равен нулю. Посему, вполне хватает такой записи:

/* если .child блочный элемент */
.parent {
  display: table-cell;
  width: 300px;
  height: 300px;
  vertical-align: middle; /* центрируем по вертикали */
  background: #ccc;
}
.child {
  margin: 0 auto; /* центрируем по горизонтали */
  width: 150px;
  height: 150px;
  background: #060;
}

/* если .child блочно-встроенный элемент (inline-block)
  или встроенный (inline) */
.parent {
  display: table-cell;
  width: 300px;
  height: 300px;
  text-align: center; /* центрируем по горизонтали */
  vertical-align: middle; /* центрируем по вертикали */
  background: #ccc;
}
.child {
  display: inline-block; /* или inline */
  width: 150px; /* только для inline-block */
  height: 150px; /* только для inline-block */
  background: #060;
}

И еще один интересный способ, с которым я хотел бы познакомить - это использование псевдоэлемента:

.parent {
  width: 300px;
  height: 300px;
  text-align: center;
  background: #ccc;
}
.parent::before { /* Если учитывать IE8 - .parent:before */
  display: inline-block;
  content: '';
  height: 100%;
  vertical-align: middle;
  margin-right: -0.36em; /* (*см. ниже) */
}
.child {
  display: inline-block;
  width: 150px;
  height: 150px;
  vertical-align: middle;
  background: #060;
}

*отрицательный отступ задаётся потому, что между элементами inline-block, присутствуют пустые текстовые узлы, из-за которых и появляются отступы между ними. То есть, учитывая такой "пустой узел" между псевдоэлементом и центрируемым элементом, мы и смещаем последний на 0.36em влево для более точного расположения.
Преимуществом такой реализации, есть то, что размеры как родительского, так и дочернего элемента, могут быть какими-угодно и нам их не нужно учитывать при центрировании... ну, ясное дело, что родитель должен иметь размеры побольше ;)


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

Incode Pro logo
Ваш комментарий:
X