<rmcreative>

RSS

Фиксированная середина, плавающие колонки

5 декабря 2009

Вчера понадобилось получить довольно нестандартную трёхколоночную разметку: с фиксированной средней колонкой (например, шириной в 500px) и двумя боковыми, занимающими всё остальное пространство.

http://rmcreative.ru/playground/fluid-fixed-fluid/target.png

Оказалось, что решение довольно интересное.

Для начала разметим страничку:

<!doctype html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <title>Fluid-Fixed-Fluid layout</title>
    <meta charset="utf-8" />
</head>
<body>
    <div class="fluid-left-wrapper">
        <div class="fluid-left">
            левая колонка
        </div>
    </div>
    <div class="fixed">
        средняя колонка
    </div>
    <div class="fluid-right-wrapper">
        <div class="fluid-right">
            правая колонка
        </div>
    </div>
</body>
</html>

Две обёртки понадобятся нам для позиционирования боковых колонок.

Выставляем всем трём блокам float: left, задаём обёрткам ширину в 50%.

Теперь правую и левую обёртки надо сместить соответственно влево и вправо на

ширины центральной колонки. Получим такую картину:

http://rmcreative.ru/playground/fluid-fixed-fluid/step1.png

Далее даём внутреннему левому блоку отступ на ½ ширины центральной колонки справа. Правому — слева.

http://rmcreative.ru/playground/fluid-fixed-fluid/step2.png

На этом мы могли бы и закончить, если бы не наш любимый IE, который упорно считает, что 50% + 50% = 100,1%.

Специально для него выставляем ширину обёрток в 49.999%;.

Работающий пример

Комментарии RSS

  1. №2036
    rommanc
    rommanc 06 дек. 2009 г., 0:09:52

    спасибо, все гениальное просто)

    я тоже как раз недавно пытался сделать что-то подобное но получилось как-то убого, при увеличении размера шрифта (ctrl and +) правая колонка съезжала под лейаут, то есть располагалась под левой(

    p.s. хе, увидел доктайп и начал у себя переименовывать дивы в сектион и эсайды, а им то оказывается надо дислей блоковый указывать, что в-общем странно, такими они ведь по-умолчанию должны как бы!

    еще раз спасибо!

  2. №2037
    Sam
    Sam 06 дек. 2009 г., 13:02:24

    rommanc

    Для IE придётся немного пошаманить.

    А вообще новые теги HTML5 на рабочих проектах использовать пока ещё рано — явные проблемы с FF2.

  3. №2038
    Search Bot
    Search Bot 06 дек. 2009 г., 13:16:00

    Отличное простое решение. И работает отлично: блоки не дергаются при изменении размера. Во всяком случае в Хроме.

    Да, ИЕ считать проценты не умеет )

  4. №2039
    Игорь
    Игорь 06 дек. 2009 г., 14:29:37

    А я дизайнер и ничего в этом не понимаю :(

  5. №2088
    agat
    agat 11 дек. 2009 г., 10:47:44

    float: left; clear: right; для блоков и не нужно шаманить с шириной в процентах для IE.

  6. №2090
    Sam
    Sam 11 дек. 2009 г., 12:17:12

    А пример можно?

  7. №2094
    Николай
    Николай 14 дек. 2009 г., 10:31:27

    float: left; clear: right; не решит проблемы с шириной в IE, просто блоки не будут спрыгивать. Работать будет 100% :)

  8. №2102
    Never Lex
    Never Lex 18 дек. 2009 г., 14:44:30

    Спасибо! Очень интересный вариант макета.

  9. №2141
    vovans
    vovans 07 янв. 2010 г., 17:29:02

    У меня две колонки справа и основной блок слева. Как сделать так, чтоюы этот с новной блок был "резиновым", но не уменьшался более чем на 750px?

  10. №2147
    ололо
    ололо 08 янв. 2010 г., 14:25:04

    Какое счастье, что есть таблицы и не надо вот так извращаться

  11. №2149
    Sam
    Sam 08 янв. 2010 г., 21:24:05

    vovans

    Использовать min-width и хаки для тех, кто его не поддерживает.

  12. №2696
    Дмитрий
    Дмитрий 07 июля 2010 г., 13:01:20

    Вопрос автору (надеюсь на помощь). Столкнулся с проблемой: архитектура сайта такая - Основная часть занимает 800 px (левый сайдбар - 200px, и основная часть 600px). А вот по бокам оставлены колонки, ширина которых не проставлена. То есть задумано так, что 800 px будет по центру, а размеры боковых частей будут формироваться автоматически в зависимости от разрешения экрана (то есть width не проставлен вообще). В мозиле и опере всё работает без проблем. А вот IE это судя по всему не понравилось, так как крайние колонки растягиваются не до конца, вследствие чего растягивается основная часть (не 800 px получается , а больше). Сайт: _www.vel-les.ru. Какие значения выставить для этих 2 колонок по бокам? Спасибо.

  13. №2699
    Sam
    Sam 07 июля 2010 г., 13:25:11

    У вас там табличная разметка и проблемы с разметкой. Пройдитесь валидатором для начала и поправьте ошибки.

  14. №4109
    Иван
    Иван 14 марта 2011 г., 22:26:22

    Использовал Ваш метод. Вроде всё было хорошо. Но есть одно "Но..." В mozille правый блок как бы накладывается сверху на контент. И, к примеру, ссылки которые размещены в контенте в правой стороне - не работают...

  15. №8141
    Евгений Шев
    Евгений Шев 07 июля 2013 г., 14:51:14

    Гораздо проще (и бОльшим числом браузеров поддерживается) задать центрирование фиксированного блока через

    margin: 0 auto;

    а контейнеры по бокам сделать так (правый, например):

    position: absolute;
    top: 0;
    left: 50%;
    right: 0;
    margin-left: 250px;
  16. №8430
    Vo
    Vo 05 окт. 2013 г., 17:29:35

    Отлично! Подскажите теперь, пожалуйста, как сделать эти колонки равными по высоте.

  17. №11371
    Владимир
    Владимир 22 дек. 2018 г., 1:08:11
    <!DOCTYPE html>
    <html>
        <head>
            <title>3 колонки</title>
            <meta charset="UTF-8">
        </head>
        <body style="margin: 0;">
            <div class="full_main_block" style="width: 100%; white-space:nowrap; height: 100px;">
                <div class="left_main_block" style="background-color: #6c6052; float:left; height: 100px;">&nbsp</div>
                <div class="center_main_block" style="background-color: #сссссс; background-image: url(/../img/head_fon_e.jpg); width: 1000px; float:left; height: 100px;">Фиксированная колонка</div>
                <div class="right_main_block" style="background-color: #fcfbc4; float:left; height: 100px;">&nbsp</div>
            </div>
            <div class="full_main_block" style="width: 100%; white-space:nowrap; height: 600px;">
                <div class="left_main_block" style="float:left; height: 600px;">&nbsp</div>
                <div class="center_main_block" style="background-color: #cccccc; width: 1000px; float:left; height: 600px;">&nbsp</div>
                <div class="right_main_block" style="float:left; height: 600px;">&nbsp</div>
            </div>
            <script>
                // Функция - добавляет обработчик события addEvent(window, 'resize', watch, true);
                var addEvent = function (obj, type, callback, eventReturn) {
                    if (obj == null || typeof obj === 'undefined') {
                        return;
                    }
                    if (obj.addEventListener) {
                        obj.addEventListener(type, callback, eventReturn ? true : false);
                    } else if (obj.attachEvent) {
                        obj.attachEvent("on" + type, callback);
                    } else
                        obj["on" + type] = callback;
                };
                // Функция - обработчик события addEvent(window, 'resize', watch, true);
                var watch = function (evt)
                {
                    var dimensions = {
                        height: (evt.srcElement || evt.currentTarget).innerHeight,
                        width: (evt.srcElement || evt.currentTarget).innerWidth
                    };
                };
    
                f_h_b = document.getElementsByClassName("full_main_block");
                l_h_b = document.getElementsByClassName("left_main_block");
                c_h_b = document.getElementsByClassName("center_main_block");
                r_h_b = document.getElementsByClassName("right_main_block");
                // функция непосредственно корректирует размеры блоков на странице
                // в момент загрузки страницы и в момент изменениц размера окна браузера
                function setSizeMainHeaderContainer() {
                    for (var i = 0; i < f_h_b.length; i++) {
                        width = (f_h_b[i].clientWidth - c_h_b[i].clientWidth) / 2;
                        if (width > 0) {
                            l_h_b[i].style.width = width + "px";
                            r_h_b[i].style.width = (width - 1) + "px";
                        } else {
                            l_h_b[i].style.width = 0;
                            r_h_b[i].style.width = 0;
                        }
                    }
                }
                addEvent(window, 'resize', watch, true);
                window.onresize = function () {
                    setSizeMainHeaderContainer();
                };
                // Запускает фуекцию setSizeMainHeaderContainer при начале загрузки страницы
                // В это время еще не загружены картинки и другие даные.
                document.addEventListener("DOMContentLoaded", setSizeMainHeaderContainer);
            </script>
        </body>
    </html>
    
  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.