Выравнивание по вертикали CSS

05.02.2019 at 08:56

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

Свойство vertical-align

Это встроенный стандартный метод выравнивания, который может использоваться для строчных элементов и таблиц.
Он может набирать разных значений. Первое из них – baseline. Выравнивание осуществляется по базовой линии родительского элемента.

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

Второе значение – sub. Его ориентир – нижняя базовая линия родительского элемента. Например, так.

Противоположное sub выравнивание super. Ориентиром служит верхняя базовая линия родительского элемента.

Оба эти значения в таблицах аналогичны baseline.
Совершенно другая ситуация с выравниванием middle. Это значение css позволяет выровнять текст по центру. Здесь ориентиром служит середина родительского элемента. Вычисляется она очень просто: берется его размер по вертикали и делится пополам. Через центр проводится линия, по которой и выравнивается элемент.
В случае с таблицами элемент выравнивается по середине ячейки без границ.

Еще одна пара значений – top-bottom. Они выравнивают элемент по верхней и нижней линии строки соответственно. Ну или ячейки, если речь идет о таблице.
Также можно указывать размещение элемента по горизонтали в процентах или непосредственном значении в единицах, поддерживаемых CSS (пикселях, сантиментрах, em и так далее). В этом случае браузер ориентируется на базовую линию родительского элемента. В таблицах код себя ведет так же, как если верстальщик укажет baseline в качестве значения.

Возможные проблемы

Предположим, мы хотим нарисовать с помощью HTML и CSS такой рисунок.

С точки зрения HTML необходимо создать два div элемента. Присвоим внешнему родительскому элементу класс outer, а внутреннему – inner. В качестве примера приведем ситуацию, когда мы знаем заранее размеры каждого блока.
Необходимо прописать такой css-код.

.outer {

/* Размеры внешнего блока */
    width: 200px; 
    height: 200px;
    text-align: center;
    vertical-align: middle;
    background-color: #ffc; /* Фоновый цвет нужно указать, чтобы видеть границы внутреннего и внешнего элементов */
}
.inner {
    display: inline-block; /* Выравнивание возможно лишь для элементов, отображающихся как inline или inline-block */
    width: 100px;
    height: 100px;
    background-color: #fcc;
}

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

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

Использование таблицы для выравнивания текста по вертикали в CSS

В отличие от инлайн-блоков, выравнивание ячейки таблицы позволяет переместить и ее содержимое. Сделать это можно просто средствами HTML.

<table id="outwrap">
    <td id="out">
        <div id="in"></div>
    </td>
</table>

Недостатков у такого подхода два:

  1. Неправильно с позиции семантики применять таблицы для этой цели.
  2. Необходимо создать лишний элемент.

Исправить первый недостаток можно, изменив теги table и td на div и использовать режим отображения «table» и «table-cell» соответственно.

#outwrap {
    display: table;
}

#out {
    display: table-cell;
}

Но вот второй недостаток все равно останется. Код будет немного тяжеловат, особенно если таких элементов много.

Отступы

Можно выровнять внутренний див по центру с помощью вертикальных отступов. Недостаток метода – необходимо точно знать высоту обоих блоков. Величина отступа вычисляется по формуле (высота внешнего блока – высота внутреннего блока)/2. Пример кода.

#out {
    height: 200px;
}

#in {
    height: 100px;
    margin: 50px 0;
}

Line-height

С помощью этого свойства также можно выравнивать элементы по вертикали. Важно, чтобы в инлайн-блоке было не больше одной строчки текста. Это основной недостаток метода. Если эти правила соблюдены, необходимо приравнять line-height к высоте внешнего дива.
Поскольку нельзя допускать, чтобы образовывалось больше одной строчки, рекомендуется добавить к коду правила white-space: nowrap и overflow: hidden.
Код будет выглядеть следующим образом.

#out {
    height: 200px;
    line-height: 200px;
}

#in {
    white-space: nowrap;
    overflow: hidden;
}

Еще один недостаток этого способа исправить проблему – необходимость знать высоту внешнего блока.

Растягивание

Этот метод можно использовать, если известна высота только внутреннего блока. Сначала необходимо выставить абсолютное позиционирование для него, а для внешнего – относительное. Для внутреннего блока также устанавливаются правила top: 0 и bottom: 0, чтобы расширить его по всей высоте внешнего блока.
После этого выставляется значение вертикальных отступов внутреннего блока на auto. Код выглядит следующим образом.

#out {
    position: relative;
}

#in {
    height: 100px;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto 0;
}

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

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

  1. Внутренний блок опускается вниз на половину высоту внешнего.
  2. После этого он поднимается вверх на половину своей высоты.

Технически метод реализуется следующим образом.

#out {
    position: relative;
}

#in {
    height: 100px;
    position: absolute;
    top: 50%;
    margin-top: -50px;
}

Свойство transform

В отличие от предыдущего метода, здесь не требуется знать высоту внутреннего блока. Во всем остальном способ такой же самый, просто вместо margin-top: -50px пишется transform: translateY(-50%).
Возникает вопрос: почему в прошлом способе нельзя было сдвинуть объект вверх на определенное количество процентов. Причина кроется в том, что margin-top высчитывает процент от родителя, в то время как transform позволяет сдвинуть объект на определенный процент от своей высоты.
Недостаток метода в плохой поддержке старых версий браузеров.

Выравнивание с помощью Flexbox

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

.out {
    display: flex;
    width: 200px;
    height: 200px;
}

.in {
    width: 100px;
    margin: auto;
}

Этот способ идеален, если основная аудитория сайта пользуется современными браузерами.

Tags: