Выравниваем блок по центру страницы
Очень часто стоит задача выровнять блок по центру страницы / экрана, да ещё и так, чтобы без ява-скрипта, без задания жёстких размеров или отрицательных отступов, ещё чтобы и скроллбары работали у родителя, если блок превышает его размеры. В сети ходят достаточно много однообразных примеров как выровнять блок по центру экрана. Как правило большинство из них основаны на одних принципах.
Ниже представлены основные способы решения задачи, их плюсы и минусы. Чтобы понимать суть примеров, рекомендую уменьшить высоту / ширину окошка Result в примерах по указанным ссылкам.
Вариант 1. Отрицательный отступ.
Позиционируем блок атрибутами top и left на 50%, и заранее зная высоту и ширину блока, задаём отрицательный margin, который равен половине размера блока. Огромным минусом данного варианта является то, что нужно подсчитывать отрицательные отступы. Так же блок не совсем корректно ведёт себя в окружении скроллбаров — он попросту обрезается так как имеет отрицательные отступы.
Пример: jsfiddle.net/serdidg/pphzjh25/1/.
<div class="parent">
<div class="block">
<img src="http://habrastorage.org/files/50f/7b2/1cc/50f7b21ccabd4b20bc0369f228138b5b.jpg" alt=""/>
</div>
</div>
.parent {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: auto;
}
.block {
width: 250px;
height: 250px;
position: absolute;
top: 50%;
left: 50%;
margin: -125px 0 0 -125px;
img {
max-width: 100%;
height: auto;
display: block;
margin: 0 auto;
border: none;
}
}
Вариант 2. Автоматический отступ.
Менее распространённый, но схожий с первым. Для блока задаём ширину и высоту, позиционируем атрибутами top right bottom left на 0, и задаём margin auto. Плюсом данного варианта являются рабочие скроллбары у родителя, если у последнего задана 100% ширина и высота. Минусом данного способ является жёсткое задание размеров.
Пример: jsfiddle.net/serdidg/sg0xbw88/1/.
<div class="parent">
<div class="block">
<img src="http://habrastorage.org/files/50f/7b2/1cc/50f7b21ccabd4b20bc0369f228138b5b.jpg" alt=""/>
</div>
</div>
.parent {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: auto;
}
.block {
width: 250px;
height: 250px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
img {
max-width: 100%;
height: auto;
display: block;
margin: 0 auto;
border: none;
}
}
Вариант 3. Таблица.
Задаём родителю табличные стили, ячейке родителя устанавливаем выравнивание текста по центру. А блоку задаём модель строчного блока. Минусами мы получаем не рабочие скроллбары, и в целом не эстетичность «эмуляции» таблицы.
Пример: jsfiddle.net/serdidg/fk5nqh52/2/.
<div class="parent">
<div class="inner">
<div class="block">
<img src="http://habrastorage.org/files/50f/7b2/1cc/50f7b21ccabd4b20bc0369f228138b5b.jpg" alt=""/>
</div>
</div>
</div>
.parent {
width: 100%;
height: 100%;
display: table;
position: absolute;
top: 0;
left: 0;
> .inner {
display: table-cell;
text-align: center;
vertical-align: middle;
}
}
.block {
display: inline-block;
img {
display: block;
border: none;
}
}
Чтобы добавить скролл в данный пример, придётся добавить в конструкцию ещё один элемент.
Пример: jsfiddle.net/serdidg/fk5nqh52/3/.
Вариант 4. Псевдо-элемент.
Данный вариант лишён всех проблем, перечисленных у предыдущих способов, а так же решает первоначально поставленные задачи. Суть состоит в том, чтобы у родителя задать стили псевдо-элементу before, а именно 100% высоту, выравнивание по центру и модель строчного блока. Так же само и у блока ставится модель строчного блока, выравнивание по центру. Чтобы блок не «падал» под псевдо-элемент, когда размеры первого больше чем родителя, указываем родителю white-space: nowrap и font-size: 0, после чего у блока отменяем эти стили следующими — white-space: normal. В данном примере font-size: 0 нужен для того, чтобы убрать образовавшийся пробел между родителем и блоком в связи с форматированием кода. Пробел можно убрать и иными способами, но лучшим считается просто его не допускать.
Пример: jsfiddle.net/serdidg/nfqg9rza/1/.
Примеры без нулевого font-size: jsfiddle.net/serdidg/nfqg9rza/29/, jsfiddle.net/serdidg/nfqg9rza/39/.
<div class="parent">
<div class="block">
<img src="http://habrastorage.org/files/50f/7b2/1cc/50f7b21ccabd4b20bc0369f228138b5b.jpg" alt=""/>
</div>
</div>
.parent {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: auto;
white-space: nowrap;
text-align: center;
font-size: 0;
&:before {
height: 100%;
display: inline-block;
vertical-align: middle;
content: '';
}
}
.block {
display: inline-block;
white-space: normal;
vertical-align: middle;
text-align: left;
img {
display: block;
border: none;
}
}
Вариант 5. Кнопка.
Пользователь azproduction предложил вариант, где блок обрамляется в тег button. Кнопка имеет свойство центрировать всё, что находится у неё внутри, а именно элементы строчной и блочно-строчной (inline-block) модели. На практике использовать не рекомендую.
Пример: jsfiddle.net/serdidg/0bn8wg38/.
<button class="parent">
<div class="block">
<img src="http://habrastorage.org/files/50f/7b2/1cc/50f7b21ccabd4b20bc0369f228138b5b.jpg" alt=""/>
</div>
</button>
.parent {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
overflow: auto;
background: none;
border: none;
outline: none;
}
.block {
display: inline-block;
img {
display: block;;
border: none;
}
}
Бонус
Используя идею 4-го варианта, можно задавать внешние отступы для блока, и при этом последний будет адекватно отображаться в окружении скроллбаров.
Пример: jsfiddle.net/serdidg/nfqg9rza/2/.
Так же можно выравнивать картинку по центру, и в случае если картинка больше родителя, масштабировать её по размеру родителя. Пример: jsfiddle.net/serdidg/nfqg9rza/3/.