Выравнивание по центру в CSS: приёмы, свойства, подводные камни
Как расположить что угодно по центру чего угодно с помощью каскадных таблиц стилей.


Иллюстрация: Оля Ежак для Skillbox Media
CSS существует и развивается с 1996 года. За четверть века и три редакции в этом языке появилось много разных способов отцентрировать элемент — как костыльных, так и каноничных.
В статье мы расскажем об основных приёмах для выравнивания по центру в CSS. Какой из них более удобен и приятен — решать вам.
Содержание:
Горизонтальное центрирование
Как работают способы из этого раздела, мы покажем на примере блоков div, однако применять их можно и к другим элементам: заголовкам, абзацам, изображениям, кнопкам, формам, спискам и так далее.
Для наглядности мы добавим границы блоков: синие для родительских и чёрные для дочерних.
С помощью Flexbox
Добавьте в родительский элемент свойства display: flex, чтобы сделать элемент flex-контейнером, и justify-content: center, чтобы контент внутри контейнера расположился посередине горизонтальной оси. Обратите внимание: justify-content действует только на flex-элементы, поэтому без display: flex он не заработает.
HTML:
<div class="parent">
<div class="child">Блок с текстом</div>
</div>
CSS:
.parent {
display: flex;
justify-content: center;
border: 2px solid blue;
}
.child {
border: 2px solid black;
}
Результат:

Преимущество такого метода в том, что дочерний блок будет автоматически подстраиваться под размеры содержимого. Если же нужно задать размеры явно, то сделать это можно с помощью width для ширины, и height для высоты.
Через автоотступы
Добавьте свойства margin-left: auto и margin-right: auto — они устанавливают автоматические отступы слева и справа. И укажите ширину с помощью width:
CSS:
.block {
width: 70px;
margin-left: auto;
margin-right: auto;
border: 2px solid black;
}
HTML:
<div class="block">Блок с текстом</div>
Результат:

Преимущество метода состоит в том, что не нужно явно прописывать свойства родительского элемента (в нашем случае это body).
Две строки с автоотступами можно заменить на одну: margin: 0 auto или margin: auto. В обоих случаях результат будет одинаковым.
С помощью inline-блоков
Проще всего выравнивать текст по горизонтали. Для этого существует свойство text-align: center, которое применяется к родительскому элементу.
CSS:
.parent {
text-align: center;
border: 2px solid blue;
}
HTML:
<div class="parent">Текст</div>
Результат:

Несмотря на своё название, text-align можно применять не только к тексту. Для этого нужно сделать элементы, которые хотите выровнять, встроенными — с помощью display: inline-block.
CSS:
.parent {
text-align: center;
border: 2px solid blue;
}
.child {
display: inline-block;
border: 2px solid black;
}
HTML:
<div class="parent">
<div class="child">Блок с текстом</div>
</div>
Результат:

В этом методе так же, как и в первом, размеры блока подстраиваются под содержимое. Но при желании можно явно задать ширину и высоту.
Выравнивание нескольких элементов
Каждый из трёх способов будет вести себя по-разному, если мы будем размещать по центру сразу несколько элементов. Возьмём один и тот же HTML-код и последовательно применим к нему описанные выше методы:
<div class="parent">
<div class="child">Блок с текстом</div>
<div class="child">Блок с текстом<br>в две строки</div>
<div class="child">Блок с текстом<br>в три<br>строки</div>
</div>
Flex-элементы выстраиваются в один ряд и приобретают одинаковую высоту:
.parent {
display: flex;
justify-content: center;
border: 2px solid blue;
}
.child {
border: 2px solid black;
}

С автоотступами каждый блочный элемент помещается в отдельную строку:
.block {
width: 120px;
margin: auto;
border: 2px solid black;
}

Инлайн-блоки остаются в одном ряду, но у них будет разная высота (у каждого — по размеру контента). Плюс текст в них автоматически выравнивается по центру.
.parent {
text-align: center;
border: 2px solid blue;
}
.child {
display: inline-block;
border: 2px solid black;
}

Вертикальное центрирование
При горизонтальном центрировании легко определить ширину родительского элемента: если она не задана явно, то обычно равна ширине экрана. При вертикальном центрировании всё немного сложнее: высоту родительского элемента приходится задавать явно с помощью свойства height.
Как и в прошлом разделе, мы будем показывать работу всех методов на примере блоков div и добавим те же границы: синие — для родительских и чёрные — для дочерних элементов. Во всех примерах будем использовать один и тот же HTML-код:
<div class="parent">
<div class="child">Блок с текстом</div>
</div>
С помощью Flexbox
Добавьте в родительский элемент свойства display: flex (превращает элемент во flex-контейнер) и align-items: center. Второе свойство отцентрирует весь контент внутри контейнера по вертикали.
.parent {
height: 100px;
display: flex;
align-items: center;
border: 2px solid blue;
}
.child {
border: 2px solid black;
}

С помощью свойств position и transform
Этот способ использует сразу много свойств для разных целей, поэтому разберём его по шагам.
Родительскому элементу нужно присвоить свойство position: relative, а дочернему — position: absolute. Благодаря этому мы сможем сдвинуть дочерний блок относительно верхнего края родительского, используя свойство top: 50%.
.parent {
height: 100px;
position: relative;
border: 2px solid blue;
}
.child {
position: absolute;
top: 50%;
border: 2px solid black;
}

Обратите внимание, что сейчас по центру расположена не середина блока с текстом, а его верхняя граница. Чтобы исправить это, дочерний элемент нужно сдвинуть на половину его высоты вверх. Делается это свойством transform: translate (0, -50%). Первое число означает смещение по горизонтали, второе — по вертикали.
.parent {
height: 100px;
position: relative;
border: 2px solid blue;
}
.child {
position: absolute;
top: 50%;
transform: translate(0, -50%);
border: 2px solid black;
}
В результате получается так:

Если по какой-то причине вы не хотите использовать свойство transform, вместо него можно поставить margin. Но для этого необходимо знать размер дочернего элемента и установить отрицательный margin-top, равный половине его высоты.
Ячейки таблицы
Добавьте в родительский элемент display: table-cell, чтобы блок вёл себя как ячейка таблицы, и vertical-align: middle — это свойство центрирует содержимое блока по вертикали.
.parent {
height: 100px;
display: table-cell;
vertical-align: middle;
border: 2px solid blue;
}
.child {
border: 2px solid black;
}

Это довольно костыльный и не очень удобный способ. Так как ячейка находится вне таблицы, мы не можем корректно управлять её шириной. Для этого нужно создать родительский элемент со свойством display: table и задавать width уже внутри него.
Выравнивание по центру
Чтобы поместить элемент по центру родительского блока (то есть выровнять одновременно по горизонтали и вертикали), иногда достаточно объединить под одним селектором методы горизонтального и вертикального центрирования.
Во всех примерах мы будем использовать один и тот же HTML-код и получать один и тот же результат.
<div class="parent">
<div class="child">Блок с текстом</div>
</div>

С помощью Flexbox
Чтобы центрировать элемент с помощью Flexbox, достаточно объединить горизонтальный и вертикальный способы:
.parent {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
border: 2px solid blue;
}
.child {
border: 2px solid black;
}
С помощью свойств position и transform
В этом случае нужно сделать всё то же, что и при вертикальным центрировании, но с двумя изменениями в стилях дочернего элемента:
- добавить свойство left: 50%;
- установить свойству transform значение translate (-50%, -50%).
.parent {
height: 100px;
position: relative;
border: 2px solid blue;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 2px solid black;
}
Через CSS Grid
Этот способ похож на вёрстку флексами. Нужно установить в родительском элементе свойство display: grid — оно превратит его в grid-контейнер. А в дочернем задать автоматические отступы с помощью margin: auto.
.parent {
height: 100px;
display: grid;
border: 2px solid blue;
}
.child {
margin: auto;
border: 2px solid black;
}
Центрирование на примерах
Теперь рассмотрим частные случаи, как отцентрировать текст, заголовок, список, форму, блок, изображение и кнопку.
Центрирование текста по горизонтали
Самый простой способ выровнять текст по горизонтали — использовать свойство text-align: center.
HTML:
<p class="center-text">Абзац текста, горизонтально выровненный по центру</p>
CSS:
.center-text {
text-align: center;
}
Результат:

Если добавить в абзаце автоматические отступы, то у текста как будто появятся границы, за которые он не будет выходить.
HTML:
<p class="center-text">Абзац текста, выровненный по центру, ограниченный справа и слева</p>
CSS:
.center-text {
width: 100px;
margin: auto;
text-align: center;
}
Результат:

При желании также можно использовать флексбоксы, но это менее удобно, потому что в таком случае придётся явно задавать родительский элемент.
Центрирование текста по вертикали
Все способы вертикального центрирования можно использовать и для выравнивания текста. В приведённых ниже примерах голубой рамкой выделены родительские элементы.
Flexbox. В этом случае нужно задать стили только для родительского элемента, а для дочернего CSS-кода можно не писать.
HTML:
<main class="parent">
<p class="child">Абзац с текстом, вертикально выровненный по центру</p>
</main>
CSS:
.parent {
height: 100px;
display: flex;
align-items: center;
border: 2px solid blue;
}
Результат:

Позиционирование. Если применить к элементу <p> свойства position и transform, позиционирование будет работать некорректно из-за того, что по умолчанию у него есть отступы. Решить это можно двумя путями.
Первый (рекомендуемый) — убрать из абзаца отступ свойством margin: 0.
HTML:
<main class="parent">
<p class="child">Абзац с текстом, вертикально выровненный по центру</p>
</main>
CSS:
.parent {
height: 100px;
position: relative;
border: 2px solid blue;
}
.child {
position: absolute;
top: 50%;
transform: translate(0, -50%);
margin: 0;
}
Второй — применить стиль дочернего элемента к тегу <span> внутри <p>.
HTML:
<main class="parent">
<p><span class="child">Абзац с текстом, вертикально выровненный по центру</span></p>
</main>
CSS:
.parent {
height: 100px;
position: relative;
border: 2px solid blue;
}
.child {
position: absolute;
top: 50%;
transform: translate(0, -50%);
При обоих путях результат будет один и тот же:

Ячейки таблицы. Здесь так же, как и в случае с флексбоксами, нужно задать стиль только для родительского элемента.
HTML:
<main class="parent">
<p>Абзац с текстом, вертикально выровненный по центру
</main>
CSS:
.parent {
height: 100px;
display: table-cell;
vertical-align: middle;
border: 2px solid blue;
}
Результат:

Как выровнять заголовок, список или форму
К заголовкам, спискам и формам применяются все те же способы позиционирования по центру, что и к обычному тексту: как по горизонтали, так и по вертикали.
Единственная особенность списков — их родителю не стоит присваивать свойство text-align: center. Выглядеть это будет плохо, можете убедиться в этом на следующем примере.
HTML:
<div class="parent">
<ul>
<li>Первый пункт</li>
<ul>
<li>Первый подпункт</li>
<li>Второй подпункт</li>
</ul>
<li>Второй пункт</li>
</ul>
</div>
CSS:
.parent {
text-align: center;
border: 2px solid blue;
}
Результат:

Как центрировать блок
Когда мы рассказывали о способах выравнивания элементов, приводили примеры именно на блоках. Поэтому, если вы ищете ответ на этот вопрос, перейдите в один из предыдущих разделов:
Как разместить блок посередине страницы
Чтобы поставить блок в центре веб-страницы, можно использовать любой из перечисленных выше способов. Однако будет два различия:
- в качестве родительского элемента выступает всё тело веб-страницы (элемент <body>);
- необязательно явно указывать высоту блока.
Во всех примерах результат будет одинаковым. Как и раньше, голубую и чёрную рамку используем для наглядности.

Flexbox. Недостаток этого подхода в том, что такая страница будет выравнивать по центру все элементы внутри себя, а не только те, которые нам нужны.
HTML:
<body>
<div>Блок посередине</div>
</body>
CSS:
body {
display: flex;
align-items: center;
justify-content: center;
border: 2px solid blue;
}
Позиционирование. Дополнительное отличие от описанного выше способа в том, что не нужно указывать свойство position: relative — ведь расположение <body> не зависит ни от каких других элементов.
В итоге для родительского элемента не нужно писать никаких свойств — достаточно задать их только тому блоку, который мы хотим разместить по центру.
HTML:
<body>
<div class="block">Блок посередине</div>
</body>
CSS:
body {
border: 2px solid blue;
}
.block {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 2px solid black;
}
Grid. Здесь мы задаём свойства как родительскому, так и дочернему элементу.
HTML:
<body>
<div class="block">Блок посередине</div>
</body>
CSS:
body {
display: grid;
border: 2px solid blue;
}
.block {
margin: auto;
border: 2px solid black;
}
Выравнивание картинок и кнопок по центру
Центрирование изображений <img> и кнопок <button> в CSS работает почти так же, как и с блоками. В большинстве случаев вы можете просто использовать те же методы, о которых мы рассказывали ранее:
- для горизонтального центрирования (кроме автоотступов);
- для вертикального центрирования (кроме некоторых случаев во флексбоксах);
- для выравнивания посередине (кроме некоторых случаев во флексбоксах).
Если вы выравниваете картинку или кнопку по горизонтали с помощью автоотступов, добавьте ей свойство display: block, чтобы она вела себя как блок.
HTML:
<img src="https://skillbox.ru/local/templates/media/images/common/menu-icon-3.svg">
CSS:
<img src="https://skillbox.ru/local/templates/media/images/commonimg {
height:150px;
display: block;
margin: auto;
}/menu-icon-3.svg">
Результат:

При выравнивании с помощью Flexbox изображения или кнопки могут вести себя необычно. Вот в каких случаях это происходит:
- задана высота родительского блока;
- не заданы размеры картинки;
- не указано свойство align-items.
При выполнении всех трёх условий изображение или кнопка растянутся, чтобы занять всё пространство родительского элемента — от верхней границы до нижней.
CSS:
.parent {
height: 300px;
display: flex;
justify-content: center;
border: 2px solid blue;
}
HTML:
<div class="parent">
<img src="https://skillbox.ru/local/templates/media/images/common/menu-icon-3.svg">
</div>
Результат:

Изображение: Skillbox Media
В остальных случаях флексбоксы будут работать так же, как и с блочными элементами.
Резюмируем
Основная сложность при выравнивании элементов веб-страницы по центру — обилие подходов, у каждого из которых свои тонкости и ограничения:
- Flexbox удобен для любого вида выравнивания. При таком подходе необходимо задавать стили только родительскому элементу.
- Позиционирование можно использовать для выравнивания по вертикали и размещения элемента по центру блока (выравнивания по вертикали и горизонтали одновременно).
- Автоотступы и inline-блоки удобно использовать для горизонтального выравнивания, ячейки таблицы — для вертикального, Grid — для размещения элемента по центру родительского блока.
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!