Кросс-браузерное решение для резинового макета с одинаковой высотой колонок и стопроцентной высотой
Недавно понадобилось сверстать резиновый трёхколоночный макет с высотой 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;
}
}
Открыл в IE 5 и 5.5 не работает.
“…EasyClearing портит разметку в IE 5.01. По счастью, это легко лечится путём добавления float: left контейнеру #container:”
olga:
“…Почему, если вставлять в левый блок ссылки так, чтоб при наведеннии на них они подчеркивались, этот левый блок уплывает вправо?…”
http://www.positioniseverything.net/easyclearing.html
http://www.positioniseverything.net/explorer/guillotine.html
Я не сильно расстроился Сам по себе EasyClearing действительно лечится путем добавления
float: left
, возможно, я где-то что-то испортил. А с тех пор, как умерла Win 2000, IE 5.x у меня нет. Да и IE 6 тоже.IE 5.5 не понравилось
left: 200px;
поправил таким образом:
voice-family: "\"}\"";
voice-family: inherit;
left: 200px;
}
IE 6.028 никаких горизонтальных полос прокрутки нет. В целом очень даже кросс-браузерный макет .
Здорово, спасибо! Добавлю в статью.
Здравствуйте! В IE6 появляется горизонтальная полоса прокрутки при наполнении колонок контентом. Подскажите пожалуста как исправить?
Спасибо за статью