Блочная верстка в 3 колонки (fluid layout)
Эта статья из 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.11.2007
Постоянная ссылка (Permalink)
Спасибо что так подробно расписал, я давно хотел начать верстать дивами, но думал что это сложно, теперь же буду на этом примере тренироваться.
Mike Khasaya
30.11.2007
Постоянная ссылка (Permalink)
Да не за что ;-) Собственно статью написали ребята из TJKDesign, а я только перевел ее. Если вдруг появятся вопросы, пиши на форум, чем смогу помогу.
Николай
28.02.2008
Постоянная ссылка (Permalink)
Подскажите а как сделать чтобы правая колонка скрывалась в некоторых разделах, т.е. чтобы на главной было 3 колонки а на другой странице 2 колонки
Mike Khasaya
29.02.2008
Постоянная ссылка (Permalink)
Если Вы оставите подключенным исходный файл стилей, то под ним включите еще один файл стилей например 2col.css:
<code class="css">#container {float:none; margin-left:0;}
#left {float:left; width:150px; margin-left:0;
#sidebar {display:none; padding-left:0; margin-left:0;}
</code>
Я не проверял, но навскидку должно работать. Правда поисковикам может не понравиться что вы скрываете колонку свойством <kbd>display:none;</kbd>. На этот случай могу Вам порекомендовать сделать еще один шаблон на основе 3 колоночного, удалить из него код колонки <kbd>#sidebar</kbd> и в файле стилей изменить стили для блоков так, как я написал выше. Если не выйдет, пишите, что нибудь придумаем ;-)
Андрей
15.05.2008
Постоянная ссылка (Permalink)
А в IE8 такая верстка уже не прокатывает...
Макс
16.05.2008
Постоянная ссылка (Permalink)
Ну IE8 вроде еще не вышел, а как выйдет, думаю, можно будет и под него подогнать))
Михаил
02.10.2008
Постоянная ссылка (Permalink)
Если использую даный способ, в нутри .main при использовании clear, контент уходит ниже .left
Как бороться.... усердно пытаюся найти
Денис
28.01.2009
Постоянная ссылка (Permalink)
Огромное спосибо за статью ))
Дмитрий
21.03.2009
Постоянная ссылка (Permalink)
Как - то сложно все. А в чем преимущество данного способа перед стандартным, когда блоки left, content и sidebar помещаются в container, при этом sidebar и left - плавающие, а content-у задаются левые и правые margin, равные ширине крайних колонок?
Shoorick
07.02.2010
Постоянная ссылка (Permalink)
Google Chrome 4.0.249.43 под Linux (Mandriva One 2010.0) — работает.
Морфин
22.05.2010
Постоянная ссылка (Permalink)
Под Windows аналогично. В Mozilla Firefox 3.6.3 тоже работает отлично
Верстак
02.08.2010
Постоянная ссылка (Permalink)
В листинге таблицы стилей в некоторых местах пропущены [;], закрывающие правило
(например, width:180px)
Решение с padding-left:100% для sidebar нельзя назвать изящным; попробуйте назначить этому селектору background красного цвета и увидите, что я имею ввиду.
MarSoft
12.11.2010
Постоянная ссылка (Permalink)
В браузере Chromium 8.0.552.28 под Gentoo Linux всё отображается отлично. То же самое должно быть применимо и к подавляющему большинству других linux-дистрибутивов.