Кросс-браузерное решение для резинового макета с одинаковой высотой колонок и стопроцентной высотой

Недавно понадобилось сверстать резиновый трёхколоночный макет с высотой 100% и колонками одинаковой высоты. К моему удивлению, это оказалось не очень простым делом: вместо планируемого получаса это заняло намного больше времени.

Требования к макету:

  • кросс-браузерность (куда без неё);
  • минимальная высота: 100% (полное окно, независимо от высоты контента);
  • минимум кода;
  • все три колонки должны быть одинаковой высоты;
  • никакого JavaScript.

Минимум кода означает минимум разметки:

[-]
View Code HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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, как любит говорить один мой коллега. Теперь переходим к разметке.

Начнём с общих определений:

[-]
View Code CSS
html {
    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

[-]
View Code CSS
html {
    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, в противном случае контент будет нещадно обрезаться.

Задаем заголовок и подвал:

[-]
View Code CSS
#header {
    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) — как и в случае с заголовком, для поддержания стопроцентной высоты необходимо, чтобы он располагался "на территории" контейнера.

Теперь переходим к трём колонкам:

[-]
View Code CSS
#container {
    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). Мне-то всё равно, но так как исправить просто (в смысле, сделать колонки разной высоты), то почему бы и нет:

[-]
View Code CSS
#left, #right, #content {
    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:

[-]
View Code CSS
#container:after {
    content: 'EasyClearing';
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

#container { display: inline-block; }
/*\*/
#container { display: block; }
/**/

Но, как это обычно бывает в жизни, исправил одну ошибку — вылезла другая: EasyClearing портит разметку в IE 5.01. По счастью, это легко лечится путём добавления float: left контейнеру #container:

[-]
View Code CSS
#container {
    float: left; /* IE 5.01 */
    float/**/: none;
}

Тем не менее, мы исправили не все глюки в Опере. Для Opera 8, у которой есть свои глюки в обработке overflow: hidden, нам придётся убрать margin-bottom/padding-bottom с самих колонок и применить их элементу внутри колонок. Либо так:

[-]
View Code CSS
@media all and (min-width: 0px) {
    #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;
    }
}

Тестовая страница.

Добавить в закладки

Связанные записи

29
Июнь
2008

Комментарии к статье «Кросс-браузерный резиновый трёхколоночный макет в высоту окна» (16)  »

  1. Serg says:

    Открыл в 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

    • Vladimir says:

      Открыл в IE 5 и 5.5 не работает.

      Я не сильно расстроился :-) Сам по себе EasyClearing действительно лечится путем добавления float: left, возможно, я где-то что-то испортил. А с тех пор, как умерла Win 2000, IE 5.x у меня нет. Да и IE 6 тоже.

  2. Serg says:

    IE 5.5 не понравилось left: 200px;
    поправил таким образом:

    [-]
    View Code CSS
    * html #left {
            voice-family: "\"}\"";
            voice-family: inherit;
            left: 200px;
    }

    IE 6.028 никаких горизонтальных полос прокрутки нет. В целом очень даже кросс-браузерный макет :) .

  3. Крис says:

    Здравствуйте! В IE6 появляется горизонтальная полоса прокрутки при наполнении колонок контентом. Подскажите пожалуста как исправить?

  4. n_string says:

    Спасибо за статью

Подписаться на RSS-ленту комментариев к статье «Кросс-браузерный резиновый трёхколоночный макет в высоту окна» Trackback URL: http://blog.sjinks.org.ua/css/209-cross-browser-liquid-three-column-layout-full-height/trackback/

Оставить комментарий к записи «Кросс-браузерный резиновый трёхколоночный макет в высоту окна»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя