Клавиша / esc

Блок по центру экрана

6 способов выровнять блок по центру по вертикали и горизонтали.

Время чтения: 5 мин

Задача

Скопировано

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

Готовое решение

Скопировано

Ниже перечислены все возможные способы центрирования элемента. Выберите один из них.

Центрируем при помощи гридов:

        
          
          .parent {  display: grid;  place-items: center;}
          .parent {
  display: grid;
  place-items: center;
}

        
        
          
        
      

Центрируем при помощи флексбокса, способ первый:

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

        
        
          
        
      

Центрируем при помощи флексбокса, способ второй:

        
          
          .parent {  display: flex;}.child {  margin: auto;}
          .parent {
  display: flex;
}

.child {
  margin: auto;
}

        
        
          
        
      

Используем margin и transform:

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
  transform: translateY(-50%);
}

        
        
          
        
      

Абсолютное позиционирование, когда известна высота:

        
          
          .child {  height: 200px;  margin-inline: auto;  inset-inline: 0;  /* Отступ сверху 50% минус половина высоты */  inset-block-start: calc(50% - 100px);}
          .child {
  height: 200px;
  margin-inline: auto;
  inset-inline: 0;
  /* Отступ сверху 50% минус половина высоты */
  inset-block-start: calc(50% - 100px);
}

        
        
          
        
      

Абсолютное позиционирование, когда высота неизвестна:

        
          
          .child {  margin-inline: auto;  inset-inline: 0;  inset-block-start: 50%;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: 50%;
  transform: translateY(-50%);
}

        
        
          
        
      

Разбор решения

Скопировано

Перед разбором каждого из решений разберёмся со стартовым кодом. Во всех примерах зададим 100% высоты окна браузера для <html> и <body>, чтобы страница растянулась по высоте.

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

В качестве блока, который будем центрировать, используем тег <dialog>. Именно с его помощью сейчас принято создавать всплывающие окна.

Обратите внимание, что по умолчанию у этого элемента задано абсолютное позиционирование. Переопределим позиционирование на статичное, чтобы оно нам не мешало. Также учтите, что в примерах использован HTML-тег <dialog> с явно заданными значениями для ширины и высоты. При применении к другим тегам удостоверьтесь, что у них установлены значения для width и height.

Стартовый код:

        
          
          <body class="parent">  <dialog class="child" open>    <h1>Привет, это Дока!</h1>  </dialog></body>
          <body class="parent">
  <dialog class="child" open>
    <h1>Привет, это Дока!</h1>
  </dialog>
</body>

        
        
          
        
      
        
          
          html {  height: 100vh;}body {  min-height: 100%;}dialog {  position: static;}
          html {
  height: 100vh;
}

body {
  min-height: 100%;
}

dialog {
  position: static;
}

        
        
          
        
      
Открыть демо в новой вкладке

Гриды

Скопировано

Самый современный и изящный способ центрирования элемента — при помощи гридов.

Делаем родителя — в нашем случае .parent — грид-контейнером.

        
          
          .parent {  display: grid;}
          .parent {
  display: grid;
}

        
        
          
        
      

После этого можем использовать свойства грид-контейнера для выравнивания вложенных элементов по вертикальной и горизонтальной осям:

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

        
        
          
        
      

Или использовать шорткат для объединения двух свойств в одно:

        
          
          .parent {  display: grid;  place-items: center;}
          .parent {
  display: grid;
  place-items: center;
}

        
        
          
        
      
Открыть демо в новой вкладке

Флексбокс. Первый способ

Скопировано

Используем флексбокс для выравнивания по центру. Тут есть два способа. В первом случае будем задавать свойства родителю.

Делаем родителя флекс-контейнером:

        
          
          .parent {  display: flex;}
          .parent {
  display: flex;
}

        
        
          
        
      

Задаём свойства для выравнивания по центру вертикальной и горизонтальной осей:

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

        
        
          
        
      
Открыть демо в новой вкладке

Флексбокс. Второй способ

Скопировано

Когда родитель является флекс-контейнером, ребёнку можно задать автоматические внешние отступы со всех сторон.

        
          
          .parent {  display: flex;}.child {  margin: auto;}
          .parent {
  display: flex;
}

.child {
  margin: auto;
}

        
        
          
        
      
Открыть демо в новой вкладке

Отступ и трансформация

Скопировано

В этом способе используем комбинацию внешних отступов и трансформации. Для начала выровняем блок по горизонтальной оси автоматическими отступами, а от верхнего края отодвинем на 50%:

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
}

        
        
          
        
      
Открыть демо в новой вкладке

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

Чтобы расположить элемент ровно по центру, нужно использовать свойство transform с функцией translateY() в качестве значения.

        
          
          .child {  margin-inline: auto;  margin-block-start: 50vh;  transform: translateY(-50%);}
          .child {
  margin-inline: auto;
  margin-block-start: 50vh;
  transform: translateY(-50%);
}

        
        
          
        
      
Открыть демо в новой вкладке

При трансформации проценты вычисляются от фактического размера элемента, к которому эта трансформация применяется. Поэтому наш блок поднимается вверх ровно на половину своей высоты.

Абсолютное позиционирование с известной высотой

Скопировано

Вернём нашему диалогу абсолютное позиционирование и попробуем выровнять его в таком состоянии. Не забудем задать родителю position: relative, чтобы ребёнок позиционировался от краёв родителя.

Для начала разберём пример, когда у элемента задана фиксированная высота:

        
          
          .parent {  position: relative;}.child {  position: absolute;  height: 200px;}
          .parent {
  position: relative;
}

.child {
  position: absolute;
  height: 200px;
}

        
        
          
        
      

Сначала нужно задать элементу координаты отсчёта позиции. Пока зададим 0 со всех четырёх сторон. Используем логическое свойство inset.

        
          
          .child {  position: absolute;  height: 200px;  inset: 0;}
          .child {
  position: absolute;
  height: 200px;
  inset: 0;
}

        
        
          
        
      

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

По вертикали от верхнего края хотим оттолкнуть элемент на 50% минус половина высоты элемента. В нашем случае это 125 пикселей. Будем использовать функцию calc():

        
          
          .child {  position: absolute;  height: 250px;  margin-inline: auto;  inset-inline: 0;  inset-block-start: calc(50% - 125px);}
          .child {
  position: absolute;
  height: 250px;
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: calc(50% - 125px);
}

        
        
          
        
      
Открыть демо в новой вкладке

Абсолютное позиционирование без известной высоты

Скопировано

В этом варианте высота элемента не фиксирована. Значит, нам нечего вычитать из 50% для отступа от верхнего края. Используем transform, который вычисляет проценты от размера элемента.

        
          
          .child {  position: absolute;  margin-inline: auto;  inset-inline: 0;  inset-block-start: 50%;  transform: translateY(-50%);}
          .child {
  position: absolute;
  margin-inline: auto;
  inset-inline: 0;
  inset-block-start: 50%;
  transform: translateY(-50%);
}

        
        
          
        
      
Открыть демо в новой вкладке