Вертикальное центрирование содержимого в DIVкатегории: expression , html css
Довольно распространенная проблема, когда нужно разместить содержимое блока по вертикали по середине, а использовать таблицы (в которых работает vertical-align:middle) совсем не хочется. Если высота блока с содержимым заранее известна, то проблем никаких нет: достаточно этому блоку задать атрибуты position:relative; top:50% и задать верхний отрицательный margin на половину его высоты. Можно точно также через position:absolute, зависит от ситуации. Но принцип всегда один: опускаем на 50% родителя и поднимаем на 50% собственной высоты.
Но когда высота блока неизвестна и там может быть что угодно, такой способ не подходит. Что в таком случае делать?
Всё просто: есть атрибут display:table-cell, который наследует свойства табличных ячеек (как положительные, так и отрицательные, но об этом позже).
Т.к. он наследует таблицы, в нем работает свойство vertical-align:middle. Для того чтобы задать такому блоку размеры в процентах (например height:100%, что нам понадобиться) его необходимо было поместить в блок с атрибутом display:table с заданным размером, т.к. display:table-cell может брать относительные размеры только от display:table а тот, в свою очередь, может брать размеры от любого родителя.
В итоге код будет выглядеть так:
- <!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=UTF-8" />
- <title>Центрируем контент по вертикали</title>
- <style type="text/css">
- html, body {height:100%; margin:0; padding:0;}
- #table_div {
- display:table; height:100%; width:100%; }
- #valgin_div {
- display:table-cell; height:100%; width:100%; vertical-align:middle; }
- #content {
- padding:20px; text-align:center; background:#CCC; position:relative }
- </style>
- </head>
- <body>
- <div id="table_div">
- <div id="valgin_div">
- <div id="content">
- Я по-центру!
- </div>
- </div>
- </div>
- </body>
- </html>
Теперь об особенностях display:table-cel:
Он наследует от таблиц всё, включая задание размеров: блок перестаёт занимать всё пространство и формируется по объему содержимого, padding считается внутрь блок (не добавляется к width), а margin – наружу (добавляется к width)
Если вам нужно вставить в этот блок div с динамической (относительной) шириной и overflow – у вас ничего не выйдет. Как и в таблицах, блок не сможет рассчитать размер «выхода за пределы», скролл не появится и родителя растянет по содержимому. Это можно по-хитрому обойти, но об этом в другой раз.
Но не всё так просто, как хотелось бы. IE ниже 8й версии не понимает этот атрибут. На помощь к нам прийдут условные комментарии, behavior и expression. В условном комментарии [if lte IE 7] задаём родителю подходящий атрибут display (скорее всего block) а к блоку с содержимым применяем метод из самого начала: опускаем на 50% родителя и поднимаем на 50% собственной высоты. Вот тут нам и пригодится behavior и expression – для поднятия блока содержимого на 50% собственной высоты, заранее её не зная. Само выражение будет выглядеть так:
behavior:expression(function(t){var h = t.offsetHeight;if (t.h != h) {t.h = h;t.style.marginTop = -(h / 2 );}}(this));
Т.е. под стилями для всех браузеров (или в отдельном CSS) пишем следующее:
<!--[if lte IE 7]> <style type="text/css"> #valgin {display:block;} #content {position:relative; top:50%; behavior:expression(function(t){var h = t.offsetHeight;if (t.h != h) {t.h = h;t.style.marginTop = -(h / 2 );}}(this)); } </style> <![endif]-->
Вот, в общем-то и всё.
Ссылки
Страницу-пример можно посмотреть тут и еще можете посмотреть на сайт где это всё использовалось тут.