Резиновый трехколоночный макет с правосторонними сайдбарами
Кросс-браузерный семантически корректный резиновый макет с тремя колонками (сайдбары справа)
Очередной раз попав не туда, куда надо из Google, я натолкнулся на статью "Трехколоночный макет на CSS с одинаковой высотой колонок". Да, трехколоночные макеты (да еще и резиновые!) очень популярны, я смотрю
Но, несмотря на популярность таких макетов, многие верстальщики почему-то не хотят учиться и городят целый огород на div'ах.
В указанной статье приводится следующая разметка (я убрал пустые строки и изменил форматирование):
<div id="wrapper">
<div id="header"></div>
<div id="container">
<div id="sub-container">
<div id="wrpr">
<div id="content">
<div id="text"></div>
</div>
<div id="left"></div>
</div>
</div>
<div id="right"></div>
</div>
<div id="footer"></div>
</div>
</body>
Что мы видим: пример, как верстать не надо. Может быть, сказано слишком резко, но на мой взгляд, суп из div'ов (с глубиной вложенности 6) ничем не лучше табличной вёрстки (табличная вёрстка будет даже компактнее). Кроме того, большая часть этого супа не несёт семантической нагрузки. И вообще, при верстке нужно руководствоваться принципом KISS, но это моё сугубо личное мнение.
Попробуем переделать.
Начнём с разметки:
<div id="header"></div>
<div id="container">
<div id="content" class="column"></div>
<div id="col1" class="column"></div>
<div id="col2" class="column"></div>
</div>
<div id="footer"></div>
</body>
Как я уже отмечал в предыдущих статьях, названиям классов и атрибутам id нужно давать семантически значимые имена, но в качестве тестового примера пойдут и такие.
Простая разметка — простые стили:
margin: 0;
padding: 0;
border: 0;
width: 100%;
}
html { /* Для IE6 и IE7 */
overflow: auto;
}
body {
min-width: 50em; /* #container.paddingRight + #col1.offsetWidth + #col2.offsetWidth */
}
#container {
overflow: hidden;
padding-right: 25em; /* #col1.offsetWidth + #col2.offsetWidth */
position: relative;
}
/*\*/
* html #container {
height: 1%;
}
/**/
.column {
position: relative;
float: left;
padding-bottom: 1002em !important;
margin-bottom: -1000em !important;
overflow: hidden;
}
#content {
width: 100%;
}
#col1 {
width: 10em;
margin-right: -100%;
}
#col2 {
width: 15em;
margin-right: -100%;
margin-left: 10em; /* #col1.offsetWidth */
}
#footer {
clear: both;
}
Для краткости презентационные стили (aka расцветка) опущены.
Тестовая страница доступна здесь. Кстати, разметка получилась даже проще, чем здесь
Но макет не был бы так хорош, если бы не позволял с лёгкостью добавлять отступы, границы и бордюры. В статье "IE7/8 и общий случай двухколоночной резиновой вёрстки" я показывал, как получаются формулы для вычисления значений границ и иже с ними (вспоминаем про эквивалентность преобразований), поэтому здесь приведу только конечный результат:
| Элемент | Свойство | Формула |
|---|---|---|
| body | min-width | (#container.offsetWidth - #container.width) + (#content.offsetWidth - #content.width) + #col1.offsetWidth + #col2.offsetWidth |
| #container | padding-right | (#content.offsetWidth - #content.width) + #col1.offsetWidth + #col2.offsetWidth |
| #content | margin-left | =#container.paddingLeft |
| #col1 | margin-left | =#content.marginRight |
| #col2 | margin-left | #col1.offsetWidth + #col2.желаемый_marginLeft |
| #col1, #col2 | margin-right | -100% |
В #container.paddingRight входит желаемый #col2.marginRight (но у Opera есть некоторые проблемы с его отображением).
Из-за того, что все колонки имеют равную высоту, отобразить border-bottom у них не представилось возможным.
Для IE8 добавляются следующие изменения:
#col1.marginLeftустанавливается в сумму горизонтальных отступов, границ и бордюров элемента#content;#col2.marginLeftувеличивается на величину#col1.marginLeft.
Тестовая страница для экспериментов находится здесь.
margin: 0;
padding: 0;
border: 0;
font: 12px Verdana, Tahoma, Arial, Helvetica, sans-serif;
width: 100%;
}
html {
overflow: auto;
}
body {
min-width: 81em; /* (38.5 + 0.5 + 2*1 + 2*1) + (2*1 + 2*1 + 0.5) + (10 + 2*1 + 2*1) + (15 + 0.5 + 2*1 + 2*1) = 43 + 4.5 + 14 + 19.5 = 57 + 24 */
}
#container {
overflow: hidden;
padding-right: 38.5em; /* (2*1 + 2*1 + 0.5) + (10 + 2*1 + 2*1) + (15 + 0.5 + 2*1 + 2*1) + желаемый margin-right для #col2 (0.5em) */
position: relative;
padding-left: .5em;
padding-top: .5em;
padding-bottom: .5em;
margin: 1em;
border: 1em solid black;
}
/*\*/
* html #container {
height: 1%;
}
/**/
.column {
position: relative;
float: left;
padding-bottom: 1002em !important; /* Фактически, padding-bottom = 2em */
margin-bottom: -1000em !important;
overflow: hidden;
}
#content {
width: 100%;
border: 1em solid green;
padding: 1em;
margin-right: .5em;
}
#col1 {
width: 10em;
margin-right: -100%;
padding: 1em;
border: 1em solid red;
}
*:first-child/**/+html #col1 {
margin-left: 4.5em; /* #col1.paddingLeft + #col1.paddingRight + #col1.borderLeft + #col1.borderRight + #col2.желаемый_marginLeft */
}
#col2 {
width: 15em;
margin-right: -100%;
margin-left: 14.5em; /* #col1.paddingLeft + #col1.paddingRight + #col1.borderLeft + #col1.borderRight + #col2.желаемый_marginLeft + #col1.width */
padding: 1em;
border: 1em solid blue;
}
*:first-child/**/+html #col2 {
margin-left: 19em; /* #col2.marginLeft + #col1.marginLeft */
}
#footer {
clear: both;
}
Мар
2008
Комментарии к статье «Резиновый трехколоночный макет с правосторонними сайдбарами» (17) »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Резиновый трехколоночный макет с правосторонними сайдбарами»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.


Дмитрий, по-моему, Вы где-то ошиблись… Я сохранил страницу себе на диск, добавил
overflow: hidden.sidebarи всё отлично смотрится в Опере (по крайней мере, в 9.2x – 9.50 у меня нет).Тестовая страница: http://blog.sjinks.pro/test/imhoblog/test.html
[...] переходим к трём колонкам: [...]
У меня как раз стоит Opera 9.5. И она, к сожалению, в данном случае overflow: hidden вообще не воспринимает, т.е. получается, что трабл только в Opera 9.5.
Дмитрий, тут такая проблема… Валидатор нашел 186 ошибок (!) и проблему с распознаванием UTF-8. Я бы всё же, наверное, попытался бы исправить ошибки, и только потом переходить к CSS. Валидатор жалуется на неправильно закрытые тэги.
Дмитрий, по ходу я прав – проблема в кривой разметке.
http://blog.sjinks.pro/test/imhoblog/test.html
Я убрал этот блок (из Подписки), и всё стало красиво:
<center>
<br>
<p>
<!-- <a rel="nofollow" href="http://feeds.feedburner.com/imhoblog" rel="nofollow"><img src="http://imhoblog.ru/img/RSSicon32x32.png" height="32" width="32" style="border:0" alt="feedburner"/></a> -->
<a rel="nofollow" href="http://feeds.feedburner.com/imhoblog" rel="nofollow"><img src="http://imhoblog.ru/img/ratatfeed.gif" height="128" width="128" style="border:0" alt="Подпишись на RSS!" /></a>
<br>
<a rel="nofollow" href="http://feeds.feedburner.com/imhoblog" rel="nofollow"><img src="http://feeds.feedburner.com/~fc/imhoblog?bg=99CCFF&fg=444444&anim=0" height="26" width="88" style="border:0" alt="feedburner" /></a></p>
<br>
<a rel="nofollow" href='http://toodoo.ru/blog/19819/click' rel="nofollow">
<img src='http://c.toodoo.ru/blog/19819/images/88x15w.gif' border='0' alt='количество читателей онлайн и всего' /></a>
</a>
<br>
<!-- rss2email -->
<a "nofollow" href="http://www.rss2email.ru?rss=http://feeds.feedburner.com/imhoblog" title="Получать RSS-ленту на почту" rel="nofollow"><img src="http://www.rss2email.ru/counter/typeA/23728_3.gif" border="0"></a>
<!-- /rss2email -->
<br>
<a rel="nofollow" href="http://lenta.yandex.ru/settings.xml?name=feed&url=http://feeds.feedburner.com/imhoblog" rel="nofollow"><img src="http://lenta.yandex.ru/i/addfeed.gif" border="0" alt="Читать в Яндекс.Ленте" /></a>
<br>
<a rel="nofollow" href="http://fusion.google.com/add?source=atgs&feedurl=http%3A//feeds.feedburner.com/imhoblog" rel="nofollow"><img src="http://buttons.googlesyndication.com/fusion/add.gif" border="0" alt="Add to Google"></a>
<br><br>
<a href="http://imhoblog.ru/2008/05/09/chto-takoe-rss-chast-1-osnovy/" target="_blank" rel="nofollow">Что означает значок RSS?</a>
<br>
</center>
<noindex>
Для сравнения старая версия: http://blog.sjinks.pro/test/imhoblog/test2.html
Мораль: ошибки в разметке надо исправлять
Ошибка с незакрытым тегом, слава Богу, не моя. Я подобных ошибок стараюсь не допускать.
Удивительные вещи – после исправления этого тега футер возвращается на место, но отступ все равно остается, теперь уже под футером. Методом исключений определил, что отступ появляется сразу же после выполнения скрипта todoo-виджета (блок «Наши ИМХО люди»). Вот это побороть я уже не в силах.
Это из-за того, что WordPress по умолчанию оформляет все виджеты как списки, а этот TooDoo лепит внутрь элемента
ulтаблицу. Фикс – править исходный код плагина или попытаться поиграть с параметрами виджета$beforeи$after(если они есть).