- PVSM.RU - https://www.pvsm.ru -
Мой первый пост.
Центрирование блока относительно другого блока относительно часто-попадающаяся задача, это очередное ее решение. Для меня оно стало самым универсальным и покрывающим все кейсы, с которыми я когда-либо сталкивался.
Формулировка
Центрировать модальное окно по горизонтали и вертикали.
Условия
Как это делалось раньше?
Если габариты модального окна заданы, то все просто:
<div class="fixed-overlay">
<div class="modal">
<div class="modal_container">
</div>
</div>
</div>
* {
box-sizing: border-box;
}
.fixed-overlay {
position: fixed;
overflow: auto;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.modal {
position: absolute;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -75px;
}
.modal_container {
background-color: #fff;
width: 200px;
height: 150px;
}
Работает прекрасно, нареканий нет. Но нам такой способ не подходит, ибо мы не хотим зависеть от размеров модального окна.
Первый способ, который удовлетворяет всем перечисленным требованиям я увидел у Jabher [1]. Речь идет об использовании свойства transform и его значения translate вместо margin. Вот как это работает:
.modal {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.modal_container {
padding: 20px;
background-color: #fff;
color: #000;
}
Магия! Теперь мы не зависим от габаритов .modal_container. Все потому что translate отталкивается от размеров элемента, к которому применятся свойство. Напомню, что процентные значения свойства margin будут вычисляться относительно размеров родителя, что нам явно не подходит.
Теперь о минусах. Используя свойство transform, мы столкнемся с субпиксельным рендерингом. Проще говоря, контент при ресайзе начнет замыливаться, результат выглядит скверно, особенно это заметно при рендере текста и тонких линий, вроде однопиксельных бордеров. Я не смог найти решений этой проблемы, если у вас они есть — пожалуйста, поделитесь в комментариях.
Не так давно я нашел изумительный по своей простоте способ. На помощь спешат инлайн блоки. Их легко центрировать по-горизонтали, навесив text-align: center на родителя. Немного подумав, я вспомнил про замечательное свойство vertical-align. Как оно работает? Если этому свойству задать значение middle, то элементы с этим свойством будут центрироваться по-вертикали друг относительно друга. А это значит, что помимо элемента .modal, в .fixed-overlay должен быть еще кто-то, кто поможет нашей модалке встать по-центру окна. Высота этого кого-то должна быть равна высоте .fixed-overlay. На роль этого помощника напрашивается псевдоэлемент:
<div class="fixed-overlay fixed-overlay__modal">
<div class="modal">
<div class="modal_container">
</div>
</div>
</div>
.fixed-overlay__modal {
text-align: center;
white-space: nowrap;
}
.fixed-overlay__modal::after {
display: inline-block;
vertical-align: middle;
width: 0;
height: 100%;
content: '';
}
.modal {
display: inline-block;
vertical-align: middle;
}
.modal_container {
margin: 50px;
padding: 20px;
min-width: 200px;
text-align: left;
white-space: normal;
background-color: #fff;
color: #000;
}
Пример: jsfiddle.net/yvp0jdnw/ [2]
Буду рад любой критике, это мой первый опыт написания статей.
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/pesochnitsa/85463
Ссылки в тексте:
[1] Jabher: http://habrahabr.ru/users/jabher/
[2] jsfiddle.net/yvp0jdnw/: http://jsfiddle.net/yvp0jdnw/
Нажмите здесь для печати.