Все, кто занимаеться версткой, рано или поздно сталкиваются с необходимостью выравнивать элементы по вертикали... и знают, какие сложности могут возникнуть при выравнивании элемента по центру. В CSS есть свойство `vertical-align` со множеством значений которое, по логике, и должно выполнять вертикальное выравнивание. Однако на практике оно работает совсем не так, как ожидается.
Для решения данной проблемы существует несколько техник. Ниже подробнее рассмотрим каждую из них.
1. Выравнивание с помощью таблицы
В этом случае мы заменяем внешний блок таблицей из одной ячейки. Выравнивание будет применяться к содержимому ячейки, то есть к внутреннему блоку.
HTML
<table class="outer-wrapper">
<td class="outer">
<div class="inner"></div>
</td>
</table>
CSS
.outer {
width: 200px;
height: 200px;
text-align: center;
vertical-align: middle;
background-color: #ffc;
}
Основной минус данного решения, с точки зрения семантики - применение таблицы не по прямому назначению. Второй минус в том, что для создания таблицы требуется добавить еще один элемент вокруг внешнего блока.
Первый минус можно частично невилировать, заменив теги таблицы на div
и задав табличный режим отображения в CSS.
HTML
<div class="outer-wrapper">
<div class="outer">
<div class="inner"></div>
</div>
</div>
CSS
.outer-wrapper {
display: table;
}
.outer {
display: table-cell;
}
2. Выравнивание с помощью отступов
При условии, если нам известны высоты внутреннего и внешнего блоков, выравнивание можно задать с помощью вертикальных отступов у внутреннего блока, используя формулу: (Houter – Hinner) / 2.
CSS
.outer {
height: 200px;
}
.inner {
height: 100px;
margin: 50px 0;
}
Минусом решения есть обязательное знание высоты обоих блоков.
3. Выравнивание с помощью line-height
Если внутренний блок занимает не более одной строки текста, то можно воспользоваться свойством line-height
и задать его равным высоте внешнего блока. Поскольку контент внутреннего блока не должен переходить на вторую строку, желательно также добавить правила white-space: nowrap
и overflow: hidden
.
CSS
.outer {
height: 200px;
line-height: 200px;
}
.inner {
white-space: nowrap;
overflow: hidden;
}
Данный способ можно использовать и для выравнивания многострочного текста. Для этого внутреннему блоку нужно переопределить значение line-height
, а также добавить правила display: inline-block
и vertical-align: middle
.
CSS
.outer {
height: 200px;
line-height: 200px;
}
.inner {
line-height: normal;
display: inline-block;
vertical-align: middle;
}
Минус способа - должна быть известна высота внешнего блока.
4. Выравнивание с помощью “растягивания”
Данный способ можно применять, когда высота внутреннего блока нам известна, а внешнего - нет.
Чтобы применить данный метод нам необходимо:
- Внешнему блоку завдать относительное позиционирование
position: relative
, а внутреннему − абсолютноеposition: absolute
; - Внутреннему блоку добавить несколько правил
top: 0
иbottom: 0
, в результате чего он растянется на всю высоту внешнего блока; - Для вертикальных отступов внутреннего блока установить значение
auto
.
CSS
.outer {
position: relative;
}
.inner {
height: 100px;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
}
Минус данного способа — должна быть известна высота внутреннего блока.
5. Выравнивание с помощью отрицательного margin-top
Аналогично предыдуему, данный способ применяется, когда высота внешнего блока неизвестна, но известна высота внутреннего.
Нужно задать внешнему блоку относительное позиционирование, а внутреннему − абсолютное. После чего сдвинуть внутренний блок вниз на половину высоты внешнего блока top: 50%
и поднять вверх на половину собственной высоты margin-top: -H<sub>inner</sub> / 2
.
CSS
.outer {
position: relative;
}
.inner {
height: 100px;
position: absolute;
top: 50%;
margin-top: -50px;
}
Минус данного способа — должна быть известна высота внутреннего блока.
6. Выравнивание с помощью transform
Способ может применятся когда высота внутреннего блока неизвестна. Необходимо сдвинуть внутренний блок вниз на половину высоты внешнего блока top: 50%
, после чего воспользоваться свойством transform
и поднять его обратно вверх с помощью функции translateY(-50%)
.
CSS
.outer {
position: relative;
}
.inner {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
7. Выравнивание с помощью псевдоэлемента
Это наиболее универсальный способ, который может применяться, когда неизвестны высоты обоих блоков.
Суть способа в добавлении внутри внешнего блока строчного блока inline-block высотой в 100% и задания ему вертикального выравнивания. Таким образом, высота добавленного блока будет равна высоте внешнего блока. Внутренний блок выровняется по вертикали относительно добавленного, а значит, и внешнего блока.
Чтобы не нарушать семантику, строчный блок желательно добавлять с помощью псевдоэлементов before
или after
.
CSS
.outer:before {
display: inline-block;
height: 100%;
vertical-align: middle;
content: "";
}
.inner {
display: inline-block;
vertical-align: middle;
}
Минус данного способа — невозможно примнять при абсолютном позиционировании внутреннего блока.
8. Выравнивание с помощью Flexbox
Самым современным способом вертикального выравнивания является применение Flexible Box Layout (или сокращенно Flexbox). Он позволяет гибко управлять позиционированием элементов на странице, располагая их практически как угодно. Выравнивание по центру для Flexbox − очень простая задача.
Внешнему блоку указываем display: flex
, а внутреннему − margin: auto
. И это все! Красиво, правда?
CSS
.outer {
display: flex;
width: 200px;
height: 200px;
}
.inner {
width: 100px;
margin: auto;
}
Минус данного способа − Flexbox поддерживается только современными браузерами.
Какой способ выбрать?
- Для вертикального выравнивания текста можно использовать вертикальные отступы или свойство
line-height
. - Для абсолютно позиционированных элементов с известной высотой (например, иконок) подойдет способ с отрицательным свойством
margin-top
. - Для более сложных случаев, когда неизвестна высота блока, можно применять псевдоэлемент или свойство
transform
. - Как универсальный способ пора начинать (если еще не начали) использовать Flexbox.