Задача
СкопированоПеред вами встала задача выровнять блок по центру экрана по вертикали и горизонтали. Предположим, это будет всплывающее окно. В этом рецепте разберём все существующие на данный момент способы решения задачи.
Готовое решение
СкопированоНиже перечислены все возможные способы центрирования элемента. Выберите один из них.
Центрируем при помощи гридов:
.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>
. Именно с его помощью сейчас принято создавать всплывающие окна.
Обратите внимание, что по умолчанию у этого элемента задано абсолютное позиционирование. Переопределим позиционирование на статичное, чтобы оно нам не мешало.
Стартовый код:
<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%); }