Эта статья из A List Apart послужила большим источником вдохновения для меня. После «тест-драйва» указанного в ней метода, я решил применить отрицательные внешние полоски (negative margins) с точностью до наоборот.
Я думаю, что главное преимущество этой техники состоит в том, что используется меньше несемантических элементов и на один плавающий блок меньше. Это также, лечит маленькие проблемы, не перечисленные в оригинальном демонстрационном примере:
- Ссылки в правой колонке не работают в Opera 6
- Возникают проблемы с прорисовкой фона в MSIE
- В разметке отсутствует структурный хак, который не позволяет очистить место после левой колонки в Netscape Navigator 6
Мой новый метод не использует:
- CSS хаки
- Структурные хаки для очистки плавающих элементов
- IE/Win условные комментарии
- Загадочные CSS правила
- Длинные таблицы стилей
- Надписи «Best viewed in...» (см. список поддерживаемых браузеров)
Эта страница показывает основную технику, но я создал «более сложный» проект, основанный на этом решении: это - вызов CSS.
Логика
Изображение ниже показывает, как работает макет. Я сдвигаю блок #container влево вместо правой стороны (противоположность тому что сделано в статье ALA), и самая важная часть - то, что я не делаю плавающим блок #sidebar.
Разметка
<body>
<div id="outer_wrapper">
<div id="wrapper">
<div id="header">
<h2>Header</h2>
<p>...</p>
</div><!-- /header -->
<div id="container">
<div id="left">
<h1>Left</h1>
<ol>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ol>
</div><!-- /left -->
<div id="main">
<h1>Main</h1>
<p>...</p>
</div><!-- /main -->
<!-- This is for NN6 -->
<div class="clearing"> </div>
</div><!-- /container -->
<div id="sidebar">
<h1>Sidebar</h1>
<p>...</p>
</div><!-- /sidebar -->
<!-- This is for NN4 -->
<div class="clearing"> </div>
<div id="footer">
<h2>Footer</h2>
<p>...</p>
</div><!-- /footer -->
</div><!-- /wrapper -->
</div><!-- /outer_wrapper --&;gt;
</body>
CSS файлы
Я привожу здесь только стили относящиеся к разметке. Названия картинок и пути упрощены для наглядности.
Таблица стилей для современных браузеров (подключаем через @important):
#outer_wrapper {
/* т.к. min-width не поддерживается IE, мы будем использовать скрипт написанный PVII */
min-width:740px;
/* Правило для решения бага прорисовки фона в IE, но т.к. оно создает промежуток
под футером, мы добавим такое же правило в блок #footer */
width:100%;
/* Техника ложных колонок (faux-column), левая колонка */
background:#fff url(left.gif) repeat-y left
}
#wrapper {
/* Техника ложных колонок (faux-column), правая колонка */
background:url(right.gif) repeat-y right
}
#header {
border:1px solid #b0b0b0;
background:#b0b0b0;
/* Задаем "определение позиции" для элемента и устраняем
peek-a-boo баг в IE (v6 sp2) */
width:100%;
/* Предыдущее правило создает горизонтальную прокрутку в IE,
избавимся от нее */
margin:0 -1px
}
#container {
float:left;
width:100%;
/* IE удваивает внешние полоски (margins) у плавающих элементов,
позаботимся об этой проблеме */
display:inline;
/* Тут мы расходимся во мнениях с Ryan Brill (автором статьи в ALA) */
margin-left:-200px
}
#left {
float:left;
width:150px;
/* IE удваивает внешние полоски (margins) у плавающих элементов,
позаботимся об этой проблеме */
display:inline;
margin-left:200px
}
#main {
/* ширина левой колонки #left (150px) + отрицательное поле (negative margin)
у блока #container (200px) */
margin-left:350px
}
/* Примечание: если блок #sidebar будет короче чем блок #main,
тогда можете удалить это правило */
#sidebar {
/* Для сохранения контента блока #sidebar справа от блока #main,
если контента в #main меньше */
padding-left:100%;
/* Возвращаем блок #sidebar на место, который был вытеснен
из вьюпорта из-за отступа */
margin-left:-200px
}
#sidebar p {
/* Удостоверимся что IE (v6 sp2) отображает элемент (та же проблема что и
с блоком #header, но решение другое) */
position:relative
}
#footer {
/* См. блок #outer_wrapper */
width:100%;
/* Для очистки #container */
clear:both;
border-top:1px solid #b0b0b0;
border-bottom:1px solid #b0b0b0;
background:#b0b0b0}
/* Этот класс применяется к 2-м структурным хакам в разметке. Первый
"бессмысленный" элемент используется для очистки блока #left в NN6,
а последний для очистки #container в NN4 */
.clearing {height:0;clear:both}
Вы заметили, что несколько правил используются только для MSIE/Win, поэтому я советую вам убрать их из основной таблицы стилей CSS и включить в документ с помощью условных комментариев IE.
Стили для старых браузеров 4 версий:
Т.к. мы решили сделать поддержку NN4, необходимо указывать корневые относительные пути к картинкам в таблицах стилей.
#outer_wrapper {
/* Техника ложных колонок (faux-column), левая колонка */
background-image:url(/корневой относительный путь/outer_wrapper.gif);
background-repeat:repeat-y;
border:1px solid #b0b0b0
}
#header,#footer {
/* Заставим блоки расшириться до 100% ширины */
width:150%;
/* Данный трюк позволит закрасить блок целиком, а не только область под контентом */
background:#b0b0b0 url(/корневой относительный путь/clear.gif)
}
#container {
/* Удостоверимся что NN4 не отрисует фон в этом элементе */
background-image:none;
float:left;
width:auto;
/* Внешняя и внутрянняя полоски нужны чтобы оставить место для блока #sidebar */
margin-right:160px;
padding-right:160px
}
#left {
float:left;
width:140px
}
#main {
/* В NN4, очень важно корректно определить background для позиционированных
элементов. Если NN4 не найдет картинку, то разметка разрушится */
background-image:url(/корневой относительный путь/clear.gif);
/* это правило сохранит оболочку внутри вьюпорта */
margin:0
}
#sidebar {
/* Определяем фоновый цвет для блока #sidebar; я также удостоверился чтобы он
не наследовал фоновые картинки */
background:#ccc none;
margin:0;
padding:10px 0;
/* В современных браузерах этот элемент не плавающий, а вот в NN4 он должен
быть плавающим */
float:right;
width:180px
}
/* Этот класс используется для структурных хаков в разметке */
.clearing {clear:both}
Современные браузеры проигнорируют эти стили, т.к. я использую специальный скрипт:
if (!document.getElementById)
document.write('<link rel="stylesheet" type="text/css" href="/css/v4.css">');
Список поддерживаемых браузеров
Windows:
- NN 4.7*
- FireFox 0.8
- FireFox 1.0.7
- Opera 6.05
- Opera 7.23
- Opera 8.5
- Netscape 6.2
- Netscape 7.1
- Netscape 8.0
- IE 5.00
- IE 5.01
- IE 5.5
- IE 6.0
- Mozilla 1.4.1
- Mozilla 1.7.5
Mac OS:
- NN 4.7*
- FireFox 1.0
- Mozilla 1.7.3
- Camino 0.8.2
- IE5.0 (OS9)
- IE5.2 (OSX)
- Safari 1.2.4
Mandrake:
- Mozilla 1.7.5
- Konqueror 3.3
Red Hat 9:
- Mozilla 1.21
- Konqueror 3.1-12
- Netscape 7.2
- Opera 8 Beta
Ubuntu 5.10 breezy badger:
- Epiphany 1.8.12
- Firefox 1.0.7
- Mozilla 1.7.12
- Opera 8.5
* - макет жидкий, но колонки разные по высоте. В версии вызов CSS, колонки одинаковой высоты.
Если у Вас установлен другой браузер и макет выглядит нормально, пожалуйста дайте мне знать и я включу его в этот список.
@ 29 Ноября 2007 в 11:12
Спасибо что так подробно расписал, я давно хотел начать верстать дивами, но думал что это сложно, теперь же буду на этом примере тренироваться.
@ 30 Ноября 2007 в 16:19
Да не за что ;-) Собственно статью написали ребята из TJKDesign, а я только перевел ее. Если вдруг появятся вопросы, пиши на форум, чем смогу помогу.
@ 07 Февраля 2008 в 18:07
Крайне, полезная статья по резиновой верстке и написана очень понятно! Продолжайте в том же духе!;)
@ 28 Февраля 2008 в 04:52
Подскажите а как сделать чтобы правая колонка скрывалась в некоторых разделах, т.е. чтобы на главной было 3 колонки а на другой странице 2 колонки
@ 29 Февраля 2008 в 16:36
Если Вы оставите подключенным исходный файл стилей, то под ним включите еще один файл стилей например 2col.css:
#container {float:none; margin-left:0;}
#left {float:left; width:150px; margin-left:0;
#sidebar {display:none; padding-left:0; margin-left:0;}
Я не проверял, но навскидку должно работать. Правда поисковикам может не понравиться что вы скрываете колонку свойством display:none;. На этот случай могу Вам порекомендовать сделать еще один шаблон на основе 3 колоночного, удалить из него код колонки #sidebar и в файле стилей изменить стили для блоков так, как я написал выше. Если не выйдет, пишите, что нибудь придумаем ;-)