Многоколоночный макет, выходящий за пределы блока
23.02.2007 веб-стандарты, верстка, alistapart, css
by Alan Pearce
Нам всем хорошо известна проблема, возникающая при создании многоколоночного макета, в котором колонки должны быть одинаковой высоты. Прочитать подробно об этом можно в разных местах. Потому не будем углубляться в суть данной проблемы.
Проект, над которым в недавнем прошлом мне пришлось работать, требовал создания тянущегося макета, с двумя колонками одинаковой высоты, каждая со своим фоновым цветом. Как обычно бывает в подобных ситуациях, невозможно точно сказать, которая из колонок будет длиннее. Я просмотрел статью Faux Columns, однако требовался именно тянущийся макет. Далее я просмотрел статью One True Layout, однако, похоже, она была с ошибками, содержала избыточный код разметки и требовала слишком много хаков под мои требования. Я даже подумал использовать JavaScript для создания колонок одинаковой высоты, но это было бы неправильно. Отчаявшись, я чуть было не применил таблицы!
Но нет, нашлось все же решение. Мне потребовалось просто поразмыслить о том, что находится за пределами блока. Так что же за блоком есть? Границы. Если бы мне удалось, используя свойство float сместить колоночный div
за границы основного контента, я смог бы имитировать колонки одинаковой высоты, независимо от того, которая из них длиннее.
Если все это звучит уже знакомо, то только лишь потому, что подобный метод был представлен Douglas Livingstone и расширен Holly и John Bergevin с статье Position Is Everything. Если следовать данной теории, метод, представленный здесь использует более “чистую”, с небольшой степенью вложенности разметку, включая тянущиеся двухколоночные варианты макетов и в целом однозначно лучше, описанного в статье One-True-Layout. Вот как это все выглядит.
HTML код:
<div id="container"> <div id="content">This is<br />some content</div> <div id="rail">This is the rail</div> </div>
Код CSS:
#container{ background-color:#0ff; overflow:hidden; width:750px; } #content{ background-color:#0ff; width:600px; border-right:150px solid #f00; /* The width and color of the rail */ margin-right:-150px; /* Hat tip to Ryan Brill */ float:left; } #rail{ background-color:#f00; width:150px; float:left; }
Я создал правую границу в div
’е content такой же ширины и цвета, как и блок rail, затем сместил этот блок rail свойством float
влево, Правая граница margin-right:-150px
блока content позволила блоку rail сместиться влево на освобожденное место. Если блок content будет длиннее блока rail, вместе с ним вырастет и граница, т.о. блок rail тоже вытянется. Я установил фон блока container и content одинаковыми для того, чтобы если блок rail является более высоким, то блок container “вырастет” вместе с ним. Для того, чтобы блок rail выровнялся по левому краю необходимо внести небольшие изменения только в таблицу стилей CSS в зависимости от того, что длиннее, либо content, либо rail.
Можете просмотреть данный пример в действии либо взглянуть на «тянущуюся» версию макета; попробуйте поменять размер шрифта, и посмотрите, как будет меняться макет.
Три колонки: три цвета
Трехколоночный макет требует немного другого подхода, а именно граница применяется непосредственно к блоку container. (Я мог бы сделать это и с двухколоночным макетом, однако я не думал об этом на тот момент).
HTML код:
<div id="container"> <div id="center">CENTER<br />COLUMN CENTER</div> <div id="leftRail">LEFT RAIL</div> <div id="rightRail">RIGHT RAIL</div> </div>
Код CSS:
#container{ background-color:#0ff; float:left; width:500px; border-left:150px solid #0f0; /* The width and color of the left rail */ border-right:200px solid #f00; /* The width and color of the right rail */ } #leftRail{ float:left; width:150px; margin-left:-150px; position:relative; } #center{ float:left; width:500px; margin-right:-500px; } #rightRail{ float:right; width:200px; margin-right:-200px; position:relative; }
Пример в действии.
Центральная колонка имеет границу -500px. Это позволяет левому блоку rail располагаться с левого края центральной колонки. Отрицательные границы вставляют боковые колонки на свои места. Существует несколько способов добиться этого, но данный кажется наиболее оптимальным решением при переходе позже к «тянущемуся» макету
Для блока container я установил свойство float: left
вместо overflow:hidden
. Сделано это потому, что колоночные блоки расположены за пределами блока container, обтекая его границы, поэтому они просто исчезнут с использование свойства overflow: в IE боковые колонки не исчезают, однако в Firefox’е корректно пропадают.
Для колонок не нужно устанавливать цвет фона. Поскольку цвета устанавливаются для блока container, который «растет» вместе с самой длиной колонкой, появляется иллюзия равной высоты всех колонок.
«Тянущийся» макет
После того, как мы разобрались с фиксированным макетом, я решил создать «тянущийся» макет, используя тот же самый метод. Боковые колонки должны по-прежнему иметь фиксированную ширину, поскольку большинство браузеров не поймет просто процентное задание ширины границ, но мы можем создать «резиновую» центральную колонку.
Код CSS:
#container{ background-color:#0ff; overflow:hidden; margin:0 100px; padding-right:150px; /* The width of the rail */ } * html #container{ height:1%; /* So IE plays nice */ } #content{ background-color:#0ff; width:100%; border-right:150px solid #f00; margin-right:-150px; float:left; } #rail{ background-color:#f00; width:150px; float:left; margin-right:-150px; }
Пример в действии.
Размета точно такая же как и при двух-колоночном макете фиксированной ширины, за исключением блока content. Таблица стилей CSS претерпела незначительные изменения, однако обратим внимание на несколько важных различий: блок container не имеет фиксированной ширины и добавлена высота в 1%, чтобы IE правильно обработал свойством overflow:hidden
(Я использовал хак *html, однако можно было бы использовать conditional comments для включения стилей понятных только IE)
Я также добавил границы по бокам, как опцию. Отступ справа padding-right
создает дополнительное пространство для блока и блок content заполняет все что осталось, поскольку имеет ширину 100%, если бы не было отступа, то боковой блок ушел бы за пределы блока container и исчез бы. Наконец, ширина блока content переключается на 100% и добавляется граница к боковой колонке margin-right:-150px
Также как и в двух-колоночном макете фиксированной ширины, версия left-rail требует внесения небольших изменений в CSS. Я добавил просто header и footer и теперь можно просмотреть исходник и увидеть пример в действии.
Трех-колоночный «тянущийся» макет
Трех-колоночные макеты, с колонками равной высоты назывались по всякому: “Holy Grail”, “One True Layout”, “pain in the @$$”… Предложенный ниже метод является относительно несложным, использует правильный порядок в разметке, не требует использования фоновых изображений и похоже, не имеет багов.
The HTML:
<div id="container"> <div id="center">Center Column Content</div> <div id="leftRail">Left<br /> Sidebar</div> <div id="rightRail">Right Sidebar</div> </div>
The CSS:
body{ margin:0 100px; padding:0 200px 0 150px; } #container{ background-color:#0ff; float:left; width:100%; border-left:150px solid #0f0; border-right:200px solid #f00; margin-left:-150px; margin-right:-200px; display:inline; /* So IE plays nice */ } #leftRail{ float:left; width:150px; margin-left:-150px; position:relative; } #center{ float:left; width:100%; margin-right:-100%; } #rightRail{ float:right; width:200px; margin-right:-200px; position:relative; }
В body
на этот раз используются граница и отступ. Граница «вдавливает» макет между краями экрана, а отступ является шириной боковых колонок. Оставшееся место — это ширина, до которой может увеличиваться блок container: 100% ширины браузера минус граница и отступ. В блоке container я установил границы и бордюры одинаковой ширины но с разными знаками. Это накладывает границы поверх отступов в body
, расставляя все на свои места. Затем мы можем размещать любые блоки.
Следующий пример показывает вложенный «тянущийся» двух-колоночный макет с header’ом и footer’ом. Посмотрите в код, и поймете как просто наполнить и стилизовать этот макет. Вложенный «тянущийся» двух-колоночный макет использует технику с границей в блоке container. Это позволяет мне добавить левый бордюр в 2px в блоке content и правый бордюр в 2px в блоке rail и перекрыть их, создав разделитель полной высоты между ними. Этот разделитель вытянется вместе с боковыми колонками независимо от того, какая из них длиннее.
Еще раз обращаю внимание, что этот метод работает только с колонками фиксированной ширины, поскольку только Opera понимает ширину границ в %-х. Блок rail может и не иметь фонового рисунка, однако это может измениться в свойстве border-image property in CSS3
Итак, мы имеем много-колоночные макеты с колонками равной высоты, фиксированные и тянущиеся центральные блоки, чистая разметка CSS. И все, что нужно было для этого сделать, так это немного поразмыслить за пределами блока.
Пример в действии.
Источник alistapart.com
Перевод — Дмитрий Папуца
Оригинал статьи
Translated with the permission of A List Apart Magazine and the author[s].