Задача
СкопированоПеред вами встала задача выровнять блок по центру экрана по вертикали и горизонтали. Предположим, это будет всплывающее окно. В этом рецепте разберём все существующие на данный момент способы решения задачи.
Готовое решение
СкопированоНиже перечислены все возможные способы центрирования элемента. Выберите один из них.
Центрируем при помощи гридов:
.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 с функцией translate в качестве значения.
.child { margin-inline: auto; margin-block-start: 50vh; transform: translateY(-50%);}
.child {
margin-inline: auto;
margin-block-start: 50vh;
transform: translateY(-50%);
}
При трансформации проценты вычисляются от фактического размера элемента, к которому эта трансформация применяется. Поэтому наш блок поднимается вверх ровно на половину своей высоты.
Абсолютное позиционирование с известной высотой
СкопированоВернём нашему диалогу абсолютное позиционирование и попробуем выровнять его в таком состоянии. Не забудем задать родителю position, чтобы ребёнок позиционировался от краёв родителя.
Для начала разберём пример, когда у элемента задана фиксированная высота:
.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%);
}