Без преувеличения можно сказать, что таблицы в HTML - это больше, чем таблицы. Вообще, надо сказать, HTML полон таких вот странных примеров использования вещей "не по назначению", приспосабливания их для решения каких-то задач ввиду отсутствия нормальных механизмов решения этих задач. И таблицы - один из наиболее характерных примеров. Помимо вывода собственно табличной информации они долгое время использовались (да и сейчас продолжают использоваться) для создания средствами HTML какого-либо более-менее вразумительного макета. Дело в том, что HTML предполагает последовательную загрузку: пришла порция текста отобразилась в браузере, пришла следующая - отобразилась дальше. И так, пока не загрузится вся страница.
При медленном соединении это особенно актуально: Вы можете начинать чтение, пока остаток страницы догружается. Естественно, никакая верстка при этом невозможна: пока мы не получим весь текст, непонятно, как его верстать: может быть там осталось две строчки, а может - 10 страниц. А вдруг там внизу окажется какая-нибудь огромная картинка? Поэтому изначально в HTML вообще не было заложено никаких механизмов верстки: гипертекст аккуратненько заполнял всё окно браузера. Но когда появились механизмы отображения таблиц, кто-то подумал: а почему бы не заключить в таблицу всё содержимое страницы?
Ну и пошло-поехало. Так вот и вбивались гвоздики в крышку гроба HTML-я как языка исключительно структурной разметки: таблицами стали размечать вовсе не табличную информацию. Сейчас многие подобные несуразности уходят в историю, появились и более правильные, чем таблицы, механизмы позиционирования информации на странице (через таблицы стилей). Помимо теоретической неправильности такого использования таблиц, оно имеет и практические недостатки. Главный из них: браузер не может отобразить таблицу, не дождавшись всего помещённого в неё текста. Т. е. мы лишаем пользователя чудесной возможности начинать просмотр страницы, не дожидаясь её полной загрузки.
Вообще же подход к верстке гипертекстовых страниц должен быть иной, нежели в полиграфии. Дизайнерам очень трудно с этим смириться, но здесь невозможно точно скомпоновать всё, как на листе. Прежде всего потому, что у нас нет этого "листа": мы не можем предугадать размер окна, в котором будут просматривать нашу страницу. Кроме того, мы не можем предугадать ещё массу факторов, влияющих её внешний вид. Информация должна быть пригодна к восприятию в самых разных условиях. И вместо того, чтобы искать способы "запереть" размер шрифта или задать ширину страницы, следует разрабатывать дизайн таким образом, чтобы он нормально смотрелся при разной ширине страницы и разном размере шрифта.
Итак, таблицы… Создаются они с помощью элемента <TABLE>. Элемент блочный, закрывающий тег - обязательный. Имеет нерекомендованный атрибут align, определяющий положение таблицы в документе. Может
принимать значения: right - выравнивание по правому краю, center - выравнивание по центру и left - значение по умолчанию - выравнивание по левому краю. Также имеет атрибут width, позволяющий задать ширину таблицы и, собственно, выстраивать некий макет.
Ширина задается либо жестко - в пикселях, либо в процентах от ширины окна браузера (в этом случае к значению атрибута приписывается знак процента). Теперь наша таблица растягивается в соответствии с шириной окна. Она может иметь ширину 100% или любой другой процент. Тут опять же есть тонкости: если заданная ширина ячейки не позволяет вместить содержимое (например, в ячейке находится большая картинка или длинное слово), то, не взирая на заданную ширину, ячейка растянется так, чтобы вместить всё содержимое. Если ширина таблицы вообще не задана, то браузер сам определяет её, исходя из содержимого. Внутри себя элемент TABLE может содержать собственно ячейки таблицы (об этом - буквально через секунду), а также элемент <CAPTION>. Причем этот элемент должен размещаться до ячеек, т.е. сразу после открывающего тега <TABLE>. Этот элемент задает подпись к таблице. Этот элемент может иметь нерекомендованный атрибут align, определяющий положение подписи относительно таблицы. Может принимать значения: top (над таблицей), bottom (под таблицей), left (слева) или right (справа).
А теперь самое интересное - собственно, содержимое таблицы. Оно может распределяться по 3 группам. Первая группа - шапка таблицы - элемент <THEAD>. Обычно это первая строка (или строки) таблицы, содержащая заголовки столбцов. Вторая группа - "подвал" таблицы - элемент <TFOOT> - это те же самые заголовки, только расположенные в конце таблицы. И, наконец, третья группа - собственно "тело" таблицы - элемент <TBODY>.
К шапке и подвалу мы вернемся позже, тем более, что это вещи пока довольно экзотические, а сейчас рассмотрим тело таблицы. Элемент этот, вообще говоря, является элементом подразумеваемым, так же как <HTML> или <BODY>. Т.е. если у вас в таблице нет шапки и подвала, а одно только "тело", то явно указывать <THEAD> не обязательно. Содержимое таблицы состоит из строк, разбитых на ячейки. Вот таким образом. Устроить таблицы наоборот, "поколоночно", невозможно, хотя в каких-то случаях это было бы удобнее.
Итак, строка. Задается с помощью элемента <TR> (table row - строка таблицы). Закрывать этот элемент необязательно. Строка содержит ячейки, задаваемые элементами <TD> и <TH>. Закрывающие теги у этих элементов также необязательны. Какая же разница между td и th? <TD> - это ячейка с данными, а <TH> - ячейка с "названием" строки или столбца. Например, если у нас, как в данном случае, есть ячейки, содержащие фамилии людей, и есть ячейки, содержащие некоторые данные по этим людям, то фамилии следует заключать не в <TD>, а в <TH>. В визуальных браузерах <TH> обычно выделяется полужирным начертанием и выравниванием по центру ячейки.
О выравниваниях мы поговорим позже. С помощью атрибута width можно указывать ширину ячеек, однако, как и в случае таблицы в целом, указание ширины носит для браузера скорее рекомендательный характер. Широкое содержимое всё равно при необходимости "растянет" ячейку, а некоторые браузеры могут наоборот, сужать их до размеров содержимого, не глядя на указанный атрибут. Ещё у ячеек есть атрибут height, задающий высоту, но он работает ещё менее четко, чем width, и надеяться с его помощью корректно задавать высоты ячеек не стоит. Для этого приходится пользоваться разными ухищрениями, о которых речь пойдёт дальше.
Если нужно внутри ячейки запретить перенос по словам, можно задать этой ячейке атрибут nowrap. Ему не присваивается никакого значения, просто пишется такое слово. Это значит, что содержимое ячейки должно вытягиваться в одну строчку. Однако механизм этот не очень надежен. Например, если задана ширина ячейки, то перенос всё-таки осуществится. Надёжнее пользоваться элементом <NOBR>. Этот элемент часто применяется и в других случаях. Все, что заключено в него, выводится в одну строку, без переносов.
Несколько ячеек можно объединять в одну. Для этого служат атрибуты colspan и rowspan. Разберём на простом примере. Допустим, мы хотим объединить несколько ячеек по горизонтали. Скажем, первую и вторую. Для горизонтального объединения служит элемент colspan. Значением этого атрибута является количество объединяемых ячеек, включая и первую ячейку. В данном случае их будет две. Соответственно, вторую ячейку мы удаляем, так как она у нас слилась с первой. И вот, что у нас получилось. Мы можем объединить и три ячейки. В таком случае у нас всю верхнюю строку займет одна ячейка. Rowspan объединяет ячейки "по вертикали". Берет ячейки не из соседних столбцов, а из соседних строк. Можно, конечно, захватить для объединения ячейки и больше, чем из одной строки. Можно одновременно применять и colspan, и rowspan.
Естественно, мы не можем объединять ячейки какой-нибудь "буквой Г". При объединении ячеек нужно быть очень внимательным, чтобы не запутаться, где у нас сколько элементов TD. Например, в данном случае мы имеем три строки по три ячейки. Но первая ячейка объединяет две по горизонтали и две по вертикали. Соответственно, в первой строке остается одна неприсоединенная ячейка. Во второй строке две первых ячейки относятся к первой строке, то есть остается также одна ячейка. Ну а третья строка не тронута. Справедливости ради надо сказать, что составлять таблицы, конечно, удобнее в HTML-редакторе, а писать их вручную - не самое эффективное занятие. Но надо уметь по крайней мере разобраться в коде, чтобы найти ошибку, если таблица "разъехалась", а редактор найти эту ошибку не может.
Ячейки таблиц могут содержать вложенные таблицы. Особенно это актуально как раз для "неправильного" использования таблиц - для создания макета страницы. Вот таким необычным образом несчастные дизайнеры вынуждены реализовывать свои смелые идеи.
Теперь вернемся к шапке и подвалу - элементам <THEAD> и <TFOOT>. И шапка, и, как это ни удивительно, подвал в HTML-е должны идти до тела таблицы. Однако это перестает казаться удивительным, если разобраться, для чего они нужны. Правда, браузеры пока толком не поддерживают все эти замечательные функции, но замысел здесь следующий: во-первых, реализовать скролиинг содержимого таблицы независимо от шапки и подвала (такая возможность есть, например, в Экселе: вы проматываете содержимое большой таблицы, при этом названия столбцов остаются у вас перед глазами), во-вторых, при распечатке длинных таблиц, не помещающихся на одной печатной странице, шапка и подвал могут автоматически выводится на каждой странице.
Теперь поговорим об оформлении таблиц. Опять же оговорюсь, что правильнее контролировать оформление через таблицы стилей, но перечисленные ниже атрибуты всё ещё поддерживаются браузерами. Прежде всего, конечно, какие у нас есть механизмы раскрашивания, прошу прощения за грубое слово, таблиц? Таких механизмов два: атрибут bgcolor, задающий фоновой цвет. Если мы применяем этот атрибут к таблице, то она вся заливается этим цветом. Либо мы можем задать цвет фона отдельных ячеек. Тогда нужно проставить атрибут соответствующим элементам TD. Вот таким, например, образом. Итак, атрибут bgcolor может быть установлен как для всей таблицы, так и выборочно, для отдельных её ячеек.
Второй механизм - атрибут background, позволяющий задать в качестве фона не цвет, а некое графическое изображение. Значением атрибута является адрес файла фоновой картинки. Об этом мы подробнее поговорим при изучении изображений. Вот такая красота. Теперь остановимся на
выравнивании. Содержимое любой ячейки может выравниваться тем или иным образом по горизонтали и по вертикали.
Горизонтальное выравнивание контролирует знакомый вам атрибут align. Он может принимать значения left, center, right, justify. Все эти значения Вам уже должны быть знакомы. По умолчанию обычно ячейки с данными <TD> выравниваются по левому краю, ячейки-заголовки <TH> - по центру. Как раз с помощью атрибута align мы можем их выравнивание изменить (например, выровнять возраст по центру).
За вертикальное выравнивание отвечает атрибут valign. По умолчанию содержимое вертикально выравнивается по центру. Мы можем это изменить. Вот этот атрибут, который может принимать значения top (выравнивание по верхнему краю), bottom (выравнивание по нижнему краю) или middle -это то, что мы видим по умолчанию - выравнивание по центру.
Следующий инструмент оформления таблиц - это расстояние между ячейками таблицы и между их содержимым. Для этого предназначены два атрибута: cellspacing и cellpadding. Cellspacing задает расстояние между ячейками таблицы. Cellpadding задает отступ от границы ячейки до её содержимого. Значения эти задаются разом для всей таблицы. Таблицы стилей позволяют задавать значения и для отдельных ячеек. Обратите внимание, что в промежутки, образованные атрибутом cellspacing, просвечивает фон таблицы. Это позволяет нам имитировать разные интересные обводки (например вот такие, или такие) варьируя cellspacing, цвет таблицы и ячеек. Очень часто, особенно при использовании таблиц для создания макетов, значения этих атрибутов (так же как и толщину рамки) обнуляют, чтобы содержимое ячеек вплотную прилегало друг к другу. Таблица тогда фактически не видна, а видно только, каким образом сверстан текст.
Граница (рамка, обводка) таблицы и её ячеек контролируются атрибутами border, frame и rules. Border задает ширину рамки таблицы в пикселях. Как видите, это рамка самой таблицы, а не ячеек. Атрибут frame указывает, с каких сторон таблицы нужно рисовать границу, а с каких - нет. Значения могут быть следующие: void (рамка не отображается), box, border (все 4 стороны - это значение по умолчанию), above (только верхняя граница), below (только нижняя граница), hsides (верхняя и нижняя границы), vsides (левая и правая), lhs (только левая), rhs (только правая). Вроде, ничего не забыл.
Rules отвечает не за внешнюю границу таблицы, а за границы между ячейками. Тут возможных значений чуть меньше: none (границ между ячейками нет), all (значение по умолчанию - изображаются все границы), rows (видны границы только между строками), cols (только между столбцами)
и, наконец, groups (границы проводятся только между группами строк, то есть шапкой, телом, подвалом).