Кросс-браузерный резиновый трёхколоночный макет в высоту окна
Кросс-браузерное решение для резинового макета с одинаковой высотой колонок и стопроцентной высотой
Недавно понадобилось сверстать резиновый трёхколоночный макет с высотой 100% и колонками одинаковой высоты. К моему удивлению, это оказалось не очень простым делом: вместо планируемого получаса это заняло намного больше времени.
Требования к макету:
- кросс-браузерность (куда без неё);
- минимальная высота: 100% (полное окно, независимо от высоты контента);
- минимум кода;
- все три колонки должны быть одинаковой высоты;
- никакого JavaScript.
Минимум кода означает минимум разметки:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Three Column Liquid Layout</title>
</head>
<body>
<div id="header">Header</div>
<div id="container">
<div id="content" class="column">
<p>Sed eleifend, sapien vel mollis euismod, sem velit semper ante...</p>
</div>
<div id="left" class="column">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis sollicitudin dolor nec nunc iaculis tincidunt...</p>
</div>
<div id="right" class="column">
<p>Phasellus sollicitudin. Fusce ut tellus. Vivamus dapibus. Cras eu elit. Vestibulum ante ipsum primis in faucibus orci luctus et...</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
So far so good
, как любит говорить один мой коллега. Теперь переходим к разметке.
Начнём с общих определений:
background: #800000;
}
html, body {
margin: 0;
padding: 0;
border: 0;
}
body {
font: 14px/120% Verdana, Tahoma, Arial, Helvetica, sans-serif;
width: 90%;
margin: 0 auto;
}
Теперь переходим к 100% высоте. Помним, что Konqueror/KHTML имеет свою точку зрения по поводу того, кто задаёт скроллинг; также не забываем про IE6, который не понимает min-height
overflow: auto;
}
html:not(:nth-child(1)) {
overflow: visible; /* KHTML сам нарисует скроллинг, не будем ему мешать */
}
html, body {
margin: 0;
padding: 0;
border: 0;
width: 100%;
height: 100%;
}
#container {
height: auto !important;
height: 100%; /* для IE6 */
min-height: 100%;
}
* html #container { overflow: visible; }
Для IE6 мы должны задать overflow: visible, в противном случае контент будет нещадно обрезаться.
Задаем заголовок и подвал:
height: 3em;
background: red;
color: #FFF;
position: absolute;
top: 0;
width: 100%;
z-index: 1000;
left: 0;
}
.column {
padding-top: 3em !important; /* компенсация высоты заголовка */
}
#footer {
height: 3em;
color: #FFF;
background: green;
position: relative;
z-index: 1000;
margin-top: -3em;
width: 100%;
}
Заголовок позиционируем абсолютно, так как контейнер #container имеет как минимум стопроцентную высоту: задать высоту 100%-3em будет проблематично. Поэтому, считая, что высота заголовка нам известна (а так обычно всегда), мы просто помещаем заголовок "на территорию" контейнера, а высота заголовка будет компенсирована верхним отступом у колонок. Даже если нам придётся задать фоновый рисунок у #container, мы можем компенсировать высоту заголовка путём использования background-position.
Аналогично (только хуже
) с футером: его нужно поднять вверх на всю его высоту (отсюда относительное позиционирование и z-index) — как и в случае с заголовком, для поддержания стопроцентной высоты необходимо, чтобы он располагался "на территории" контейнера.
Теперь переходим к трём колонкам:
padding-left: 220px;
padding-right: 200px;
overflow: hidden;
float: left; /* IE 5.01 */
float/**/: none;
background: lime;
position: relative;
}
#left, #right, #content {
float: left;
position: relative;
padding-bottom: 1000em !important;
margin-bottom: -997em !important; /* компенсация высоты футера */
}
#left {
width: 220px;
background: url(images/tile-2.jpg) repeat;
margin-left: -100%;
right: 220px;
}
* html #left { /* У IE6 всё не как у людей */
left: 200px;
}
#right {
width: 200px;
background: url(images/tile-3.jpg) repeat;
margin-right: -100%;
}
#content {
width: 100%;
background: url(images/tile-1.jpg) repeat;
}
Теперь идут хаки. По слухам, в IE/Mac вышеприведённая техника для создания колонок одинаковой высоты не работает. Вернее, он работает, но страницу разносит по высоте (добавляется невидимый padding). Мне-то всё равно, но так как исправить просто (в смысле, сделать колонки разной высоты), то почему бы и нет:
float: left;
position: relative;
padding-bottom: 3em; /* компенсация высоты футера */
}
/* Прячем от IE/Mac \*/
#left, #right, #content {
padding-bottom: 1000em !important;
margin-bottom: -997em !important;
}
/**/
Переходим к Опере. Старые версии (7.0-7.2) не обрезают колонки по высоте. На помощь приходит EasyClearing:
content: 'EasyClearing';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
#container { display: inline-block; }
/*\*/
#container { display: block; }
/**/
Но, как это обычно бывает в жизни, исправил одну ошибку — вылезла другая: EasyClearing портит разметку в IE 5.01. По счастью, это легко лечится путём добавления float: left контейнеру #container:
float: left; /* IE 5.01 */
float/**/: none;
}
Тем не менее, мы исправили не все глюки в Опере. Для Opera 8, у которой есть свои глюки в обработке overflow: hidden, нам придётся убрать margin-bottom/padding-bottom с самих колонок и применить их элементу внутри колонок. Либо так:
#left, #right, #content {
margin-bottom: 0 !important;
padding-bottom: 3em !important; /* Компенсация высоты футера */
}
#left:before, #right:before, #content:before {
content: 'EasyClearing';
display: block;
background: inherit;
padding-top: 1000em !important;
margin-bottom: -1000em !important;
height: 0;
}
}
Июн
2008
Комментарии к статье «Кросс-браузерный резиновый трёхколоночный макет в высоту окна» (36) »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Кросс-браузерный резиновый трёхколоночный макет в высоту окна»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.


БОЛЬШОЕ СПАСИБО!Хорошие комментарии и хороший макет.
Макет действительно работает. Но, вот, решил я найти универсальный макет (для одной простенькой цмски), в котором можно было бы убрать, к примеру одну из боковых колонок и средняя растянулась бы на её место.
))
В данном шаблоне сделать такой фокус простым убиранием div’а с боковой колонкой не прокатил…
Как быть? Нужно ещё и в стилях что-то править? Но, они довольно тонко заточены всякими отступами да выступами… Даже страшно трогать
А ещё эти боковые полосы – они действительно нужны?
За шаблон действительно автору отдельное СПАСИБО.
Но, есть в нем одна проблема.
Если где-то в контенте установить якорь (ссылку вида
<a>…), и перейти по этому якорюwww.mysite/index.html#1, то весь контент, что над якорем заползает под header (короче исчезает).Виноваты в этом стили, с помощью которых как раз и получаются колонки во всю высоту:
margin-bottom: -997em !important; /* компенсация высоты футера */
Вопрос к автору, каким еще способом в данном шаблоне лучше растянуть колонки на всю высоту?
Что касается дела «Исчезающей колонки в IE6″ (или уползающей колонки), методом экспериментов было выяснено, что это все связано с использованием псевдоклассов hover и active с тегом a и стилем background (хоть и не сложная смесь, но осел ее осилить не смог). Если hover и active и стиль background применять к li, то IE6 их просто игнорирует и левая колонка не убегает.
Я в своё время искал решение, но не нашел — всё, что у меня получалось, это заставить код работать в одном IE, после чего всё напрочь ломалось в другом.
slavapth
Я тоже столкнулся с похожей проблемой – в FF. В др. браузерах (IE и Opera) такого не встречал. Долго рыскал в инете в поисках ответа. И решил воспользоваться методом «тыка». Ошибка в…
Если убрать в стиле #container – overflow: hidden
Но тогда появляется другая ошибка…ищу ответ дальше…
Спасибо за решение. Сам больше года пользовался другимм – много плюсов, но были и минусы.
Вопрос, сосбственно, такой: можно ли как-то сделать так, чтобы футер не наезжал на бэкграунд колонок? У меня в футере прозрачный png, поэтому получается оч коряво.
Ух как! Поигрался 5 минут, скрестил свое решение и ваше и получилось вообще чудесно. Кода раза в три меньше и удобнее
Работает в последних лисе, опере и хроме, а также в ие 8, 7 и 6.
Если есть желание выложить тут, могу скинуть на почту автору.
Кирилл, если не трудно, вышлите, пожалуйста, на
vladimir at extrememember dot com, я его опубликую. Ну и ссылку на Ваш сайтОтправил
здравствуйте
очень интересно узнать, что же за решение пришло от Кирилла…
==============================
никак не могу найти способ, как сделать «резиновой» по высоте среднюю строку таблицы в 3 строки при фиксированной высоте верхней и нижней…
спасибо большое автору этого блога, что готов делиться своими вариантами реализации не самых простых целей!
=====================================================
если кому-то нужно решение описанного мной выше вопроса,
я его нашла здесь:
http://krylov.org.ua/?p=682
для меня, как для начинающего «вебера»,- самое простое решение без лишних телодвижений ))
А мне вот нужно сделать полупрозрачные колонки (с непрозрачным текстом) одинаковой высоты, и подвал, приклеенный к самому низу. В FF работает вот это:
#left:before, #right:before, #content:before {content: 'EasyClearing';
display: block;
background: inherit;
background-image:url("040_FFFFFF.png");
padding-top: 1000em !important;
margin-bottom: -1000em !important;
height: 0;
}
040_FFFFFF.png – это белый полупрозрачный пиксель. В бэкграунд самого div’а ставить его бесполезно – будет двойное наложение из-за inherit. А если inherit убрать, то будет неполное заполнение колонок.
Проблема в том, что не работает в IE. Вообще. Колонки прозрачные, пикселя нет, как-то по-другому он отрабатывает этот вот :before.