Выравнивание модального окна по центру

от автора

Мой первый пост.
Центрирование блока относительно другого блока относительно часто-попадающаяся задача, это очередное ее решение. Для меня оно стало самым универсальным и покрывающим все кейсы, с которыми я когда-либо сталкивался.

Формулировка
Центрировать модальное окно по горизонтали и вертикали.

Условия

  • Габариты модалки могут быть указаны в любых единицах измерения. Или же могут быть не указаны вовсе.
  • Отзывчивость. При ресайзе окна, модалка подстраивается под текущий размер.
  • Если модалка сверстана так, что у нее еcть min-height/min-width, то при ресайзе окна до меньших размеров должен появляться скролл.
  • IE 9+.
  • Позиционирование должны быть реализовано на CSS, без применения JS.

Как это делалось раньше?
Если габариты модального окна заданы, то все просто:

<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. Речь идет об использовании свойства 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/

Буду рад любой критике, это мой первый опыт написания статей.

ссылка на оригинал статьи http://habrahabr.ru/post/252769/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *