В чистом CSS рабочим ответом однажды будет просто использовать "display:table-cell"
. К сожалению, это не работает в современных браузерах А-класса, так что для всего этого вы могли бы также использовать таблицу, если вы все равно хотите добиться того же результата. По крайней мере, вы будете уверены, что это работает достаточно далеко в прошлом.
Честно говоря, просто используйте стол, если это проще. Это не повредит.
Если семантика и доступность элемента таблицы действительно имеют для вас значение, существует рабочий черновик для того, чтобы сделать вашу таблицу несемантической:
http://www.w3.org/TR/wai-aria/#presentation
Я думаю, что для этого требуется специальный DTD помимо XHTML 1.1, который бы просто вызвал все споры text/html
против application/xml
, поэтому давайте не будем идти туда.
Итак, к вашей нерешенной проблеме CSS ...
Вертикально выровнять два элемента по их центру: это можно сделать несколькими различными способами, с помощью некоторой тупой хакерской CSS.
Если вы можете вписаться в следующие ограничения, то есть относительно простой способ:
- Высота двух элементов фиксирована.
- Фиксированная высота контейнера.
- Элементы будут достаточно узкими, чтобы не перекрываться (или могут быть установлены на фиксированную ширину).
Тогда вы можете использовать абсолютное позиционирование с отрицательными полями:
.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }
Но в большинстве ситуаций это бессмысленно ... Если вы уже знаете высоту элементов, то вы можете просто использовать поплавки и добавить достаточное поле для их размещения.
Вот еще один метод, использующий текстовую базовую линию для вертикального выравнивания двух столбцов в виде встроенных блоков. Недостатком здесь является то, что вам нужно установить фиксированную ширину для столбцов, чтобы заполнить ширину от левого края. Поскольку нам нужно сохранить элементы привязанными к базовой строке текста, мы не можем просто использовать float: right для второго столбца. (Вместо этого мы должны сделать первый столбец достаточно широким, чтобы перевернуть его.)
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; }
.valign { display: inline-block; vertical-align: middle; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { padding: 8px; width: 384px; }
.group-buttons { padding: 8px; width: 84px; text-align: right; }
</style>
<!--[if lt IE 8]>
<style type="text/css">
.valign { display: inline; margin-top: -2px; padding-top: 1px; }
</style>
<![endif]-->
</head>
<body>
<div class="group-header">
<div class="valign">
<div class="group-title">This is my title.</div>
</div><!-- avoid whitespace between these! --><div class="valign">
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
</div>
<div class="group-content">
<p>And it works perfectly, but mind the hacks.</p>
</div>
</body>
</html>
HTML: Мы добавляем обертки .valign вокруг каждого столбца. (Дайте им более «семантическое» имя, если это сделает вас счастливее.) Их нужно хранить без пробелов между ними, иначе текстовые пробелы будут их раздвигать. (Я знаю, что это отстой, но это то, что вы получаете за то, что вы «чисты» с разметкой и отделяете ее от слоя представления ... Ха!)
CSS: Мы используем vertical-align:middle
, чтобы выровнять блоки по текстовой базовой линии элемента заголовка группы. Различные высоты каждого блока будут оставаться вертикально центрированными и выталкивать высоту их контейнера. Ширина элементов должна быть рассчитана, чтобы соответствовать ширине. Здесь их 400 и 100 минус горизонтальное заполнение.
В IE исправлено: Internet Explorer отображает только встроенный блок для встроенных элементов (например, span, а не div). Но если мы передадим div hasLayout, а затем отобразим его как встроенный, он будет вести себя как встроенный блок. Корректировка поля должна исправить зазор в 1 пиксель сверху (попробуйте добавить цвета фона в заголовок .group, чтобы увидеть).