Глаза страшат, а руки делают

CSS и DOCTYPE


Когда я углубился в изучение блочной вёрстки, то обнаружил, что многие «рецепты» кодов в разных браузерах ведут себя непредсказуемо. Я задавал занудные вопросы на форумах, но никто толком не мог ничего объяснить.

Однажды я скачал готовый блочный шаблон, написанный для совместимости с XML, и начал его редактировать, убирая «лишние» слэши и установив «правильный» доктайп.

Вёрстка развалилась…

Дело оказалось именно в доктайпе. Теперь я в состоянии всё это объяснить.


В самом начале кода HTML в различных пособиях обычно рекомендуют ставить тэг <!DOCTYPE>. Говорят, что он «объясняет» браузеру тип документа, что это якобы может быть важно, но в подробности не вдаются. В шаблоне редактора HomeSite, в котором я постоянно работаю, стояла такая вот «глокая куздра»:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

Если использовались фреймы, то рекомендовалось ставить

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">

Я это честно копировал, не задумываясь о сущности. Потом как-то узнал, что есть ещё «строгий» доктайп:

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

Но опять всё было без объяснений, кто же такой этот бокр и за что его куздра будланула.

Но когда будланула уж слишком штеко, да ещё и раскурдячила всех моих бокрят, я панически загуглил.

Итак, сначала маленькое занудное пояснение:

!DOCTYPE — тип документа.

Атрибуты:

HTML — указание на тип документа HTML.

PUBLIC — документ публичный (а не SYSTEM — системный, внутренний).

Следующий атрибут — выражение в кавычках, пожалуй, оставим на уровне «глокой куздры», отметим лишь следующее:

HTML 4.01//EN говорит, что документ поддерживает версию HTML 4.01, описание которого существует на английском языке (EN).

Последний атрибут — опять же выражение в кавычках — указывает адрес файла этого описания. В шаблоне HomeSite тэг <!DOCTYPE> давался без последнего атрибута, но правильнее — его указывать.

Файл strict.dtd описывает «строгий» синтаксис, без поблажек и причуд.

HTML 4.01 Transitional//EN указывает на так называемый переходный синтаксис, описанный в файле loose.dtd по тому же адресу. Вот так это выглядит полностью:

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

И наконец полный доктайп фреймовой страницы:

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

Синтаксис Transitional придуман для совместимости со страницами, созданными для более старых версий как браузеров, так и самого языка разметки. Как водится, в разных браузерах это работает по-разному. Но в этой кажущейся непредсказуемости уже забрезжили закономерности.

В общем, нас с вами сейчас интересуют предельно конкретные различия между Transitional и Strict.

Отчего в IE рассыпается блочная вёрстка?

Стиль margin

Главным образом оттого, что Internet Explorer 6 в режиме Transitional не поддерживает выравнивание блока по центру с помощью правила margin: 0 auto.

Пояснение: margin: 0 auto указывает, что верхний и нижний отступы нулевые, а правый и левый — auto, т.е. размер этих отступов будет автоматически рассчитан браузером. В ныне действующей спецификации DOM блок с такими параметрами по горизонтали позиционируется по центру. IE до версии 6.0 не поддерживает это значение и горизонтально позиционирует блок по умолчанию, т.е. по нулю.

В следующем шаблоне всё содержимое помещено в блок, позиционированный с отступами

margin: 0 auto.

При этом белое поле основного блока представлено как фоновая картинка в body:

background: #73C5E5 [цвет за пределами контента]

url(images/img01.gif) repeat-y center top [позиционированный по центру белый фоновый рисунок].

Позиция фонового рисунка repeat-y center top поддерживается и устаревшей спецификацией.

Вид шаблона при Strict

Вид шаблона при Transitional (блок-контейнер уезжает на левый ноль, фоновая подложка остаётся на определённом для неё месте)

Проблемы с padding, height и border

Я уже писал о трактовке свойства border разными браузерами (см. статью Блоки: IE via Mozilla). В «строгом» режиме это уже не актуально, все браузеры выносят border за пределы заданной ширины/высоты элемента.

Поведение width

Действие width в браузерах

DOCTYPE

Internet Explorer

Firefox

Opera

Не указан

Если содержимое превышает заданную ширину, то блок изменяет свои размеры, подстраиваясь под содержимое. В противном случае ширина блока равна значению width.

Во всех случаях Firefox действует по спецификации CSS. А именно, ширина блока получается сложением значений width, padding, margin и border.
Содержимое блока, если не помещается в заданные размеры, отображается поверх блока.

Ширина равна значению width.Содержимое блока, если не помещается в заданные размеры, отображается поверх.

"Переходный"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

"Строгий"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

Ширина формируется путем сложения значений width, padding, margin и border.
Содержимое блока, если не помещается в заданные размеры, отображается поверх.

Ширина равна значению width плюс padding, margin, и border.
Содержимое блока, если не помещается в заданные размеры, отображается поверх.

XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

Так выглядит блок с указанными параметрами в режиме strict во всех стандартных браузерах (красной пунктирной линией показаны границы блока при «плавающей» вёрстке):

style="margin: 0px 50px 0px 80px; width: 300px; border: 15px solid Black; padding: 20px;
80 15 20 300 20 15 50

А так — в IE в режиме transitional:

style="margin: 0px 50px 0px 80px; width: 300px; border: 15px solid Black; padding: 20px;
80 15 20   20 15 50
300

Нежелательные тэги и атрибуты

Небольшой справочник по устаревшим тэгам и атрибутам, которые при определении strict могут работать криво или никак.

Тэги

Тэг

Описание

Альтернатива

<applet>

Вставляет на страницу апплеты, написанные на языке Java (не путать с JavaScript!)

Заменяется универсальным тэгом <object>, вставляющим любые «инородные» объекты.

<basefont>

Задаёт шрифт, размер и цвет текста по умолчанию во всем документе, кроме текста, заключённого в тэг <font>, в котором можно переопределить параметры.

Заменяется определением шрифта в стиле CSS.

<center>

Располагает содержимое по горизонтальному центру относительно родительского элемента.

Замены:
а). <div align="center">;
б). стиль CSS {text-align: center;}.

<dir>

Создаёт список, содержащий названия директорий (системные папки). Работает точно так же, как тэг <ul>.

Абсолютно логично заменить его тэгом <ul>.

<font>

Задаёт шрифт, размер и цвет текста, заключённого в тэг.

Заменяется определением шрифта в стиле CSS.

<isindex>

Предназначен для поискового индекса в текущем документе. Этого тэга я даже не знал. И так и не понял, как он работает.

Рекомендуется вместо него использовать тэги <form> и <input>.

<noframes>

Отображается только в браузерах, которые не поддерживают фреймы. В нём можно разместить, например, сообщение, что Ваш [ископаемый] браузер не поддерживает [и без того давным-давно устаревшие] фреймы.

Нормальные браузеры просто игнорируют этот тэг.

<plaintext>

Делает фактически то же, что тэг <pre>, только с глюками.

Просто забыть и забить. Использовать <pre>.

<s>, <strike>

Идентичные тэги, отображающие текст как перечеркнутый.

Заменяются стилем CSS {text-decoration: line-through;}.

<u>

Подчёркнутый текст.

Заменяется стилем CSS {text-decoration: underline;}.

<xmp>

Абсолютно то же, что и тэг <pre>.

Тоже забыть и забить и использовать <pre>.

Атрибуты

Если рекомендации по поводу устаревших тэгов кажутся мне вполне логичными, то со «списыванием» некоторых атрибутов хочется поспорить.

Атрибут

Тэг

Описание

Альтернатива

target

<a>

Определяет, в каком окне открывать ссылку: в том же или в новом. Логика причисления атрибута к «лику динозавров» такова: во всех современных браузерах это регулируется в меню правой кнопки мышки. Разные пользователи любят разные способы открытия. И нечего им указывать, где открывать окно. Но, скажем, я пользуюсь правой кнопкой. А очень многие этого не понимают. К тому же не очень понимают, как вернуться назад, если в текущем окне открылась новая страница (что поделать, живём в эпоху тотальной дебилизации). Я считаю этот атрибут, всё-таки, полезным в некоторых случаях.

Альтернатива: учитесь пользоваться всеми кнопками.

start

<ol>

Показывает, с какого пункта начать нумерованный список. По-моему, очень полезный атрибут для больших текстов, где между пунктами списка вложены комментарии в обычном формате. Зачем его «списали» — не понимаю.

Альтернатива только одна: не использовать тэг <ol> и набирать все номера списка вручную.

type

<li>, <ol>, <ul>

Для тэга <ol> устанавливает тип нумерации (арабские, римские цифры, заглавные, строчные латинские буквы), для тэга <ul> — тип «булика», для тэга <li> — в зависимости от контекста (какому списку он принадлежит).

Заменяется стилем CSS list-style-type. Значений у него очень много, не буду их перечислять — есть даже армянские и греческие буквы (а вот русских нет).

Вёрстка

В строгом режиме текст нельзя напрямую добавлять в <body>, его надо предварительно уложить в блочный элемент: например, <p> или <div>.

Неправильно:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Пример 1</title>
</head>
<body>

Этот текст выводится на страницу.
</body>
</html>

Тоже неправильно (<span> — это не блочный элемент):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Пример 2</title>
</head>
<body>
<span>
Этот текст выводится на страницу.</span>
</body>
</html>

Правильно:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Пример 3</title>
</head>
<body>
<p>
Этот текст выводится на страницу.</p>
</body>
</html>

Тоже правильно:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
Пример 4</title>
</head>
<body>
<div>
Этот текст выводится на страницу.</div>
</body>
</html>

Не рекомендуется также помещать прямо в <body> изображения и элементы форм. Кроме того, в тэге <form> должен присутствовать атрибут action.

Плохо:

<body>
<img src="picture.jpg">
</body>

Хорошо:

<body>
<div>
<img src="picture.jpg"></div>
</body>

Неправильно (сразу две ошибки):

<body>
<form>
<input type=
"text">
</form>

</body>

Обе ошибки исправлены:

<body>
<form action="">
<p><input type="text"></p>
</form>
</body>


 004920