Горизонтальное и вертикальное центрирование контейнера

Вертикальное выравнивание всегда было проблемным местом в CSS, так как свойство vertical-align действует только на inline-элементы (состоящие из одной строки) и не работает с блочными элементами. Однако вертикальное выравнивание можно применить к ячейкам таблицы, таким образом мы можем использовать это в наших интересах в браузерах, которые поддерживают свойство display:table;, например в Mozilla и Opera.

Мы также можем приручить IE5-IE7 с помощью условных комментариев, написав для него отдельные правила вертикального центрирования.

Я сделал пример страницы, содержимое которой центрируется по вертикали и горизонтали.

Для начала я покажу что нужно сделать для Мозиллы. Вот листинг основной таблицы стилей:

* {margin:0;padding:0} /* mac hide \*/ html,body{height:100%;width:100%;} /* end hide */ body { background-color: #cccccc; text-align:center; min-height:468px;/* для правильных браузеров*/ min-width:552px;/* для правильных браузеров*/ } #outer{ height:100%; width:100%; display:table; vertical-align:middle; } #container { text-align: center; position:relative; vertical-align:middle; display:table-cell; height: 468px; } #inner { width: 552px; background:red; height: 468px; text-align: center; margin:0 auto; border:1px solid #000; }

Наш HTML код будет выглядеть так:

<body> <div id="outer"> <div id="container"> <div id="inner"> <h1>Отцентрированно по вертикали и горизонтали</h1> </div> </div> </div> </body>

Большинство из вышеупомянутого должно быть Вам знакомо, но нас интересует сейчас свойство display:table; в контейнере #outer. Именно оно говорит браузеру что надо отобразить блочный элемент с характеристиками, присущими таблицам. Это позволит нам использовать свойство vertical-align:center;. Далее мы обьявляем контейнер #container ячейкой таблицы (display:table-cell) и он отцентрируется вертикально относительно #outer.

Внутренний элемент #inner мы центрируем горизонтально с помощью свойства margin:0 auto;. Теперь Mozilla и Opera, отображают все так, как мы задумали. Конечно плохо что мы нуждаемся в дополнительных обертках, но это - самый безопасный способ решения задачи вертикального центрирования. Описанный мной метод всегда оставляет контент во вьюпорте, в отличие от других методов.

IE не понимает свойства display:table; и игнорирует его. Для того чтобы заставить его центрировать страницу по вертикали добавим на страницу код:

<!--[if IE ]> <style type="text/css"> #container{top:50%} #inner{top:-50%;position:relative;} </style> <![endif]-->

Вертикальное центрирование элементов неизвестной ширины и высоты

Два вышеописанных метода настолько хороши, что немного модифицировав наш код, мы получим решение для вертикального центрирования элементов с неизвестной шириной и высотой. Я не буду описывать модификации, а сразу приведу пример. Появились вопросы? Пишите комментарии!

Поделись с друзьями:
Комментарии

А если высота известна, то можно ещё проще делать :)

body,html {height: 100%;}
#example {position: absolute; top: 50%; left: 0; height: 200px; margin-top: -100px;}

А Вы уверены что контент не вылезет из вьюпорта если страница развернута не на весь экран? Мне вот кажется, что он уедет за пределы видимой области, хотя можно поробовать поставить свойство min-height и хак для IE 6 ;-)

Ну естественно вылезет, если высота окна будет меньше 200 пикселей :) А вообще, пример оттестирован, работает на нескольких сайтах.

html, body{
	padding: 0; margin: 0;
	width:100%; height:100%;
}
#container{
	position: absolute;
	top: 50%; left: 50%;
	width: 400px; height: 300px;
	margin-left: -200px; margin-top: -150px;
}

Делаем так и не паримся. И ничего никуда не вылезет.
Если нужна динамическая высота - паримся.

Для динамической высоты не надо париться, я все уже расписал!

А как быть если внутри блока inner нужно вставить еще один блок, допустим inner2. И в inner2 вставить inner3, и все их центрировать по вертикали?

Народ! Эти примеры очень сильно глючат в злосчастном IE7. Выходил из положения элементарно с помощью одной таблицы:

<table width="960" style="height:100%" align="center">
<tr><td><div></div></td></tr>
<tr><td height="720">
_Содержимое_
</td></tr>
<tr><td><div></div></td></tr>
</table>

Проверял в FF, Opera, IE 6-7 везде работало. По моему и кода меньше. Разве не так?

Павел, не позорьтесь. Добавьте DOCTYPE и увидите что ваш пример не работает в IE7. Надо переходить на верстку по стандартам!

Статья замечательная, большое спасибо!
Действительно работает почти (об этом чуть позже) во всех браузерах даже тогда, когда размер окна браузера меньше размеров центрируемого DIVа, что исключает использование метода, предложенного Никитой.
Теперь о "почти". В IE 8 без включения режима совместимости не работает, т.к. читается условный комментарий: <!--[if IE ]>... . Поэтому считаю, что его надо было бы уточнить: <!--[if lt IE 8]>... А в остальном, прекрасная маркиза, все хорошо :)

Попробовал вместо формы вставить картинку, но она по горизонтали не отценрировалась! А слабо с картинкой проделать тоже самое?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML xmlns="http://www.w3.org/1999/xhtml">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<TITLE> Example </TITLE>
<STYLE type="text/css">
body,html {width: 100%; height: 100%; padding: 0; margin: 0;}
</STYLE>
</HEAD>
<BODY>
<DIV style="background: url(/img/intro.jpg) center center no-repeat; border: 1px solid #0000ff"></DIV>
<SCRIPT language="JavaScript">
<!--
var div = document.getElementsByTagName("DIV");
div[0].style.height=document.body.clientHeight+"px";
//-->
</SCRIPT>
</BODY>
</HTML>

Т.о. DIV выводится на всю доступную площадь броузера, а его фон центрируется.
Проверено в Opera,FF,Safari,Chrome,IE7 - везде одинаково. :)

HTML:

<html>
<body>
<div id="tocenter">Бла бла бла</div>
</body>
</html>

CSS:

body {margin:0; padding:0; border-collapse:collapse;}
#tocenter {position:absolute; width:552px; height:468px; margin:-234px 0 0 -276px; left:50%; top:50%;}

Проблема в опере: не происходит динамического центрирования по вертикали.