Каждый
из броузеров имеет свой довольно сложный алгоритм выбора размеров ячеек и размещения
материала в них в зависимости от натуральных размеров материала в ячейках,
«рекомендованных» размеров ячеек (атрибуты height и width
тега TD) и наличия некоторых особых случаев вроде групп ячеек,
объединенных по горизонтали или вертикали (атрибуты colspan и rowspan
того же тега). Расследование нюансов, странностей и просто
239
ошибок
в этих алгоритмах — занятие необычайно увлекательное (я сам, надо признаться,
отдал ему должное в свое время), но малопродуктивное. Лучше примите к сведению
небольшой набор советов, следование которым защитит вас от большинства
неприятных неожиданностей:
•
Не полагайтесь на «рекомендательные» размеры для отдельных ячеек; если вам
нужно, чтобы ячейка имела определенную ширину и высоту, вставьте в нее соответствующих
размеров распорку.Без атрибута width в
теге TD нельзя обойтись только тогда, когда нужно ограничить
ширину ячейки, содержащей текст (причем Iрезультат будет соответствовать
ожиданиям, только если текста этого хватает при данной ширине хотя бы на одну
полную строку).
Имеет
смысл зафиксировать также общую ширину самой внешней таблицы, определяющей
габариты всей страницы: атрибуту width соответствующего тега TABLE
обычно присваивается значение 100% для «резинового» и около 580 пикселов для
жесткого табличного дизайна (стр. 193). Более того, без жесткого (в пикселах)
задания ширины в теге TABLE таблица, содержащая слитые
по горизонтали ячейки, иногда совершенно необъяснимым образом «распухает», так
что ее ширина превосходит сумму ширин распорок во всех ячейках.
•
При необходимости можно сращивать несколько ячеек по горизонтали (атрибут colspan
тега TD), но только в том случае, если ширины участвующих в
операции столбцов жестко заданы распорками в других ячейках; если же, наоборот,
жестко задана только ширина объединенной ячейки, на правильное распределение
этой ширины между столбцами рассчитывать не приходится. По этой же причине
объединять ячейки по вертикали не рекомендуется вообще — лучше пользоваться
вложенными таблицами (рис. 52).
• В
сложных случаях, когда таблица упорно не хочет вести себя как задумано, можно
подсветить границы ячеек, заменив в заголовке border=0
на border=l, —
удобное средство отладки, аналогичное временной замене невидимых распорок на
видимые (см. выше). Учтите, что появляющаяся рамка добавляет по одному пикселу
ширины и высоты на каждую ячейку, так что общие габариты таблицы изменяются.
Спецификация
CSS1
(стр. 40) была типичным «пожарным» решением, спешной попыткой залатать самые
зияющие дыры HTML. Кроме возможности устанавливать поля
вокруг объектов, никаких усовершенствований на тему позиционирования в этой
версии еще не было. В CSS2, однако, разработчики
стандарта подошли к делу гораздо серьезнее и реализовали логичный и всеобъемлющий
набор инструментов, позволяющий свободно размещать материал на плоскости
страницы, сняв всякую необходимость пользоваться с этой целью таблицами.
Для
начала давайте рассмотрим, чем вообще определяется положение на странице того
или иного элемента документа (стр. 27). Язык CSS
унаследовал от HTML идею разделения всех элементов, чье
содержимое подлежит в той или иной форме выводу на экран, на строчные (inline) и блочные (block). Разница
между ними состоит в том, что идущие подряд строчные элементы выстраиваются по горизонтали, переходя
на новую строку, только если исчерпано горизонтальное пространство, тогда как
блочные элементы располагаются вертикально друг под другом (можно
сказать, что каждый блочный элемент начинает собой новый абзац).
Понятно,
что и для строчных, и для блочных элементов положение на странице будет
зависеть от количества и размеров всех предшествующих объектов того же класса.
Кроме образования цепочек, объекты обычно выстраиваются еще и в иерархические
структуры — так, цепочка строчных элементов может находиться внутри блочного
элемента (абзаца или таблицы). Таким образом, «в обычной жизни» координаты
элемента определяются двумя факторами: положением элемента-"родителя» и
наличием «старших братьев», т. е. элементов, предшествующих данному и имеющих с
ним общего родителя.
Теперь
вам будет легко понять разницу между двумя основными режимами
позиционирования, введенными в CSS2: относительным (relative) и абсолютным (absolute). Относительное
позиционирование позволяет смещать объект от той точки, которую он занимал бы
по умолчанию с учетом обоих упомянутых только что факторов. Относительное
позиционирование отдельных букв в абзаце позволяет, например, воспроизвести
логотип системы TEX, в котором буква «Е» cмещена
вниз не относительно какой-то точки на странице, 1 относительно своих соседей.
Такой логотип ведет себя как единый строчный элемент (в частности, он свободно
241
перемещается
при переверстке абзаца). Относительное смешение объекта не влияет на следующие
объекты в цепочке; они ведут себя так, как если бы тот стоял на своем законном
месте, — что может приводить, в частности, к наложению объектов друг на друга.
Разновидностью
относительного является плавающее (float) позиционирование, при котором объект смещается относительно
исходного положения до упора вправо или влево, отодвигая в этом месте текст (а
не накладываясь на него). В HTML того же эффекта для
изображений можно достичь с помощью атрибута align
тега IMG.
При
абсолютном
позиционировании элемента снимается один из двух указанных
факторов: положение объекта вычисляется относительно его «родителя», но без учета
«братьев». Иначе говоря, абсолютное позиционирование на самом деле вполне
относительно, но отличается тем, что имеет одну и ту же точку отсчета для
всех «детей» данного элемента-«родителя». Именно с помощью абсолютного позиционирования
обычно реализуется наложение элементов друг на друга, а также всевозможные
анимационные эффекты (для которых нужна также поддержка языка сценариев, стр.
64).
Разновидностью
абсолютного является фиксированное (fixed) позиционирование, при котором
элементом-«родителем» считается окно броузера. Это позволяет реализовать в CSS
некоторое подобие фреймов (в том числе и с автоматически появляющимися полосами
прокрутки), а также фоновые «водяные знаки», остающиеся неподвижными при
прокрутке содержимого переднего плана.
Как
относительное, так и абсолютное позиционирование могут приводить к наложению
элементов друг на друга. По умолчанию видимым остается тот элемент, который
выводится последним, т. е. стоит дальше всего от начала в исходном тексте HTML-документа.
Однако автор может управлять видимостью элементов и иначе. Для этого нужно
присвоить каждому элементу целое число, обозначающее его координату по «оси Z», направленной
перпендикулярнс плоскости экрана, — или, иными словами, указать порядковый
номер «слоя», в котором находится этот элемент. Пpи
наложении видимым будет тот элемент, у которого больше значение свойства z-order, —
т. е. тот, который находится «ближе к зрителю».
242
Оба
визуальных броузера поддерживают абсолютное позиционирование начиная с
четвертых версий. К сожалению, как и в других компонентах CSS, в
реализации этой технологии пока что много ошибок и несовместимостей. Причем
вместо того, чтобы бросить все силы на доводку своего сырого продукта,
создатели NetscapeCommunicator
сочли более важным застолбить новый участок очередным нестандартным тегом. Teг LAYER,
хотя и предоставляет ровно те же возможности, что и абсолютное позиционирование
средствами CSS, рекламируется фирмой намного активнее
(так, вместо термина «absolutepositioning» в
документации Netscapeгораздо
чаше употребляется «layers» или «layertechnology»). Хотя до сих пор смелое теготворчество давало Netscape
известное преимущество в конкурентной борьбе, я сильно сомневаюсь, что кто-то
станет пользоваться тегом LAYER при наличии полноценной
альтернативы, освященной авторитетом Консорциума W3.