Создание web страниц. Верстка в две колонки с разделителем.

Владимир | | CSS, HTML.

В интернете можно найти массу примеров верстки страницы в две колонки. Но у большинства из них есть недостаток: нельзя установить разделитель между колонками нужной длины.

Проблема заключается в следующем. Нам нужно сверстать страницу с двумя колонками, например, меню (menu) и раздел с текстом (textBlock), между которыми нужно поставить разделитель (обычную линию или повторяющийся по вертикали рисунок). При этом размер колонок заранее неизвестен, т.е. меню может быть короче текстового блока, а может и наоборот. Вот тут и возникает проблема. Если использовать свойство border (или background-image) в более коротком блоке, то разделитель получится оборванным.

Я хочу показать прием, который позволит обойти эту проблему. Идея заключается в том, что нужно поместить наше меню и текстовый блок во внешний блок (container). При этом container всегда должен быть больше чем оба наших блока. На первый взгляд тут не должно возникнуть никаких затруднений, но вспомним, что для размещения блоков рядом друг с другом для одного из них мы должны задать свойство float, а оно «вырывает» блок из потока документа. Например, правило float:left задано для меню. Тогда, если меню длиннее, чем текстовый блок мы получим такую картинку:

Плавающий блок выходит за границы контейнера

При такой разметке задавать в контейнере границы и фоновые изображения нет никакого смысла.

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

Первый способ. Добавляем в контейнер еще один блок (bottom) и устанавливаем для него в таблице стилей свойство clear:both. Этот блок будет всегда размещен под любым предыдущим блоком, не зависимо от того, задано свойство float или нет. После этого контейнер растянется так чтобы охватывать блок bottom. Теперь можно создать картинку и использовать ее в качестве фона в контейнере. Размещение блоков показано на рисунке 2:

Контейнер растянут до размеров большего блока

Ниже приведен текст файлов с разметкой и стилями. Вы также можете скачать пример (вместе с картинкой, которая используется в качестве разделителя).

test2col.html

<body>
<div id="header">
<p>Заголовок страницы</p>
</div> <!-- Завершение header -->
<div id="container">
	<div id="textBlock">
	<p>Тут находится основное содержимое страницы (текст, рисунки, таблицы и т.д.).</p>
	<p>Длина этого блока может быть меньше или больше длины menu.</p>
	<p>Для демонстрации работы разметки мы сделали этот блок длиннее чем menu, т.к. в нашей таблице стилей для этого блока используется директива float и он может выходить за пределы блока container.</p>
	<p>Дело в том, что директива float:right "вырывает" блок из потока документа и указывает остальным блокам обтекать этот блок слева. Т.к. у нас и textBlock, и menu входят в блок container, то высота блока container будет равняться высоте menu, потому что для него не установлена директива float.</p>
	<p>Что бы обойти это ограничение мы добавили в контейнет дополнительный блок bottom и в таблице стилей установили для него директиву clear: both</p>
	</div> <!-- Завершение textBlock -->
	<div id="menu">
		<ul>
		<li>Раздел 1</li>
		<li>Раздел 2</li>
		<li>Раздел 3</li>
		<li>Раздел 4</li>
		<li>Раздел 5</li>
		</ul>
	</div> <!-- Завершение menu -->
	<div id="bottom">
	</div>
</div> <!-- Завершение container -->
<div id="footer">
<p>Автор: Стаценко Владимир</p>
</div> <!-- Завершение -->
</body>

test2col.css

#header {
	border: solid 1px #0f0;
}

#header p {
	text-align: center;
	font-size: 140%;
}

#container {
	border: dotted 1px #f00;
	background-image: url(’delimeter.gif’);
	background-repeat: repeat-y;
}

#textBlock {
	width: 70%;
	float: right;
	border: dotted 1px #00f;
}

#textBlock p {
}

#menu {
	width: 200px;
	border: dotted 1px #ff0;
}

#menu ul {
	list-style: none;
}

#menu ul li { } #bottom { clear: both; } #footer { }

Примечание: размер блока bottom будет зависеть от его содержимого. Если вы в него ничего не вставите, то его высота будет равна нулю и блок будет невидимым.

Второй способ немного сложнее. Идея в целом та же, но здесь мы применим трехколоночную верстку. Третья (центральная) колонка будет использоваться исключительно для создания разделителя. На мой взгляд, этот вариант удобнее для «текущей» верстки, потому что позволяет сохранять соотношение между шириной колонок при различных разрешениях экрана.

Делается это следующим образом. Для обоих блоков мы задаем свойство float (например, для меню float: right, а для текста — float: left) и указываем их ширину (допустим, 30% и 78%). Обратите внимание, мы оставили «зазор» в 2% для нашего разделителя (центральной колонки), назовем ее line.

Теперь нам нужно обеспечить, чтобы высота разделителя равнялась высоте большего блока. Как это сделать, мы уже знаем. Добавляем в блок line блок bottom. Т.к. блок bottom будет находится под меню и текстовым блоком, то line растянется на нужную нам высоту. А дальше задаем для блока line границу или фоновое изображение.

Исходный код для реализации такой разметки может выглядеть таким образом. (Примечание: в этом примере меню находится справа, а текстовый блок слева. Чтобы поменять их местами просто измените параметры свойств float в строках 15 и 24 таблицы стилей на противоположные. И, конечно, изменить параметры свойства margin в строке 37).

Разделитель в третьей колонке

test3col.html

<body>
<div id="header">
<p>Заголовок страницы</p>
</div> <!-- Завершение header -->
<div id="container">
	<div id="textBlock">
	<p>Тут находится основное содержимое страницы (текст, рисунки, таблицы и т.д.).</p>
	<p>Длина этого блока может быть меньше или больше длины menu.</p>
	<p>Для демонстрации работы разметки мы сделали этот блок длиннее чем menu, т.к. в нашей таблице стилей директива float используется для этого блока и он может выходить за пределы блока container.</p>
	<p>Дело в том, что директива float:left "вырывает" блок из потока документа и указывает остальным блокам обтекать этот блок справа. Т.к. у нас и textBlock, и menu входят в блок container, то высота блока container будет равняться высоте menu, потому что для него не установлен директива float.</p>
	</div> <!-- Завершение textBlock -->
	<div id="menu">
		<ul>
		<li>Раздел 1</li>
		<li>Раздел 2</li>
		<li>Раздел 3</li>
		<li>Раздел 4</li>
		<li>Раздел 5</li>
		</ul>
	</div> <!-- Завершение menu -->
	<div id="line">
		<div id="bottom"></div>
	</div>
</div> <!-- Завершение container -->
<div id="footer">
<p>Автор: Стаценко Владимир</p>
</div> <!-- Завершение -->
</body>

test3col.css

#header {
	border: solid 1px #0f0;
}

#header p {
	text-align: center;
	font-size: 140%;
}

#container {
	border: dotted 1px #f00;
}

#textBlock {
	float: left;
	width: 65%;
	border: dotted 1px #00f;
}

#textBlock p {
}

#menu {
	float: right;
	width: 29%;
	border: dotted 1px #ff0;
}

#menu ul {
	list-style: none;
}

#menu ul li {
}

#line {
	margin: 0 29% 0 70%;
	border-left: solid 3px #000;
}

#bottom {
	clear: both;
}

#footer {
}

Вы также можете скачать архив с этими файлами.

Постовой

Портал работы в Одессе

  • а почему на рисунках блоки со скругленными углами 🙂 ?

  • а почему на рисунках блоки со скругленными углами 🙂 ?

  • Так прикольнее 🙂 .
    К тому же, фотошопу без разницы 🙂 .

  • Так прикольнее 🙂 .
    К тому же, фотошопу без разницы 🙂 .

  • Таким образом, если для меню задано _float:lef_ и оно длиннее

  • Таким образом, если для меню задано _float:lef_ и оно длиннее

  • Спасибо, уже исправил.

  • Спасибо, уже исправил.

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

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

  • Большое спасибо, очень помого в нужную минуту!

  • Большое спасибо, очень помого в нужную минуту!

  • FlashNet

    Думал думал и так и не понял чем второй способ лучше первого.
    Соотношение и там и там нормально сохраняется.

    • В первом варианте блок меню может «наехать» на хвостовик (размещен после контейнера, на рисунке не показан). Если меню длиннее чем основной текст.

  • FlashNet

    Думал думал и так и не понял чем второй способ лучше первого.
    Соотношение и там и там нормально сохраняется.

    • В первом варианте блок меню может «наехать» на хвостовик (размещен после контейнера, на рисунке не показан). Если меню длиннее чем основной текст.

  • rimmer

    спасибо, очень пригодилось
    зы: из оперы почему-то не получается камментить, Ваш плагин говорит что яваскрипт и кукисы выключены, хотя все включено

    • Вообще непонятная ошибка с комментариями. Я тестировал во всех браузерах, вроде все работало, но периодически возникают такие ошибки. Еще не разобрался почему.

  • rimmer

    спасибо, очень пригодилось
    зы: из оперы почему-то не получается камментить, Ваш плагин говорит что яваскрипт и кукисы выключены, хотя все включено

    • Вообще непонятная ошибка с комментариями. Я тестировал во всех браузерах, вроде все работало, но периодически возникают такие ошибки. Еще не разобрался почему.

  • Доброжелатель

    Админ,поправь ссылки «Valid XHTML, CSS» )) они не проверяют твой сайт на валидность.

    • Спасибо, что заметили.
      К сожалению не всегда получается показывать рекламу и обеспечить валидную разметку 🙁

  • Доброжелатель

    Админ,поправь ссылки «Valid XHTML, CSS» )) они не проверяют твой сайт на валидность.

    • Спасибо, что заметили.
      К сожалению не всегда получается показывать рекламу и обеспечить валидную разметку 🙁

  • Luciuz

    второй способ не работает в ие6