Web-Anatomy.Ru

Десятилетию Рунета посвящается

К выпуску № 14 («Развилка трех дорог»)

Предположим, нам необходимо решить элементарную задачу — создать простейший «каркас» страницы, состоящий из двух колонок. Общая ширина его должна составлять 600 пикселей, а левая колонка, отведенная для панели навигации, в ширину должна иметь 200 пикселей.

Если прибегнуть к табличной верстке, любой кодер, помудрив слегка с вложенностью и атрибутом cellspacing в целях получения «плоской» рамки, выдаст на-гора примерно следующее:

<!-- Об элементе !DOCTYPE не заикаемся, таблицам со стандартами не по пути -->

<html>

<head>
<title>Табличный макет, версия 1</title>
</head>

<body text="#000000" bgcolor="#ffffff" topmargin="0" bottommargin="0" leftmargin="0" bottommargin="0" marginheight="0" marginwidth="0">
<table bgcolor="#336699" width="600" cellspacing="0" cellpadding="0" border="0">
<tr>
<td><table width="100%" cellspacing="1" cellpadding="20" border="0">
<tr>
<td bgcolor="#ccf0ff" width="198">Навигация</td>
<td bgcolor="#fff0cc" width="399">Основной текст</td>
</tr>
</table></td>
</tr>
</table>
</body>

</html>

Заданную общую ширину макета нам вполне удалось выдержать, но вот незадача — соотношение ширин колонок куда-то бесконтрольно уплывает… Несмотря на явное провозглашение width="198" для левой колонки (два пикселя отводится на границы), ширина гипотетической панели навигации во многих браузерах будет отличаться от намеченной величины, причем непредсказуемым образом. Поведение браузера зависит от многих факторов, основным из которых является объем текста в той или иной ячейке таблицы. Атрибут width является в данном контексте рекомендательным, и браузеры не обязаны ему строго следовать. Самый надежный способ сохранить заданную ширину ячейки таблицы — вставить в нее невидимую графическую распорку, растянув средствами HTML однопиксельный прозрачный GIF до требуемой величины. Еще нужно не забыть вставить такие же распорки в смежные ячейки таблицы, дабы выдержать и ширину последних на заданном уровне:

<!-- И тут какой уж !DOCTYPE -->

<html>

<head>
<title>Табличный макет, версия 2</title>
</head>

<body text="#000000" bgcolor="#ffffff" topmargin="0" bottommargin="0" leftmargin="0" bottommargin="0" marginheight="0" marginwidth="0">
<table bgcolor="#336699" width="600" cellspacing="0" cellpadding="0" border="0">
<tr>
<td><table width="100%" cellspacing="1" cellpadding="20" border="0">
<tr>
<td bgcolor="#ccf0ff" width="198"><img src="empty.gif" width="158" height="1" alt="" border="0"><br>Навигация</td>
<td bgcolor="#fff0cc" width="399"><img src="empty.gif" width="359" height="1" alt="" border="0"><br>Основной текст</td>
</tr>
</table></td>
</tr>
</table>
</body>

</html>

Вроде бы, получили, что требовалось. Но ведь совесть мучает: если хорошенько разобраться, на код ведь без слез не взглянешь! Ведь хочется же насладиться глубинной эстетикой, логической стройностью, простотой и понятностью кода…

Предпринимаем робкую попытку сверстать тот же макет слоями:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>
<title>Макет на основе слоев, версия 1</title>
<style type="text/css">
<!--
html, body {margin: 0px; padding: 0px}
body {color: #000; background-color: #fff}
div {position: absolute; border: solid 1px #369; padding: 20px}
#nav {top: 0px; left: 0px; width: 158px; background-color: #ccf0ff}
#txt {top: 0px; left: 199px; width: 359px; background-color: #fff0cc}
-->
</style>
</head>

<body>
<div id="nav">Навигация</div>
<div id="txt">Основной текст</div>
</body>

</html>

И ведь замечательно смотрится, не правда ли?

Нет, неправда. Пользователи пятого IE, которых, между прочим, пока еще хватает, полагаю, наше стремление к совершенству не оценят, ибо в этом браузере все съезжает неведомо куда.

Впрочем, зря я вас пугаю — вполне «ведомо». Согласно спецификации CSS2, значение свойства width задает ширину содержимого контейнера, в то время как величины padding (отступ от содержимого до рамки) и border-width (толщина собственно рамки) дополнительно прибавляются к ширине содержимого. В нашем примере значение параметра width для левой колонки равно 158, padding — 20 и border-width — 1 (все значения в пикселях). Если дважды (слева и справа) прибавить padding и border-width к width, получится как раз 200.

Но старые браузеры думают иначе. Для Internet Explorer 5.x (вплоть до версии 5.5 для Windows — в той же самой версии для Macintosh рассматриваемый огрех уже исправлен) параметр width означает общую ширину контейнера с учетом значений полей и толщины рамки. Чтобы в пятой версии майкрософтовского браузера выполнить условия нашей задачи, потребуется видоизменить код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>
<title>Макет на основе слоев, версия 2</title>
<style type="text/css">
<!--
html, body {margin: 0px; padding: 0px}
body {color: #000; background-color: #fff}
div {position: absolute; border: solid 1px #369; padding: 20px}
#nav {top: 0px; left: 0px; width: 200px; background-color: #ccf0ff}
#txt {top: 0px; left: 199px; width: 401px; background-color: #fff0cc}
-->
</style>
</head>

<body>
<div id="nav">Навигация</div>
<div id="txt">Основной текст</div>
</body>

</html>

Для IE6, Opera и других «законопослушных» браузеров, понятное дело, такой макет не подходит. Намек, я думаю, понятен — ведь все, наверное, представляют себе, что такое переменная окружения HTTP_USER_AGENT? :-)

Впрочем, некоторые поступают гораздо проще. А именно, подготавливают версию макета сообразно правилам, принятым в IE5, и не включают в код объявление типа документа. Тогда и в IE6, и в Opera 7.x такая страница отображается «по старинке», с использованием тех же самых представлений о сути вещей, которыми «радует» нас пятая версия браузера Internet Explorer:

<-- А теперь уберем к черту этот !DOCTYPE -->

<html>

<head>
<title>Макет на основе слоев, версия 3</title>
<style type="text/css">
<!--
html, body {margin: 0px; padding: 0px}
body {color: #000; background-color: #fff}
div {position: absolute; border: solid 1px #369; padding: 20px}
#nav {top: 0px; left: 0px; width: 200px; background-color: #ccf0ff}
#txt {top: 0px; left: 199px; width: 401px; background-color: #fff0cc}
-->
</style>
</head>

<body>
<div id="nav">Навигация</div>
<div id="txt">Основной текст</div>
</body>

</html>

Только вот о каком стремлении к совершенству здесь можно говорить? Отсутствие элемента <!DOCTYPE> — это грубое нарушение стандарта. Уж лучше забыть обо всем и верстать таблицами… Так, во всяком случае, честнее будет.

Вот и наметилась, стало быть, тема следующей колонки (и, заодно, следующей серии практических примеров): как же можно «законно» обойти разногласия между IE5, с одной стороны, и приличными браузерами — с другой.

[Перейти к оглавлению]

© Артемий Ломов, 2004, 2005.