Выравнивание по центру в CSS

Выравнивание по центру в CSS
mangohost

Выравнивание элементов по центру в CSS - это одна из самых популярных причин чтобы пожаловаться на CSS. «Почему всё так сложно?» - возмущаются они. Мне кажется, что проблема заключается не в том что это трудно сделать, а в том что способов для выравнивания элементов по центру очень много и бывает достаточно сложно выбрать из них подходящий.

Давайте выстроим все возможные решения в виде древовидной схемы и будем надеяться, что это упростит нашу задачу.

Итак, мне нужно выравнять элемент по центру...

Горизонтальное выравнивание

Выравнивание по центру строкового или строково-* элемента

Выравнивать по центру строковые элементы внутри блочного родительского элемента можно достаточно просто:

.center-children {
  text-align: center;
}

Это будет работать для inline, inline-block, inline-table, inline-flex, и т. д.

Выравнивание по центру блочного элемента

Выравнять по центру блочный элемент вы можете установив свойствам margin-left и margin-right значение auto (у него также должна быть задана ширина, иначе элемент просто займёт всю ширину контента и не будет необходимости в выравнивании). Чаще всего это делается с помощью сокращённого свойства, вот так:

.center-me {
  margin: 0 auto;
}

Это будет работать независимо от того какая ширина установленная у блочного элемента или его родителя.

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

Выравнивание по центру нескольких блочных элементов

Если есть два или более блочных элементов, которые вам нужно выравнять горизонтально по центру в пределах одной строки, то возможно вам лучше изменить их тип отображения. Ниже приведён пример изменения их типа отображения на inline-block и пример с Flexbox:

Если эти несколько блоков расположены на разных строках, то техника с автоматическими отступами по прежнему прекрасна:

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

Вертикальное выравнивание по центру в CSS немного сложнее.

Выравнивание по центру строкового или строково-* элемента

Выравнивание элемента с одной строкой

Иногда строковые/текстовые элементы могут выравниваться по центру просто потому что у них одинаковое значения для свойств padding-top и padding-bottom.

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}

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

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

Выравнивание многострочного элемента

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

Если это что-то похожее на таблицу, возможно вы сможете использовать Flexbox ? Отдельный Flex-элемент может быть легко расположен по центру внутри Flex-контейнера.

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}

Помните, что это на самом деле актуально когда у контейнера есть фиксированная высота (px, %, и другие), вот почему здесь у контейнера задана высота.

Если обе техники приведённые выше нельзя применить, вы можете использовать технику «призрачного элемента», в которой псевдоэлемент с высотой в 100% размещается внутри контейнера и тех выравнивается вертикально по центру него.

.ghost-center {
  position: relative;
}

.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}

.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}

Выравнивание по центру блочного элемента

Выравнивание элемента с известной высотой

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

Но если вы знаете высоту элемента, то можете выравнивать по центру вот так:

 

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}

Выравнивание элемента с неизвестной высотой

Даже если вы не знаете высоту элемента, его всё ещё можно протолкнуть на 50% высоты его родителя, а после поднять на 50% его собственной высоты:

.parent {
  position: relative;
}

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

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

Небольшой сюрприз, это можно очень просто сделать с помощью Flexbox.

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

Горизонтальное и вертикальное выравнивание

Вы можете комбинировать представленные выше техники для того чтобы получить идеально выравненные по центру элементы. Но обычно их можно разделить на 4 группы:

Выравнивание элемента с фиксированной шириной и высотой

Использование отрицательных отступов (maring) равных половине этой ширины и высоты после абсолютного позиционирования элемента 50% / 50% выравняют элемент по центру. У этого способа достаточно хорошая кроссбраузерная поддержка:

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

  position: absolute;
  top: 50%;
  left: 50%;

  margin: -70px 0 0 -170px;
}

Выравнивание элемента с неизвестной шириной и высотой

Если вы не знаете ширину или высоту элемента, то можете использовать свойство transform и отрицательный translate в 50% в обоих направлениях (в зависимости от текущей ширины / высоты элемента) до центра:

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

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

Чтобы выровнять элемент по центру с помощью Flexbox вам нужно использовать два свойства центрирования:

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

Выравнивание элемента с помощью CSS Grid

Это просто небольшой трюк (присланный Lance Janssen), который в большей степени будет работать для одного элемента:

body, html {
  height: 100%;
  display: grid;
}

span { /* thing to center */
  margin: auto;
}

Вывод

Теперь вы можете всё что угодно выравнять по центру в CSS.

mangohost