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

Задача

Выровнять один блок внутри другого по вертикали.

Исходная верстка

<div class='parent'>
    <div class='child'></div>
</div>
CHILD

Вариант 1. Высоты обоих блоков известны

Расчеты на калькуляторе

Если высота обоих блоков известна, то нет ничего проще, чем выровнять один из них по центру другого. Для этого просто нужно рассчитать отступы:

.parent{
  height:200px;
  overflow:hidden;
}
.child{
  height:50px;
  margin:75px 0; // (200-50)/2
}
CHILD

Свойство overflow:hidden препятствует схлопыванию верхнего маргина дочернего элемента.

Вариант 2. Известна высота внешнего блока

Одна строка

Если внутренний блок занимает не больше одной строчки, для его выравнивания можно воспользоваться свойством line-height.

.parent{
  height:200px;
  line-height:200px;
}
.child{
  white-space:nowrap;
  overflow:hidden;
}
CHILD

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

Отметим, что центрировалось именно текстовое содержимое блока, а фон растянулся на всю высоту строки. Чтобы этого не происходило, если необходимо сохранить фон, нужно превратить блок в строчный элемент, добавив ему свойство display: inline.

CHILD

При должной подготовке можно попробовать и многострочный текст выровнять таким же способом:

.parent{
  height:200px;
  line-height:200px;
}
.child{
  line-height:normal;  // переопределяем высоту строки в дочернем элементе
  display:inline-block;  
  vertical-align:middle;
}
CHILD
CHILD

Вариант 3. Известна высота внутреннего блока

Два способа абсолютного позиционирования

Абсолютное позиционирование выдергивает элемент из общего потока, поэтому важно определить относительное позиционирование (position: relative) для родительского элемента, относительно которого будет происходить центрирование.

.parent {
  position:relative;
}

.child {
  position:absolute;
}

Способ #1. Растягивание

Притянем внутренний блок одновременно к верху и низу внешнего и позволим браузеру самостоятельно рассчитать отступы:

.child {
  top:0;
  bottom:0;
  height:100px;
  margin:auto;
}

Способ #2. Отрицательный маргин

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

.child {
  top:50%;
  height:100px;
  margin-top: -50px;
}

Вариант 4. Высоты обоих блоков неизвестны

Коварный vertical-align

Одним своим названием свойство vertical-align вселяет тонны ложных надежд в сердца юных верстальщиков. Но, увы!, оно не поможет нам в этом случае. Это свойство действует только на строчные элементы, причем выравнивает их не относительно контейнера, а относительно друг друга в одном контейнере.
Тем не менее, мы все же можем воспользоваться этим скользким свойством при одном условии — мы внутри таблицы.

Преимущества таблиц

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

<div class='wrapper'>
  <div class='parent'>
    <div class='child'></div>
  </div>
</div>
.wrapper{
  display:table;
}
.parent{
  display:table-cell;
  vertical-align:middle;
}
CHILD

Трансформируй это

Этот способ очень напоминает прием с отрицательным верхним маргином и так же использует абсолютное позиционирование.

.parent{
  position:relative;
}
.child{
  position:absolute;
  top:50%;
  transform:translateY(-50%);
}

Лишний элемент

Мы уже отметили, что свойство vertical-align выравнивает строчные элементы относительно друг друга в одном контейнере. Этим можно воспользоваться, если мы сможем найти где-нибудь хотя бы еще один строчно-блочный элемент. Впрочем, мы ведь можем сами его создать. И для этого даже не нужно засорять разметку, воспользуемся псевдоэлементом.

.parent:before{
  display:inline-block;
  height:100%;
  vertical-align:middle;
  content:"";
}
.child{
  display:inline-block;
  vertical-align:middle;
}

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

Новые технологии

Флексбокс предоставляет идеальные инструменты для выравнивания по всем возможным осям. Как же обидно, например, что свойство margin: auto, так хорошо помогающее при горизонтальном центрировании, по вертикали не работает. А теперь работает:

.parent{
  display:flex;
  height:200px;
  width:350px;
}
.child{
  margin:auto;
}

Внутри флекс-контейнера свойство margin:auto работает по всем фронтам.

0 комментариев

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

*Доступные HTML-теги: a, abbr, blockquote, code, pre, del, i, em, strong, b, strike
*Не будет опубликован