Центрирование элементов в css - это совсем не праздный вопрос, т.к. это довольно распространенная ситуация в верстке. В этой статье мы рассмотрим разные способы горизонтального и вертикального центрирования элементов на странице.
Устаревшие варианты центрирования
На всякий случай хочу напомнить, что такой популярный тег, как <center>
, который в далекие времена HTML4 выравнивал по центру содержимое блочного элемента, давно считается устаревшим и вызовет ошибку при валидации вашей страницы. Также в HTML4 был популярен атрибут align="center"
, с которым ситуация аналогична.
Выравнивание по горизонтальному центру строчных (inline) и строчно-блочных (inline-block) элементов
Как известно, у нас есть простые способы центрировать контент по горизонтали. Для этого мы используем text-align: center
для абзаца, div-а, заголовка, т.е. любого блочного элемента, внутри которого размещен текст или картинка, - и все работает. Например, код для изображения ниже будет таким:
1 2 3 | <p style="text-align: center"> <img src="images/cube.jpg" alt="Центрированное изображение" width="300" height="210"> </p> |
Аналогично будет центрирован любой элемент, для которого свойство display
задано, как inline
или inline-block
.
Выравнивание по горизонтальному центру блочных (block) элементов с помощью margin: auto
В том случае, если нам нужно центрировать блочный элемент относительно страницы, то тут тоже есть давно работающий метод, который предполагает указание ширины элемента и margin: auto
, например, так форматируется большая часть контейнеров:
1 2 3 4 5 6 7 | .container { width: 90%; max-width: 1200px; padding-left: 15px; padding-right: 15px; margin: auto; } |
Вариации кода могут быть разными, но принцип понятен, я думаю. Можно разместить простую форму посередине ее родительского элемента. Поскольку тег <form>
относится к блочным, то margin: auto
сработает для него в качестве центрирующего правила при заданной ширине (свойство width
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <style> #center-form { width: 350px; height: 200px; padding: 20px; border: 3px double #1e8cbe; border-radius: 12px; margin: 20px auto; } </style> <div class="test"> <form id="center-form"> <p><input name="login" type="text" placeholder="Логин"></p> <p><input name="login" type="password" placeholder="Пароль"></p> <button class="button">Войти</button> </form> </div> |
Смотрим на результат:
Свойство margin: auto
или margin: 20px auto
, как в стилях для формы, или 2 свойства: margin-left: auto
+ margin-right: auto
, заданные для блочного элемента с определенной шириной, сообщают браузеру, что тот должен самостоятельно рассчитать отступы слева и справа таким образом, чтобы они были одинаковыми. Браузеру сделать это несложно, т.к. ему всегда известна ширина открытого на данный момент окна, поэтому вычесть из нее ширину блочного элемента и разделить полученное значение на 2 для браузера пара пустяков.
Используем свойства position: absolute и transform: translate
Для абсолютно позиционированных элементов характерно особое поведение - они "вырываются" из своего родительского контейнера, "схлопывая" его высоту в 0, если явно не задано значение таких свойств, как height
или min-height
или размеры родителя не включают padding
. Кроме того, такие элементы имеют ширину, равную их контенту, если она не задана явно, поэтому бывает сложно ее рассчитать.
Для горизонтального центрирования абсолютно позиционированного элемента сначала нужно задать свойства для его родителя: position: relative
и min-height
. А для центрируемого элемента, помимо различных "оформительских" свойств (цвета фона, рамки, размера текста, внутренних отступов и т.д.) обязательно нужно указать position: absolute; left: 50%;
и transform: translate(-50%)
. В этом случае можно не задавать ширину или высоту элемента - она будет рассчитана на основе остальных свойств и содержимого. Однако никто не мешает сделать это явно, использовав свойства width
и height
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <style> .parent { position: relative; min-height: 140px; } .use-transform { text-align: center; padding: 20px; font-size: 20px; border: 3px double #1e8cbe; background-color: #cde; border-radius: 12px; position: absolute; left: 50%; transform: translate(-50%); } </style> <div class="parent"> <div class="use-transform">3-й способ<br> с position: absolute</div> </div> |
Давайте посмотрим на примере:
с position: absolute
Второй вариант, допустимый для горизонтального центрирования абсолютно позиционированных элементов, основан на отрицательном внешнем отступе с левой стороны, но он менее универсален, т.к. требует точного указания ширины элемента. В этом случае необходимо для элемента указать margin-left: -половина его ширины
, например так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <style> .parent-2 { position: relative; min-height: 230px; } #abs-center-img { width: 300px; box-shadow: 0 2px 18px #909090; position: absolute; left: 50%; margin-left: -150px; border: 2px solid #fff; } </style> <div class="parent-2"> <img id="abs-center-img" src="images/margin-font.png" alt="Центрированное изображение" width="300" height="200"> </div> |
Вот как это смотрится для абсолютно позиционированного изображения:
Вот, что еще можно сделать на основе такого подхода (автор Braydon Coyer):
See the Pen Kobe RIP by Braydon Coyer (@braydoncoyer) on CodePen.
Вертикальное и горизонтальное выравнивание с помощью position: absolute
Здесь используется тот же принцип, что и в примере с transform: translate(-50%)
но смещение на 50% идет по обеим осям. При этом важно, чтобы внутри родительского элемента высота была избыточной по сравнению с вложенным элементом.
Размещаем текстовый блок:
1 2 3 4 5 6 7 8 | #abs-center-text { width: 250px; padding: 15px; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } |
Реализация:
Vertical+Horizontal Center
Lorem ipsum dolor sit amet consectetur adipisicing elit. Saepe laborum necessitatibust!
Использование line-height для вертикального центрирования
Для элементов, которые содержат одну строку текста/иконку, можно использовать вертикальное центрирование за счет указания свойства line-height такого же размера, как и высота элемента. Учтите, что свойство line-height
- одно из немногих, для которого необязательно задавать единицы измерения, т.е. оно может быть выражено, как в px или в %, так и в виде цифры-коэффициента:
1 2 3 4 5 6 7 | .some { line-height: 160% } равносильно .some { line-height: 1.6 } .some2 { line-height: 16 } значительно больше, чем .some2 { line-height: 16px } |
В примере ниже для всех элементов с классом .icon заданы свойства height: 80px
и line-height: 80px
, за счет чего иконки размещаются по центру круга. Во второй иконке это свойство переопределено в классе .no-line-height в виде line-height: inherit
- и мы видим, что иконка "отправилась" к верху круга.
Вторая часть этого примера - это форматирование ссылки в виде кнопки. Здесь, наоборот, 2 кнопки имеют общий класс .violet
с высотой в 50px (height: 50px
), и текст в первой тоже размещен в верхней части кнопки. Зато ко второй кнопке добавлен класс .line-height со свойством line-height: 50px
- и текст в ней центрирован.
Поскольку все элементы в примере имеют свойство display: inline-block
, то text-align: center
, заданный для контейнера, выравнивает весь текст внутри каждого из них по горизонтальному центру.
See the Pen line-height for vertical text centering by Elen (@ambassador) on CodePen.
Выравнивание текста в кнопках с помощью padding
Если у вас есть необходимость как-то оформить кнопки или ссылки, то одним из вариантов является назначение ширины и высоты этому элементу, особенно, если у вас есть макет, и в нем эти величины можно получить без проблем. Однако, если вы видите, что ширина элемента зависит от текста на кнопке/ссылке, то имеет смысл центрировать этот текст, просто задавая вокруг него внутренние отступы padding
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <style> .my-link, .my-button { display: inline-block; margin: 20px 15px; background-color: #1b45cc; color: #fff; padding: 10px 25px; text-decoration: none; font-size: 16px; border: none; border-radius: 6px; } .my-button { padding: 15px 40px; } .my-link:hover, .my-button:hover { box-shadow: 0 2px 18px #909090; } </style> <a href="#center-padding" class="my-link">My Link</a> <button class="my-button">My Button</button> |
В примере выше и кнопка, и ссылка не имеют ни width
, ни height
в качестве свойств, но у первой ширина формируется отступами в виде свойства padding: 10px 25px
, а во второй - padding: 15px 40px
.
Посмотрим, что получилось:
Вторая кнопка несколько больше первой, как и ее отступы.
Используем свойства display: inline-table
для родителя + display: table-cell
для вложенного элемента, а также свойство vertical-align: middle
для вертикального центрирования
В таблицах легко можно установить размещение содержимого ячейки по центру с помощью свойства vertical-align: middle
. Почему бы не воспользоваться этим подходом для элементов, которые изначально табличными не являются? В CSS мы имеем довольно приличный список варантов отображения элементов с помощью свойства display
. Среди них есть display: inline- table
и display: table-cell
. Именно они + vertical-align: middle
помогут нам разместить иконки в примере ниже по вертикальному центру, а text-align: center
для контейнера, выравнивает текст и иконки по горизонтальному центру.
See the Pen Parent display: table + Child display: table-cell by Elen (@ambassador) on CodePen.
Использование flexbox для горизонтального и вертикального центрирования элементов
Способ 1. Сочетание свойств justify-content: center
и align-items: center
Свойства Flexbox-модели позволяют выровнять элемент не только по горизонтали, но и по вертикали. Для этого нужно использовать всего 3 свойства для родительского элемента: display: flex;
, justify-content: center;
и align-items: center
. Для того чтобы было видно, как сработало последнее свойство, необходимо также добавить высоту родительскоиу элементу (в примере - height: 320px
). Если у вас внутрь flex-контейнера вложен не один, а несколько элементов, то для того, чтобы они расположились друг под другом, нужно еще добавить свойство flex-direction: column
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <style> .test-flex{ height: 320px; display: flex; justify-content: center; align-items: center } figure {border: 2px dotted #a9a9a9;} figcaption { text-align: center; font-weight: bold; margin-bottom: 10px; } </style> <div class="test-flex"> <figure> <img src="images/cube.jpg" alt="Центрирование flex" width="300" height="200" style="margin: 0" /> <figcaption>3D Cube</figcaption> </figure> </div> |
Пример вживую:
Способ 1а: display: inline-flex для небольших элементов
Для небольших элементов типа иконок, которые вставлены в круглые/квадратные элементы с целью дополнительного оформления можно использовать сочетание display: inline-flex + justify-content: center + align-items: center
. За счет этих свойств у нас выравнивается контент в виде иконки, созданной на основе Fontawesome, по центру круга. За счет того, что сами иконки имеют свойство display: inline-flex
, их можно легко центрировать внутри контейнера с помощью свойства text-align: center
.
See the Pen inline-flex centering by Elen (@ambassador) on CodePen.
Способ 2: используем display: flex для родителя и margin: auto для дочернего элемента
Очень простой способ, который предполагает наличие одного дочернего элемента внутри flex-контейнера. CSS-стили лаконичны:
1 2 3 4 5 6 7 | .parent { height: 400px; display: flex; } .child{ margin: auto; } |
В примере ниже такой вариант применен для размещения текста по центру header-a для html-страницы.
See the Pen WNGKWNQ by Elen (@ambassador) on CodePen.
Используем свойства Grid-модели
Относительно новая система верстки Grid-модель также предоставляет набор свойств для центрирования контента в блоке не только по горизонтали, но и по вертикали. В примере ниже свойства очень похожи на те, что мы рассматривали для Flexbox-модели.
1 2 3 4 5 | .banner{ display: grid; justify-items: center; align-items: center; } |
Практический пример с баннером:
See the Pen Grid centered banner by Elen (@ambassador) on CodePen.
Можно заменить свойства одним place-items: center
, которое обеспечивает горизонтальное и вертикальное центрирование элементов.
1 2 3 4 | .banner{ display: grid; place-items: center; } |
See the Pen Centered Grid property place-items: center by Elen (@ambassador) on CodePen.