Владимир Корнилов
Владимир Корнилов —

Вертикальное центрирование содержимого в 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 а тот, в свою очередь, может брать размеры от любого родителя.

В итоге код будет выглядеть так:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <title>Центрируем контент по вертикали</title>
  6. <style type="text/css">
  7. html, body {height:100%; margin:0; padding:0;}
  8. #table_div {
  9. display:table; height:100%; width:100%; }
  10. #valgin_div {
  11. display:table-cell; height:100%; width:100%; vertical-align:middle; }
  12. #content {
  13. padding:20px; text-align:center; background:#CCC; position:relative }
  14. </style>
  15. </head>
  16. <body>
  17. <div id="table_div">
  18. <div id="valgin_div">
  19. <div id="content">
  20. Я по-центру!
  21. </div>
  22. </div>
  23. </div>
  24. </body>
  25. </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]-->

Вот, в общем-то и всё.

Ссылки

Страницу-пример можно посмотреть тут и еще можете посмотреть на сайт где это всё использовалось тут.