11 Таблицы

Содержание

  1. Введение в таблицы
  2. Элементы для построения таблиц
    1. Элемент TABLE
    2. Название таблицы: элемент CAPTION
    3. Строковые группировщики: элементы THEAD, TFOOT, и TBODY
    4. Группировщики столбцов: элементы COLGROUP и COL
    5. Строки таблиц: элемент TR
    6. Ячейки таблиц: элементы TH и TD
  3. Формирование таблиц графическими броузерами
    1. Рамки и правила оформления
    2. Горизонтальное и вертикальное выравнивание
    3. Интервалы ячейки
  4. Формирование таблиц не-графическими броузерами
    1. Соединение информации заголовка с ячейками данных
    2. Категоризация ячеек
    3. Алгоритм, для поиска информации заголовка
  5. Пример таблицы

11.1 Введение в таблицы

Модель HTMLовской таблицы позволяет нам упорядоченно размещать данные (текст, предварительно форматированный текст, изображения, связи, формы, поля формы, другие таблицы, и т.д.) в строки и столбцы из ячеек.

Каждая таблица может иметь связанное с ней название (см. элемент CAPTION), которое кратко объясняет назначение таблицы. Дополнительно, с помощью атрибута summary, для людей, использующих речевые броузеры или броузеры Брайля, можно создать более длинное описание назначения таблицы.

Строки таблиц (посредством элементов THEAD, TFOOT и TBODY, соответственно) могут быть разделены на следующие группы: верхний колонтитул, нижний колонтитул, и разделы тела таблицы. Строковые группировщики содержат дополнительную структурную информацию, и на основе этого, броузеры могут сформировать таблицу так, чтобы подчеркнуть ее структуру. Броузеры могут использовать разделение head/body/foot, чтобы обеспечить прокрутку разделов тела таблицы независимо от нижнего и верхнего колонтитулов. При печати длинных таблиц, информация из верхнего и нижнего колонтитулов может быть повторена на каждой странице, содержащей табличные данные.

Строки таблиц (table rows) (посредством элементов THEAD, TFOOT и TBODY, соответственно) могут быть разделены на следующие группы: верхний колонтитул, нижний колонтитул, и разделы тела таблицы. Строковые группировщики содержат дополнительную структурную информацию, и на основе этого, броузеры могут сформировать таблицу так, чтобы подчеркнуть ее структуру. Броузеры могут использовать разделение head/body/foot, чтобы обеспечить прокрутку разделов тела таблицы независимо от нижнего и верхнего колонтитулов. При печати длинных таблиц, информация из верхнего и нижнего колонтитулов может быть повторена на каждой странице, содержащей табличные данные.

Столбцы тоже можно группировать (group columns), если описать дополнительную структурную информацию, которая может быть использована броузерами. Более того, посредством элементов COLGROUP и COL, в начале определения таблицы можно задать реквизиты столбцов, что позволит броузерам начать выдачу этой таблицы пользователю не ожидая, перекачки абсолютно всех данных из таблицы.

В ячейках (table cells) могут храниться как табличные данные (см. элемент TH ), так и информация о заголовках столбцов (см. элемент TH ). Модель таблицы HTML 4.0 позволяет так пометить каждую ячейку, чтобы не-графические броузеры (non-visual user agents) могли легко, донести информацию о заголовоке столбца до пользователя. Эти механизмы не только облегчают жизнь слепым пользователям, они также делают возможным обработку таблиц при помощи различных универсальных беспроводных броузеров (например Веб-пейджерров или Веб-телефонов), которые имеют ограниченные возможности для отображения информации.

Таблицы не должны использоваться только как средства для верстки информации на страничке, поскольку это может создать проблемы при формировании их не-визуальными средствами (прим.пер - речь идет о "невидимых" таблицах, которые повсеместно для этого используются). Дополнительно, если эти таблицы разработаны на системе с большим дисплеем, то они могут вынуждать пользователей прокручивать их горизонтально. Если данные проблемы нежелательны, то для верстки веб-странички лучше использовать стилевые спецификации (style sheets).

Примечание. В разделах этой спецификации, посвященных рациональному использованию и коструированию таблиц (table design rationale and implementation issues) содержится более детализированая информация.

Рассмотрим простую таблицу, которая иллюстрирует некоторые из возможностей модели HTMLевской таблицы. Следующий исходный код таблицы:

<TABLE border="1"
          summary="This table gives some statistics about fruit
                   flies: average height and weight, and percentage
                   with red eyes (for both males and females).">
<CAPTION><EM>A test table with merged cells</EM></CAPTION>
<TR><TH rowspan="2"><TH colspan="2">Average
    <TH rowspan="2">Red<BR>eyes
<TR><TH>height<TH>weight
<TR><TH>Males<TD>1.9<TD>0.003<TD>40%
<TR><TH>Females<TD>1.7<TD>0.002<TD>43%
</TABLE>

на устройстве вроде телетайпа мог бы быть изображен так:

          A test table with merged cells
    /-----------------------------------------\
    |          |      Average      |   Red    |
    |          |-------------------|  eyes    |
    |          |  height |  weight |          |
    |-----------------------------------------|
    |  Males   | 1.9     | 0.003   |   40%    |
    |-----------------------------------------|
    | Females  | 1.7     | 0.002   |   43%    |
    \-----------------------------------------/

а на графическом броузере так:

A table with merged cells

11.2 Элементы для построения таблиц

11.2.1 Элемент TABLE

<!ELEMENT TABLE - -
     (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<!ATTLIST TABLE                        -- элемент таблицы --
  %attrs;                              -- %coreattrs, %i18n, %events --
  summary     %Text;         #IMPLIED  -- резюме(структурный атрибут) для речевого вывода--
  width       %Length;       #IMPLIED  -- ширина таблицы --
  border      %Pixels;       #IMPLIED  -- управляет шириной рамки вокруг таблицы --
  frame       %TFrame;       #IMPLIED  -- какие части рамки сформировать --
  rules       %TRules;       #IMPLIED  -- правила оформления строк и столбцов --
  cellspacing %Length;       #IMPLIED  -- интервалы между ячейками --
  cellpadding %Length;       #IMPLIED  -- интервалы внутри ячеек --
  >

Начальный тег: необходим, Заключительный тег: необходим

Определение атрибутов

summary = text [CS]
Этот атрибут дает конспективное изложение назначения таблицы и выступает как структура - для того, чтобы сформировать таблицу в неграфических речевых броузерах или броузерах Брайля.
align = left|center|right [CI]
Нерекомендован (Deprecated). Этот атрибут определяет позицию таблицы относительно документа. Возможные значения:
  • left: Таблица прижимается к левой стороне странички.
  • center: Таблица центрируется относительно странички.
  • right: Таблица прижимается к правой стороне странички.
width = length [CN]
Этот атрибут определяет желательную ширину всей таблицы и предназначен для графических броузеров. Если значение является процентным числом, то ширина таблицы рассчитывается исходя из видимой ширины окна броузера. При отсутствии этого атрибута ширина таблицы соответствует ширине окна броузера.

Атрибуты, совпадающие с атрибутами других элементов

Элементом TABLE обрамляются все остальные элементы, определяющие заголовок, строки, содержание, и внешний вид таблицы.

Ниже описано, какие операции при формировании таблицы могут выполнять броузеры:

Модель HTMLевской таблицы была разработана так, чтобы (при желании разработчика) броузеры могли вести вывод таблицы последовательно(incrementally) (т.е. по мере закачки отдельных строк), не дожидаясь перекачки абсолютно всех данных.

Чтобы броузер мог отформатировать таблицу за один проход, ему нужно указать следующее:

Броузер может более точно сформировать таблицу за один проход, когда посредством комбинации элементов COLGROUP и COL заданы ширины столбцов. Если ширина какого-нибудь из столбцов задана относительным или процентным условием (см. раздел по вычислению ширины столбцов (calculating the width of columns)), то необходимо указать полную ширину таблицы.

Ориентация таблицы (Table directionality) 

Ориентация таблицы (The directionality of a table) или определяется атрибутом dir элемента TABLE, или наследуется (значение по умолчанию - слева направо).

Для таблицы, ориентированной "слева направо", нулевой столбец находится слева, я нулевая строка - сверху. Для ориентированной "справа налево" таблицы, нулевой столбец находится справа, а нулевая строка все также сверху.

Когда броузер добавляет дополнительные ячейки к строке (см. раздел о вычислении числа столбцов в таблице (calculating the number of columns in a table)), то для таблиц типа "слева направо" дополнительные ячейки добавляются справа, а для таблиц типа "справа налево" - слева.

Обратите внимание, что TABLE это - единственый элемент, у которого атрибут dir изменяет порядок показа столбцов, однако у одиночной табличной строки (TR) или группы столбцов (COLGROUP), это невозможно изменить независимым образом (cannot be independently reversed).

Атрибут dir, установленный для элемента TABLE, также воздействует на направление текста внутри ячеек таблицы (так как он (атрибут dir ) унаследован элементами на уровне блока).

Для того, чтобы создать таблицу, ориентированную слева направо, атрибут dir следует использовать так:

<TABLE dir="RTL">
...the rest of the table...
</TABLE>

Направление текста в отдельных ячейках может быть изменено, если соответствующим образом установить атрибут dir в определяющем ячейку элементе. В разделе о двунаправленном тексте (bidirectional text) можно получить подробную информацию о направлении вывода текста.

11.2.2 Название таблицы: элемент CAPTION

<!ELEMENT CAPTION  - - (%inline;)*     -- название таблицы -->
<!ENTITY % CAlign "(top|bottom|left|right)">

<!ATTLIST CAPTION
  %attrs;                              -- %coreattrs, %i18n, %events --
  >

Начальный тег: необходим, Заключительный тег: необходим

Определение атрибутов

align = top|bottom|left|right [CI]
Нерекомендован (Deprecated). Этот атрибут определяет позицию названия относительно таблицы (для графических броузеров). Возможные значения:
  • top: Название находится сверху таблицы. Это значение по-умолчанию.
  • bottom: Название находится снизу таблицы.
  • left: Название находится слева от таблицы.
  • right: Название находится справа от таблицы.

Атрибуты, совпадающие с атрибутами других элементов

Текст элемента CAPTION должен описывать характер таблицы (describe the nature of the table). Элемент CAPTION разрешается помещать непосредственно после начального тега TABLE. Элемент TABLE может содержать только один элемент CAPTION.

Графические броузеры позволяют зрячим людям быстро понять смысл таблицы как из заголовков столбцов(headings), так и из названия таблицы(caption). Вследствие этого, людям использующим неграфические броузеры будет трудно разобраться в таблице, ориентируясь только на название.

Следовательно, при помощи атрибута summary элемента TABLE, необходимо задать дополнительную информацию, которая вскроет смысл и структуру таблицы. Это очень важно для таблиц, не имеющих названия. Дальнейшие примеры иллюстрируют ипользование атрибута summary.

Графические броузеры не должны показывать всего лишь часть (clipping) таблицы (даже включая название), если не обеспечивается, просмотр всей таблицы, например горизонтальной или вертикальной прокруткой. Рекомендуется, чтобы текст названия был сверстан по ширине таблицы. (См. раздел по рекомендуемым алгоритмам верстки (recommended layout algorithms).)

11.2.3 Строковые группировщики: элементы THEAD, TFOOT, и TBODY

<!ELEMENT THEAD    - O (TR)+           -- верхний колонтитул таблицы -->
<!ELEMENT TFOOT    - O (TR)+           -- нижний колонтитул таблицы -->

Начальный тег: необходим, Заключительный тег: необязателен

<!ELEMENT TBODY    O O (TR)+           -- тело таблицы -->

Начальный тег: необязателен, Заключительный тег: необязателен

<!ATTLIST (THEAD|TBODY|TFOOT)          -- секция таблицы --
  %attrs;                              -- %coreattrs, %i18n, %events --
  %cellhalign;                         -- горизонтальное выравнивание в ячейках --
  %cellvalign;                         -- вертикальное выравнивание в ячейках --
  >

Атрибуты, совпадающие с атрибутами других элементов

Строки таблиц могут быть сгруппированы между верхним и нижним колонтитулами таблицы, а также в одну или большее количество секций тела таблицы, при помощи элементов THEAD, TFOOT и TBODY соответственно. Этот разделение дает возможность броузерам поддерживать прокрутку секций тела таблицы независимо от верхнего и нижнего колонтитулов таблицы. Когда длинные таблицы печатаются, верхний колонтитул таблицы, и информация нижнего колонтитула могут быть повторены на каждой странице, содержащей эту таблицу.

Верхний и нижний колонтитулы таблицы должны содержать информацию про столбцы таблицы. Тело таблицы таблицы должно содержать строки данных таблицы.

Если применяются элементы THEAD, TFOOT, и TBODY, то каждый из них должен содержать хотя бы одну строковую группу (row group). А каждая строковая группа должна иметь внутри себя по крайней мере одну строку, определенную элементом TR.

Этот пример иллюстрирует порядок методику использования колонтитулов и секций таблицы.

<TABLE>
<THEAD>
     <TR> ...header information...
</THEAD>
<TFOOT>
     <TR> ...footer information...
</TFOOT>
<TBODY>
     <TR> ...first row of block one data...
     <TR> ...second row of block one data...
</TBODY>
<TBODY>
     <TR> ...first row of block two data...
     <TR> ...second row of block two data...
     <TR> ...third row of block two data...
</TBODY>
</TABLE>

Элемент TFOOT должен находиться перед элементом TBODY, который определен внутри элемента TABLE, для того, чтобы броузер мог сформировать нижний колонтитул до скачивания всех строк таблицы, которых может быть очень много. Следующий список показывает, какие из тегов обязательны, а какие могут быть опущены:

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

Таблица из предыдущего примера может быть укорочена за счет удаления некоторых заключительных тегов так:

<TABLE>
<THEAD>
     <TR> ...header information...
<TFOOT>
     <TR> ...footer information...
<TBODY>
     <TR> ...first row of block one data...
     <TR> ...second row of block one data...
<TBODY>
     <TR> ...first row of block two data...
     <TR> ...second row of block two data...
     <TR> ...third row of block two data...
</TABLE>

В секциях элементов THEAD, TFOOT, и TBODY должно содержаться одинаковое количество столбцов.

11.2.4 Группировщики столбцов: элементы COLGROUP и COL

Column groups allow authors to create structural divisions within a table. Authors may highlight this structure through style sheets or HTML attributes (e.g., the rules attribute for the TABLE element). For an example of the visual presentation of column groups, please consult the sample table.

A table may either contain a single implicit column group (no COLGROUP element delimits the columns) or any number of explicit column groups (each delimited by an instance of the COLGROUP element).

The COL element allows authors to share attributes among several columns without implying any structural grouping. The "span" of the COL element is the number of columns that will share the element's attributes.

The COLGROUP element 

<!ELEMENT COLGROUP - O (col)*          -- table column group -->
<!ATTLIST COLGROUP
  %attrs;                              -- %coreattrs, %i18n, %events --
  span        NUMBER         1         -- default number of columns in group --
  width       %MultiLength;  #IMPLIED  -- default width for enclosed COLs --
  %cellhalign;                         -- horizontal alignment in cells --
  %cellvalign;                         -- vertical alignment in cells --
  >

Start tag: required, End tag: optional

Attribute definitions

span = number [CN]
This attribute, which must be an integer > 0, specifies the number of columns in a column group. Values mean the following:
  • In the absence of a span attribute, each COLGROUP defines a column group containing one column.
  • If the span attribute is set to N > 0, the current COLGROUP element defines a column group containing N columns.

User agents must ignore this attribute if the COLGROUP element contains one or more COL elements.

width = multi-length [CN]

This attribute specifies a default width for each column in the current column group. In addition to the standard pixel, percentage, and relative values, this attribute allows the special form "0*" (zero asterisk) which means that the width of the each column in the group should be the minimum width necessary to hold the column's contents. This implies that a column's entire contents must be known before its width may be correctly computed. Authors should be aware that specifying "0*" will prevent visual user agents from rendering a table incrementally.

This attribute is overridden for any column in the column group whose width is specified via a COL element.

Attributes defined elsewhere

The COLGROUP element creates an explicit column group. The number of columns in the column group may be specified in two, mutually exclusive ways:

  1. The element's span attribute (default value 1) specifies the number of columns in the group.
  2. Each COL element in the COLGROUP represents one or more columns in the group.

The advantage of using the span attribute is that authors may group together information about column widths. Thus, if a table contains forty columns, all of which have a width of 20 pixels, it is easier to write:

   <COLGROUP span="40" width="20">
   </COLGROUP>

than:

   <COLGROUP>
      <COL width="20">
      <COL width="20">
      ...a total of forty COL elements...
   </COLGROUP>

When it is necessary to single out a column (e.g., for style information, to specify width information, etc.) within a group, authors must identify that column with a COL element. Thus, to apply special style information to the last column of the previous table, we single it out as follows:

   <COLGROUP width="20">
      <COL span="39">
      <COL id="format-me-specially">
   </COLGROUP>

The width attribute of the COLGROUP element is inherited by all 40 columns. The first COL element refers to the first 39 columns (doing nothing special to them) and the second one assigns an id value to the fortieth columns so that style sheets may refer to it.

The table in the following example contains two column groups. The first column group contains 10 columns and the second contains 5 columns. The default width for each column in the first column group is 50 pixels. The width of each column in the second column group will be the minimum required for that column.

<TABLE>
<COLGROUP span="10" width="50">
<COLGROUP span="5" width="0*">
<THEAD>
<TR><TD> ...
</TABLE>

The COL element 

<!ELEMENT COL      - O EMPTY           -- table column -->
<!ATTLIST COL                          -- column groups and properties --
  %attrs;                              -- %coreattrs, %i18n, %events --
  span        NUMBER         1         -- COL attributes affect N columns --
  width       %MultiLength;  #IMPLIED  -- column width specification --
  %cellhalign;                         -- horizontal alignment in cells --
  %cellvalign;                         -- vertical alignment in cells --
  >

Start tag: required, End tag: forbidden

Attribute definitions

span = number [CN]
This attribute, whose value must be an integer > 0, specifies the number of columns "spanned" by the COL element; the COL element shares its attributes with all the columns it spans. The default value for this attribute is 1 (i.e., the COL element refers to a single column). If the span attribute is set to N > 1, the current COL element shares its attributes with the next N-1 columns.
width = multi-length [CN]
This attribute specifies a default width for each column spanned by the current COL element. It has the same meaning as the width attribute for the COLGROUP element and overrides it.

Attributes defined elsewhere

The COL element allows authors to group together attribute specifications for table columns. The COL does not group columns together structurally -- that is the role of the COLGROUP element. COL elements are empty and serve only as a support for attributes. They may appear inside or outside an explicit column group (i.e., COLGROUP element).

The width attribute for COL refers to the width of each column in the element's span.

Calculating the number of columns in a table 

There are two ways to determine the number of columns in a table (in order of precedence):

  1. If the TABLE element contains any COLGROUP or COL elements, user agents should calculate the number of columns by summing the following:
  2. Otherwise, if the TABLE element contains no COLGROUP or COL elements, user agents should base the number of columns on what is required by the rows. The number of columns is equal to the number of columns required by the row with the most columns, including cells that span multiple columns. For any row that has fewer than this number of columns, the end of that row should be padded with empty cells. The "end" of a row depends on the table directionality.

It is an error if a table contains COLGROUP or COL elements and the two calculations do not result in the same number of columns.

Once the user agent has calculated the number of columns in the table, it may group them into column groups.

For example, for each of the following tables, the two column calculation methods should result in three columns. The first three tables may be rendered incrementally.

<TABLE>
<COLGROUP span="3"></COLGROUP>
<TR><TD> ...
...rows...
</TABLE>

<TABLE>
<COLGROUP>
<COL>
<COL span="2">
</COLGROUP>
<TR><TD> ...
...rows...
</TABLE>

<TABLE>
<COLGROUP>
<COL>
</COLGROUP>
<COLGROUP span="2">
<TR><TD> ...
...rows...
</TABLE>

<TABLE>
<TR>
  <TD><TD><TD>
</TR>
</TABLE>

Calculating the width of columns 

Authors may specify column widths in three ways:

Fixed
A fixed width specification is given in pixels (e.g., width="30"). A fixed-width specification enables incremental rendering.
Percentage
A percentage specification (e.g., width="20%") is based on the percentage of the horizontal space available to the table (between the current left and right margins, including floats). Note that this space does not depend on the table itself, and thus percentage specifications enable incremental rendering.
Proportional
Proportional specifications (e.g., width="3*") refer to portions of the horizontal space required by a table. If the table width is given a fixed value via the width attribute of the TABLE element, user agents may render the table incrementally even with proportional columns.

However, if the table does not have a fixed width, user agents must receive all table data before they can determine the horizontal space required by the table. Only then may this space be allotted to proportional columns.

If an author specifies no width information for a column, a user agent may not be able to incrementally format the table since it must wait for the entire column of data to arrive in order to allot an appropriate width.

If column widths prove to be too narrow for the contents of a particular table cell, user agents may choose to reflow the table.

The table in this example contains six columns. The first one does not belong to an explicit column group. The next three belong to the first explicit column group and the last two belong to the second explicit column group. This table cannot be formatted incrementally since it contains proportional column width specifications and no value for the width attribute for the TABLE element.

Once the (visual) user agent has received the table's data: the available horizontal space will be alloted by the user agent as follows: First the user agent will allot 30 pixels to columns one and two. Then, the minimal space required for the third column will be reserved. The remaining horizontal space will be divided into six equal portions (since 2* + 1* + 3* = 6 portions). Column four (2*) will receive two of these portions, column five (1*) will receive one, and column six (3*) will receive three.

    
<TABLE>
<COLGROUP>
   <COL width="30">
<COLGROUP>
   <COL width="30">
   <COL width="0*">
   <COL width="2*">
<COLGROUP align="center">
   <COL width="1*">
   <COL width="3*" align="char" char=":">
<THEAD>
<TR><TD> ...
...rows...
</TABLE>

We have set the value of the align attribute in the third column group to "center". All cells in every column in this group will inherit this value, but may override it. In fact, the final COL does just that, by specifying that every cell in the column it governs will be aligned along the ":" character.

In the following table, the column width specifications allow the user agent to format the table incrementally:

    
<TABLE width="200">
<COLGROUP span="10" width="15">
<COLGROUP width="*">
   <COL id="penultimate-column">
   <COL id="last-column">
<THEAD>
<TR><TD> ...
...rows...
</TABLE>

The first ten columns will be 15 pixels wide each. The last two columns will each receive half of the remaining 50 pixels. Note that the COL elements appear only so that an id value may be specified for the last two columns.

Note. Although the width attribute on the TABLE element is not deprecated, authors are encouraged to use style sheets to specify table widths.

11.2.5 Table rows: The TR element

<!ELEMENT TR       - O (TH|TD)+        -- table row -->
<!ATTLIST TR                           -- table row --
  %attrs;                              -- %coreattrs, %i18n, %events --
  %cellhalign;                         -- horizontal alignment in cells --
  %cellvalign;                         -- vertical alignment in cells --
  >

Start tag: required, End tag: optional

Attributes defined elsewhere

The TR elements acts as a container for a row of table cells. The end tag may be omitted.

This sample table contains three rows, each begun by the TR element:

<TABLE summary="This table charts the number of cups
                   of coffee consumed by each senator, the type 
                   of coffee (decaf or regular), and whether 
                   taken with sugar.">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR> ...A header row...
<TR> ...First row of data...
<TR> ...Second row of data...
...the rest of the table...
</TABLE>

11.2.6 Table cells: The TH and TD elements

<!ELEMENT (TH|TD)  - O (%flow;)*       -- table header cell, table data cell-->

<!-- Scope is simpler than axes attribute for common tables -->
<!ENTITY % Scope "(row|col|rowgroup|colgroup)">

<!-- TH is for headers, TD for data, but for cells acting as both use TD -->
<!ATTLIST (TH|TD)                      -- header or data cell --
  %attrs;                              -- %coreattrs, %i18n, %events --
  abbr        %Text;         #IMPLIED  -- abbreviation for header cell --
  axis        CDATA          #IMPLIED  -- names groups of related headers--
  headers     IDREFS         #IMPLIED  -- list of id's for header cells --
  scope       %Scope;        #IMPLIED  -- scope covered by header cells --
  rowspan     NUMBER         1         -- number of rows spanned by cell --
  colspan     NUMBER         1         -- number of cols spanned by cell --
  %cellhalign;                         -- horizontal alignment in cells --
  %cellvalign;                         -- vertical alignment in cells --
  >

Start tag: required, End tag: optional

Attribute definitions

headers = idrefs [CS]
This attribute specifies the list of header cells that provide header information for the current data cell. The value of this attribute is a space-separated list of cell names; those cells must be named by setting their id attribute. Authors generally use the headers attribute to help non-visual user agents render header information about data cells (e.g., header information is spoken prior to the cell data), but the attribute may also be used in conjunction with style sheets. See also the scope attribute.
scope = scope-name [CI]
This attribute specifies the set of data cells for which the current header cell provides header information. This attribute may be used in place of the headers attribute, particularly for simple tables. When specified, this attribute must have one of the following values:
  • row: The current cell provides header information for the rest of the row that contains it (see also the section on table directionality).
  • col: The current cell provides header information for the rest of the column that contains it.
  • rowgroup: The header cell provides header information for the rest of the row group that contains it.
  • colgroup: The header cell provides header information for the rest of the column group that contains it.
abbr = text [CS]
This attribute should be used to provide an abbreviated form of the cell's content, and may be rendered by user agents when appropriate in place of the cell's content. Abbreviated names should be short since user agents may render them repeatedly. For instance, speech synthesizers may render the abbreviated headers relating to a particular cell before rendering that cell's content.
axis = cdata [CI]
This attribute may be used to place a cell into conceptual categories that can be considered to form axes in an n-dimensional space. User agents may give users access to these categories (e.g., the user may query the user agent for all cells that belong to certain categories, the user agent may present a table in the form of a table of contents, etc.). Please consult the section on categorizing cells for more information. The value of this attribute is a comma-separated list of category names.
rowspan = number [CN]
This attribute specifies the number of rows spanned by the current cell. The default value of this attribute is one ("1"). The value zero ("0") means that the cell spans all rows from the current row to the last row of the table.
colspan = number [CN]
This attribute specifies the number of columns spanned by the current cell. The default value of this attribute is one ("1"). The value zero ("0") means that the cell spans all columns from the current column to the last column of the table.
nowrap [CI]
Deprecated. When present, this boolean attribute tells visual user agents to disable automatic text wrapping for this cell. Style sheets should be used instead of this attribute to achieve wrapping effects. Note. if used carelessly, this attribute may result in excessively wide cells.
width = pixels [CN]
Deprecated. This attribute supplies user agents with a recommended cell width.
height = pixels [CN]
Deprecated. This attribute supplies user agents with a recommended cell height.

Attributes defined elsewhere

Table cells may contain two types of information: header information and data. This distinction enables user agents to render header and data cells distinctly, even in the absence of style sheets. For example, visual user agents may present header cell text with a bold font. Speech synthesizers may render header information with a distinct voice inflection.

The TH element defines a cell that contains header information. User agents have two pieces of header information available: the contents of the TH element and the value of the abbr attribute. User agents must render either the contents of the cell or the value of the abbr attribute. For visual media, the latter may be appropriate when there is insufficient space to render the full contents of the cell. For non-visual media abbr may be used as an abbreviation for table headers when these are rendered along with the contents of the cells to which they apply.

The headers and scope attributes also allow authors to help non-visual user agents process header information. Please consult the section on labeling cells for non-visual user agents for information and examples.

The TD element defines a cell that contains data.

Cells may be empty (i.e., contain no data).

For example, the following table contains four columns of data, each headed by a column description.

<TABLE summary="This table charts the number of cups
                   of coffee consumed by each senator, the type 
                   of coffee (decaf or regular), and whether 
                   taken with sugar.">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR>
   <TH>Name</TH>
   <TH>Cups</TH>
   <TH>Type of Coffee</TH>
   <TH>Sugar?</TH>
<TR>
   <TD>T. Sexton</TD>
   <TD>10</TD>
   <TD>Espresso</TD>
   <TD>No</TD>
<TR>
   <TD>J. Dinnen</TD>
   <TD>5</TD>
   <TD>Decaf</TD>
   <TD>Yes</TD>
</TABLE>

A user agent rendering to a tty device might display this as follows:

Name         Cups       Type of Coffee   Sugar?
T. Sexton    10         Espresso         No
J. Dinnen    5          Decaf            Yes

Cells that span several rows or columns 

Cells may span several rows or columns. The number of rows or columns spanned by a cell is set by the rowspan and colspan attributes for the TH and TD elements.

In this table definition, we specify that the cell in row four, column two should span a total of three columns, including the current column.

<TABLE border="1">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR><TH>Name<TH>Cups<TH>Type of Coffee<TH>Sugar?
<TR><TD>T. Sexton<TD>10<TD>Espresso<TD>No
<TR><TD>J. Dinnen<TD>5<TD>Decaf<TD>Yes
<TR><TD>A. Soria<TD colspan="3"><em>Not available</em>
</TABLE>

This table might be rendered on a tty device by a visual user agent as follows:

Cups of coffee consumed by each senator
 --------------------------------------
 |   Name  |Cups|Type of Coffee|Sugar?|
 --------------------------------------
 |T. Sexton|10  |Espresso      |No    |
 --------------------------------------
 |J. Dinnen|5   |Decaf         |Yes   |
 --------------------------------------
 |A. Soria |Not available             |
 --------------------------------------

The next example illustrates (with the help of table borders) how cell definitions that span more than one row or column affect the definition of later cells. Consider the following table definition:

<TABLE border="1">
<TR><TD>1 <TD rowspan="2">2 <TD>3
<TR><TD>4 <TD>6
<TR><TD>7 <TD>8 <TD>9
</TABLE>

As cell "2" spans the first and second rows, the definition of the second row will take it into account. Thus, the second TD in row two actually defines the row's third cell. Visually, the table might be rendered to a tty device as:

-------------
| 1 | 2 | 3 | 
----|   |----
| 4 |   | 6 |
----|---|----
| 7 | 8 | 9 |
-------------

while a graphical user agent might render this as:

Image of a table with rowspan=2

Note that if the TD defining cell "6" had been omitted, an extra empty cell would have been added by the user agent to complete the row.

Similarly, in the following table definition:

<TABLE border="1">
<TR><TD>1 <TD>2 <TD>3
<TR><TD colspan="2">4 <TD>6
<TR><TD>7 <TD>8 <TD>9
</TABLE>

cell "4" spans two columns, so the second TD in the row actually defines the third cell ("6"):

-------------
| 1 | 2 | 3 | 
--------|----
| 4     | 6 |
--------|----
| 7 | 8 | 9 |
-------------

A graphical user agent might render this as:

Image of a table with colspan=2

Defining overlapping cells is an error. User agents may vary in how they handle this error (e.g., rendering may vary).

The following illegal example illustrates how one might create overlapping cells. In this table, cell "5" spans two rows and cell "7" spans two columns, so there is overlap in the cell between "7" and "9":

<TABLE border="1">
<TR><TD>1 <TD>2 <TD>3
<TR><TD>4 <TD rowspan="2">5 <TD>6
<TR><TD colspan="2">7 <TD>9
</TABLE>

11.3 Table formatting by visual user agents

Note. The following sections describe the HTML table attributes that concern visual formatting. Although style sheets will offer better control of visual table formatting, at the writing of this specification, [CSS1] did not offer mechanisms to control all aspects of visual table formatting.

HTML 4.0 includes mechanisms to control:

11.3.1 Borders and rules

The following attributes affect a table's external frame and internal rules.

Attribute definitions

frame = void|above|below|hsides|lhs|rhs|vsides|box|border [CI]
This attribute specifies which sides of the frame that surrounds a table will be visible. Possible values:
  • void: No sides. This is the default value.
  • above: The top side only.
  • below: The bottom side only.
  • hsides: The top and bottom sides only.
  • vsides: The right and left sides only.
  • lhs: The left-hand side only.
  • rhs: The right-hand side only.
  • box: All four sides.
  • border: All four sides.
rules = none|groups|rows|cols|all [CI]
This attribute specifies which rules will appear between cells within a table. The rendering of rules is user agent dependent. Possible values:
  • none: No rules. This is the default value.
  • groups: Rules will appear between row groups (see THEAD, TFOOT, and TBODY) and column groups (see COLGROUP and COL) only.
  • rows: Rules will appear between rows only.
  • cols: Rules will appear between columns only.
  • all: Rules will appear between all rows and columns.
border = pixels [CN]
This attributes specifies the width (in pixels only) of the frame around a table (see the Note below for more information about this attribute).

To help distinguish the cells of a table, we can set the border attribute of the TABLE element. Consider a previous example:

<TABLE border="1" 
       summary="This table charts the number of cups
                of coffee consumed by each senator, the type 
                of coffee (decaf or regular), and whether 
                taken with sugar.">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR>
   <TH>Name</TH>
   <TH>Cups</TH>
   <TH>Type of Coffee</TH>
   <TH>Sugar?</TH>
<TR>
   <TD>T. Sexton</TD>
   <TD>10</TD>
   <TD>Espresso</TD>
   <TD>No</TD>
<TR>
   <TD>J. Dinnen</TD>
   <TD>5</TD>
   <TD>Decaf</TD>
   <TD>Yes</TD>
</TABLE>

In the following example, the user agent should show borders five pixels thick on the left-hand and right-hand sides of the table, with rules drawn between each column.

<TABLE border="5" frame="vsides" rules="cols">
<TR> <TD>1 <TD>2 <TD>3
<TR> <TD>4 <TD>5 <TD>6
<TR> <TD>7 <TD>8 <TD>9
</TABLE>

The following settings should be observed by user agents for backwards compatibility.

For example, the following definitions are equivalent:

<TABLE border="2">
<TABLE border="2" frame="border" rules="all">

as are the following:

<TABLE border>
<TABLE frame="border" rules="all">

Note. The border attribute also defines the border behavior for the OBJECT and IMG elements, but takes different values for those elements.

11.3.2 Horizontal and vertical alignment

The following attributes may be set for different table elements (see their definitions).

<!-- horizontal alignment attributes for cell contents -->
<!ENTITY % cellhalign
  "align      (left|center|right|justify|char) #IMPLIED
   char       %Character;    #IMPLIED  -- alignment char, e.g. char=':' --
   charoff    %Length;       #IMPLIED  -- offset for alignment char --"
  >
<!-- vertical alignment attributes for cell contents -->
<!ENTITY % cellvalign
  "valign     (top|middle|bottom|baseline) #IMPLIED"
  >

Attribute definitions

align = left|center|right|justify|char [CI]
This attribute specifies the alignment of data and the justification of text in a cell. Possible values:
  • left: Left-flush data/Left-justify text. This is the default value for table data.
  • center: Center data/Center-justify text. This is the default value for table headers.
  • right: Right-flush data/Right-justify text.
  • justify: Double-justify text.
  • char: Align text around a specific character.
valign = top|middle|bottom|baseline [CI]
This attribute specifies the vertical position of data within a cell. Possible values:
  • top: Cell data is flush with the top of the cell.
  • middle: Cell data is centered vertically within the cell. This is the default value.
  • bottom: Cell data is flush with the bottom of the cell.
  • baseline: All cells in the same row as a cell whose valign attribute has this value should have their textual data positioned so that the first text line occurs on a baseline common to all cells in the row. This constraint does not apply to subsequent text lines in these cells.
char = character [CN]
This attribute specifies a single character within a text fragment to act as an axis for alignment. The default value for this attribute is the decimal point character for the current language as set by the lang attribute (e.g., the period (".") in English and the comma (",") in French). User agents are not required to support this attribute.
charoff = length [CN]
When present, this attribute specifies the offset to the first occurrence of the alignment character on each line. If a line doesn't include the alignment character, it should be horizontally shifted to end at the alignment position.

When charoff is used to set the offset of an alignment character, the direction of offset is determined by the current text direction (set by the dir attribute). In left-to-right texts (the default), offset is from the left margin. In right-to-left texts, offset is from the right margin. User agents are not required to support this attribute.

The table in this example aligns a row of currency values along a decimal point. We set the alignment character to "." explicitly.

<TABLE border="1">
<COLGROUP>
<COL><COL align="char" char=".">
<THEAD>
<TR><TH>Vegetable <TH>Cost per kilo
<TBODY>
<TR><TD>Lettuce        <TD>$1
<TR><TD>Silver carrots <TD>$10.50
<TR><TD>Golden turnips <TD>$100.30
</TABLE>

The formatted table may resemble the following:

------------------------------
|   Vegetable  |Cost per kilo|
|--------------|-------------|
|Lettuce       |        $1   |
|--------------|-------------|
|Silver carrots|       $10.50|
|--------------|-------------|
|Golden turnips|      $100.30|
------------------------------

When the contents of a cell contain more than one instance of the alignment character specified by char and the contents wrap, user agent behavior is undefined. Authors should therefore be attentive in their use of char.

Note. Visual user agents typically render TH elements vertically and horizontally centered within the cell and with a bold font weight.

Inheritance of alignment specifications 

The alignment of cell contents can be specified on a cell by cell basis, or inherited from enclosing elements, such as the row, column or the table itself.

The order of precedence (from highest to lowest) for the attributes align, char, and charoff is the following:

  1. An alignment attribute set on an element within a cell's data (e.g., P).
  2. An alignment attribute set on a cell (TH and TD).
  3. An alignment attribute set on a column grouping element (COL and COLGROUP). When a cell is part of a multi-column span, the alignment property is inherited from the cell definition at the beginning of the span.
  4. An alignment attribute set on a row or row grouping element (TR, THEAD, TFOOT, and TBODY). When a cell is part of a multi-row span, the alignment property is inherited from the cell definition at the beginning of the span.
  5. An alignment attribute set on the table (TABLE).
  6. The default alignment value.

The order of precedence (from highest to lowest) for the attribute valign (as well as the other inherited attributes lang, dir, and style) is the following:

  1. An attribute set on an element within a cell's data (e.g., P).
  2. An attribute set on a cell (TH and TD).
  3. An attribute set on a row or row grouping element (TR, THEAD, TFOOT, and TBODY). When a cell is part of a multi-row span, the attribute value is inherited from the cell definition at the beginning of the span.
  4. An attribute set on a column grouping element (COL and COLGROUP). When a cell is part of a multi-column span, the attribute value is inherited from the cell definition at the beginning of the span.
  5. An attribute set on the table (TABLE).
  6. The default attribute value.

Furthermore, when rendering cells, horizontal alignment is determined by columns in preference to rows, while for vertical alignment, rows are given preference over columns.

The default alignment for cells depends on the user agent. However, user agents should substitute the default attribute for the current directionality (i.e., not just "left" in all cases).

User agents that do not support the "justify" value of the align attribute should use the value of the inherited directionality in its place.

Note. Note that a cell may inherit an attribute not from its parent but from the first cell in a span. This is an exception to the general attribute inheritance rules.

11.3.3 Cell margins

Attribute definitions

cellspacing = length [CN]
This attribute specifies how much space the user agent should leave between the left side of the table and the left-hand side of the leftmost column, the top of the table and the top side of the topmost row, and so on for the right and bottom of the table. The attribute also specifies the amount of space to leave between cells.
cellpadding = length [CN]
This attribute specifies the amount of space between the border of the cell and its contents. If the value of this attribute is a pixel length, all four margins should be this distance from the contents. If the value of the attribute is a percentage length, the top and bottom margins should be equally separated from the content based on a percentage of the available vertical space, and the left and right margins should be equally separated from the content based on a percentage of the available horizontal space.

These two attributes control spacing between and within cells. The following illustration explains how they relate:

Image illustrating how cellspacing and cellpadding attributes relate.

In the following example, the cellspacing attribute specifies that cells should be separated from each other and from the table frame by twenty pixels. The cellpadding attribute specifies that the top margin of the cell and the bottom margin of the cell will each be separated from the cell's contents by 10% of the available vertical space (the total being 20%). Similarly, the left margin of the cell and the right margin of the cell will each be separated from the cell's contents by 10% of the available horizontal space (the total being 20%).

<TABLE cellspacing="20" cellpadding="20%">
<TR> <TD>Data1 <TD>Data2 <TD>Data3
</TABLE>

If a table or given column has a fixed width, cellspacing and cellpadding may demand more space than assigned. User agents may give these attributes precedence over the width attribute when a conflict occurs, but are not required to.

11.4 Table rendering by non-visual user agents

11.4.1 Associating header information with data cells

Non-visual user agents such as speech synthesizers and Braille-based devices may use the following TD and TH element attributes to render table cells more intuitively:

In the following example, we assign header information to cells by setting the headers attribute. Each cell in the same column refers to the same header cell (via the id attribute).

<TABLE border="1" 
       summary="This table charts the number of cups
                of coffee consumed by each senator, the type 
                of coffee (decaf or regular), and whether 
                taken with sugar.">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR>
   <TH id="t1">Name</TH>
   <TH id="t2">Cups</TH>
   <TH id="t3" abbr="Type">Type of Coffee</TH>
   <TH id="t4">Sugar?</TH>
<TR>
   <TD headers="t1">T. Sexton</TD>
   <TD headers="t2">10</TD>
   <TD headers="t3">Espresso</TD>
   <TD headers="t4">No</TD>
<TR>
   <TD headers="t1">J. Dinnen</TD>
   <TD headers="t2">5</TD>
   <TD headers="t3">Decaf</TD>
   <TD headers="t4">Yes</TD>
</TABLE>

A speech synthesizer might render this table as follows:

Caption: Cups of coffee consumed by each senator
Summary: This table charts the number of cups
         of coffee consumed by each senator, the type 
         of coffee (decaf or regular), and whether 
         taken with sugar.
Name: T. Sexton,   Cups: 10,   Type: Espresso,   Sugar: No
Name: J. Dinnen,   Cups: 5,    Type: Decaf,      Sugar: Yes

Note how the header "Type of Coffee" is abbreviated to "Type" using the abbr attribute.

Here is the same example substituting the scope attribute for the headers attribute. Note the value "col" for the scope attribute, meaning "all cells in the current column":

<TABLE border="1" 
       summary="This table charts the number of cups
                of coffee consumed by each senator, the type 
                of coffee (decaf or regular), and whether 
                taken with sugar.">
<CAPTION>Cups of coffee consumed by each senator</CAPTION>
<TR>
   <TH scope="col">Name</TH>
   <TH scope="col">Cups</TH>
   <TH scope="col" abbr="Type">Type of Coffee</TH>
   <TH scope="col">Sugar?</TH>
<TR>
   <TD>T. Sexton</TD>
   <TD>10</TD>
   <TD>Espresso</TD>
   <TD>No</TD>
<TR>
   <TD>J. Dinnen</TD>
   <TD>5</TD>
   <TD>Decaf</TD>
   <TD>Yes</TD>
</TABLE>

Here's a somewhat more complex example illustrating other values for the scope attribute:

<TABLE border="1" cellpadding="5" cellspacing="2"
  summary="History courses offered in the community of
           Bath arranged by course name, tutor, summary, 
           code, and fee">
  <TR>
    <TH colspan="5" scope="colgroup">Community Courses -- Bath Autumn 1997</TH>
  </TR>
  <TR>
    <TH scope="col" abbr="Name">Course Name</TH>
    <TH scope="col" abbr="Tutor">Course Tutor</TH>
    <TH scope="col">Summary</TH>
    <TH scope="col">Code</TH>
    <TH scope="col">Fee</TH>
  </TR>
  <TR>
    <TD scope="row">After the Civil War</TD>
    <TD>Dr. John Wroughton</TD>
    <TD>
       The course will examine the turbulent years in England
       after 1646. <EM>6 weekly meetings starting Monday 13th
      October.</EM>
    </TD>
    <TD>H27</TD>
    <TD>&pound;32</TD>
  </TR>
  <TR>
    <TD scope="row">An Introduction to Anglo-Saxon England</TD>
    <TD>Mark Cottle</TD>
    <TD>
       One day course introducing the early medieval
       period reconstruction the Anglo-Saxons and
       their society. <EM>Saturday 18th October.</EM>
    </TD>
    <TD>H28</TD>
    <TD>&pound;18</TD>
  </TR>
  <TR>
    <TD scope="row">The Glory that was Greece</TD>
    <TD>Valerie Lorenz</TD>
    <TD>
     Birthplace of democracy, philosophy, heartland of theater, home of
     argument. The Romans may have done it but the Greeks did it
     first. <EM>Saturday day school 25th October 1997</EM>
    </TD>
    <TD>H30</TD>
    <TD>&pound;18</TD>
  </TR>
</TABLE>

A graphical user agent might render this as:

A table with merged cells

Note the use of the scope attribute with the "row" value. Although the first cell in each row contains data, not header information, the scope attribute makes the data cell behave like a row header cell. This allows speech synthesizers to provide the relevant course name upon request or to state it immediately before each cell's content.

11.4.2 Categorizing cells

Users browsing a table with a speech-based user agent may wish to hear an explanation of a cell's contents in addition to the contents themselves. One way the user might provide an explanation is by speaking associated header information before speaking the data cell's contents (see the section on associating header information with data cells).

Users may also want information about more than one cell, in which case header information provided at the cell level (by headers, scope, and abbr) may not provide adequate context. Consider the following table, which classifies expenses for meals, hotels, and transport in two locations (San Jose and Seattle) over several days:

Image of a table listing travel expenses at two locations: San Jose and Seattle, by date, and category (meals, hotels, and transport), shown with subtitles

Users might want to extract information from the table in the form of queries:

Each query involves a computation by the user agent that may involve zero or more cells. In order to determine, for example, the costs of meals on 25 August, the user agent must know which table cells refer to "Meals" (all of them) and which refer to "Dates" (specifically, 25 August), and find the intersection of the two sets.

To accommodate this type of query, the HTML 4.0 table model allows authors to place cell headers and data into categories. For example, for the travel expense table, an author could group the header cells "San Jose" and "Seattle" into the category "Location", the headers "Meals", "Hotels", and "Transport" in the category "Expenses", and the four days into the category "Date". The previous three questions would then have the following meanings:

Authors categorize a header or data cell by setting the axis attribute for the cell. For instance, in the travel expense table, the cell containing the information "San Jose" could be placed in the "Location" category as follows:

  <TH id="a6" axis="location">San Jose</TH>

Any cell containing information related to "San Jose" should refer to this header cell via either the headers or the scope attribute. Thus, meal expenses for 25-Aug-1997 should be marked up to refer to id attribute (whose value here is "a6") of the "San Jose" header cell:

  
  <TD headers="a6">37.74</TD>

Each headers attribute provides a list of id references. Authors may thus categorize a given cell in any number of ways (or, along any number of "headers", hence the name).

Below we mark up the travel expense table with category information:

<TABLE border="1"
          summary="This table summarizes travel expenses
                   incurred during August trips to
                   San Jose and Seattle">
<CAPTION>
  Travel Expense Report
</CAPTION>
<TR>
  <TH></TH>
  <TH id="a2" axis="expenses">Meals</TH>
  <TH id="a3" axis="expenses">Hotels</TH>
  <TH id="a4" axis="expenses">Transport</TH>
  <TD>subtotals</TD>
</TR>
<TR>
  <TH id="a6" axis="location">San Jose</TH>
  <TH></TH>
  <TH></TH>
  <TH></TH>
  <TD></TD>
</TR>
<TR>
  <TD id="a7" axis="date">25-Aug-97</TD>
  <TD headers="a6 a7 a2">37.74</TD>
  <TD headers="a6 a7 a3">112.00</TD>
  <TD headers="a6 a7 a4">45.00</TD>
  <TD></TD>
</TR>
<TR>
  <TD id="a8" axis="date">26-Aug-97</TD>
  <TD headers="a6 a8 a2">27.28</TD>
  <TD headers="a6 a8 a3">112.00</TD>
  <TD headers="a6 a8 a4">45.00</TD>
  <TD></TD>
</TR>
<TR>
  <TD>subtotals</TD>
  <TD>65.02</TD>
  <TD>224.00</TD>
  <TD>90.00</TD>
  <TD>379.02</TD>
</TR>
<TR>
  <TH id="a10" axis="location">Seattle</TH>
  <TH></TH>
  <TH></TH>
  <TH></TH>
  <TD></TD>
</TR>
<TR>
  <TD id="a11" axis="date">27-Aug-97</TD>
  <TD headers="a10 a11 a2">96.25</TD>
  <TD headers="a10 a11 a3">109.00</TD>
  <TD headers="a10 a11 a4">36.00</TD>
  <TD></TD>
</TR>
<TR>
  <TD id="a12" axis="date">28-Aug-97</TD>
  <TD headers="a10 a12 a2">35.00</TD>
  <TD headers="a10 a12 a3">109.00</TD>
  <TD headers="a10 a12 a4">36.00</TD>
  <TD></TD>
</TR>
<TR>
  <TD>subtotals</TD>
  <TD>131.25</TD>
  <TD>218.00</TD>
  <TD>72.00</TD>
  <TD>421.25</TD>
</TR>
<TR>
  <TH>Totals</TH>
  <TD>196.27</TD>
  <TD>442.00</TD>
  <TD>162.00</TD>
  <TD>800.27</TD>
</TR>
</TABLE>

Note that marking up the table this way also allows user agents to avoid confusing the user with unwanted information. For instance, if a speech synthesizer were to speak all of the figures in the "Meals" column of this table in response to the query "What were all my meal expenses?", a user would not be able to distinguish a day's expenses from subtotals or totals. By carefully categorizing cell data, authors allow user agents to make important semantic distinctions when rendering.

Of course, there is no limit to how authors may categorize information in a table. In the travel expense table, for example, we could add the additional categories "subtotals" and "totals".

This specification does not require user agents to handle information provided by the axis attribute, nor does it make any recommendations about how user agents may present axis information to users or how users may query the user agent about this information.

However, user agents, particularly speech synthesizers, may want to factor out information common to several cells that are the result of a query. For instance, if the user asks "What did I spend for meals in San Jose?", the user agent would first determine the cells in question (25-Aug-1997: 37.74, 26-Aug-1997:27.28), then render this information. A user agent speaking this information might read it:

   Location: San Jose. Date: 25-Aug-1997. Expenses, Meals: 37.74
   Location: San Jose. Date: 26-Aug-1997. Expenses, Meals: 27.28

or, more compactly:

   San Jose, 25-Aug-1997, Meals: 37.74
   San Jose, 26-Aug-1997, Meals: 27.28

An even more economical rendering would factor the common information and reorder it:

   San Jose, Meals, 25-Aug-1997: 37.74
                    26-Aug-1997: 27.28

User agents that support this type of rendering should allow user agents a means to customize rendering (e.g., through style sheets).

11.4.3 Algorithm to find heading information

In the absence of header information from either the scope or headers attribute, user agents may construct header information according to the following algorithm. The goal of the algorithm is to find an ordered list of headers. (In the following description of the algorithm the table directionality is assumed to be left-to-right.)

11.5 Sample table

This sample illustrates grouped rows and columns. The example is adapted from "Developing International Software", by Nadine Kano.

In "ascii art", the following table:

<TABLE border="2" frame="hsides" rules="groups"
          summary="Code page support in different versions
                   of MS Windows.">
<CAPTION>CODE-PAGE SUPPORT IN MICROSOFT WINDOWS</CAPTION>
<COLGROUP align="center">
<COLGROUP align="left">
<COLGROUP align="center" span="2">
<COLGROUP align="center" span="3">
<THEAD valign="top">
<TR>
<TH>Code-Page<BR>ID
<TH>Name
<TH>ACP
<TH>OEMCP
<TH>Windows<BR>NT 3.1
<TH>Windows<BR>NT 3.51
<TH>Windows<BR>95
<TBODY>
<TR><TD>1200<TD>Unicode (BMP of ISO/IEC-10646)<TD><TD><TD>X<TD>X<TD>*
<TR><TD>1250<TD>Windows 3.1 Eastern European<TD>X<TD><TD>X<TD>X<TD>X
<TR><TD>1251<TD>Windows 3.1 Cyrillic<TD>X<TD><TD>X<TD>X<TD>X
<TR><TD>1252<TD>Windows 3.1 US (ANSI)<TD>X<TD><TD>X<TD>X<TD>X
<TR><TD>1253<TD>Windows 3.1 Greek<TD>X<TD><TD>X<TD>X<TD>X
<TR><TD>1254<TD>Windows 3.1 Turkish<TD>X<TD><TD>X<TD>X<TD>X
<TR><TD>1255<TD>Hebrew<TD>X<TD><TD><TD><TD>X
<TR><TD>1256<TD>Arabic<TD>X<TD><TD><TD><TD>X
<TR><TD>1257<TD>Baltic<TD>X<TD><TD><TD><TD>X
<TR><TD>1361<TD>Korean (Johab)<TD>X<TD><TD><TD>**<TD>X
<TBODY>
<TR><TD>437<TD>MS-DOS United States<TD><TD>X<TD>X<TD>X<TD>X
<TR><TD>708<TD>Arabic (ASMO 708)<TD><TD>X<TD><TD><TD>X
<TR><TD>709<TD>Arabic (ASMO 449+, BCON V4)<TD><TD>X<TD><TD><TD>X
<TR><TD>710<TD>Arabic (Transparent Arabic)<TD><TD>X<TD><TD><TD>X
<TR><TD>720<TD>Arabic (Transparent ASMO)<TD><TD>X<TD><TD><TD>X
</TABLE>

would be rendered something like this:

                  CODE-PAGE SUPPORT IN MICROSOFT WINDOWS
===============================================================================
Code-Page | Name                         | ACP  OEMCP | Windows Windows Windows
    ID    |                              |            |  NT 3.1 NT 3.51    95
-------------------------------------------------------------------------------
   1200   | Unicode (BMP of ISO 10646)   |            |    X       X       *
   1250   | Windows 3.1 Eastern European |  X         |    X       X       X
   1251   | Windows 3.1 Cyrillic         |  X         |    X       X       X
   1252   | Windows 3.1 US (ANSI)        |  X         |    X       X       X
   1253   | Windows 3.1 Greek            |  X         |    X       X       X
   1254   | Windows 3.1 Turkish          |  X         |    X       X       X
   1255   | Hebrew                       |  X         |                    X
   1256   | Arabic                       |  X         |                    X
   1257   | Baltic                       |  X         |                    X
   1361   | Korean (Johab)               |  X         |            **      X
-------------------------------------------------------------------------------
    437   | MS-DOS United States         |        X   |    X       X       X
    708   | Arabic (ASMO 708)            |        X   |                    X
    709   | Arabic (ASMO 449+, BCON V4)  |        X   |                    X
    710   | Arabic (Transparent Arabic)  |        X   |                    X
    720   | Arabic (Transparent ASMO)    |        X   |                    X
===============================================================================

A graphical user agent might render this as:

A table with grouped rows and columns

This example illustrates how COLGROUP can be used to group columns and set the default column alignment. Similarly, TBODY is used to group rows. The frame and rules attributes tell the user agent which borders and rules to render.

1