50
41
colgroups. An attribute setting of RULES="GROUPS
" on the TABLE element would cause
rules (that is, lines) to be displayed between colgroups and rowgroups rather than between cells.
And so on.
These convenience features are not the reason, however, for the existence of colgroups. The
original motivation for the inclusion of colgroups in the HTML specification was the desire to
support incremental rendering of data. As the introduction
to the section on tables in the HTML
4.01 specification says:
The HTML table model has been designed so that, with author
assistance, user agents may render tables incrementally (i.e., as
table rows arrive) rather than having to wait for all the data
before beginning to render.
In order for a user agent to format a table in one pass, authors
must tell the user agent: The number of columns in the table...
[and the] widths of these columns... using a combination of
COLGROUP and COL elements. If any of the columns are specified in
relative or percentage terms..., authors must also specify the
width of the table itself.
Normally, when a browser renders a table, it makes two passes over the table. In the first pass, it
examines the entire table, discovering the largest number of cells per row in the table and how
big the contents of the cells are. From this information, it calculates the widths that it will use to
display the columns in the table. Then, in a second pass, it actually displays the table. But if the
COL and COLGROUP elements supply the browser up front with all of the column width
information, that removes the need for the browser to make the first pass. It can immediately
start rendering the table. And it can do this incrementally, displaying each row as soon as it gets
it.
We won't go into the details of how COL and COLGROUP specifications are coded in HTML
— that material is available in the section on column groups
in the HTML language
specification, and we give an example of it later in this paper, in the discussion of the SCOPE
example on the Access Board's Web site
. But we will note that COL and COLGROUP tags must
be placed in a specific location
inside the TABLE element — after the CAPTION element (if
present) and before the THEAD, TFOOT, and TBODY elements.
6.2.2
Rowgroups
See Rowgroups
Colgroups are defined using the COLGROUP tag. Perhaps surprisingly, however, HTML
contains no corresponding ROWGROUP tag. HTML has the
concept
of a rowgroup
, and
"rowgroup" is a valid value of the SCOPE attribute of TH and TD tags
, but it contains no
ROWGROUP tag, as such.
The reason that HTML has no ROWGROUP tag is that it recognizes three different kinds of
rowgroups, and has specific tags for each of those kinds: THEAD, TFOOT, and TBODY. The
35
42
reason for this three-fold division is that rowgroups were designed to support a display in which
the header and footer of a table are held steady, and the user can scroll through the rows in the
body of the table. Here's what the HTML specification says:
Table rows may be grouped into a table head, table foot, and one
or more table body sections, using the THEAD, TFOOT and TBODY
elements, respectively. This division enables user agents to
support scrolling of table bodies independently of the table head
and foot.
Here's a simple illustration. Suppose we had marked up our example table with THEAD,
TFOOT, and TBODY tags. In the following graphic, we have colored the header row marked
with the THEAD tag, and the footer row marked with the TFOOT tag. The rows in the middle
have been marked with the TBODY tag. This capability would allow a browser to hold the
colored rows steady, while the user scrolled through the middle rows, perhaps with a slider bar
like the one in the illustration.
It was envisioned that this feature might also support the printing of tables.
When long tables are printed, the table head and foot information
may be repeated on each page that contains table data.
We won't go into the details of how THEAD, TFOOT, and TBODY specifications are coded in
HTML — that material is available in the section on row groups
in the HTML language
specification. But we will note that you can
not
code these elements in the order that you'd
expect — namely: THEAD, TBODY, TFOOT. If you code TFOOT, it must be coded before
TBODY, in this order — THEAD, TFOOT, TBODY. This makes perfectly good sense when
you remember the W3C's interest in supporting the incremental rendering of tables. As the
HTML language specification says
TFOOT must appear before TBODY within a TABLE definition so that
user agents can render the foot before receiving all of the
(potentially numerous) rows of data.
6.2.3
An Important Limitation of Colgroups and Rowgroups
It is important to understand the motivations behind HTML's colgroup and rowgroup features,
because these motivations explain the characteristics and limitations of colgroups and
47
43
rowgroups. And they do have an important limitation.
They cannot be nested to more than two
levels.
They support only two levels: colgroup and col, or rowgroup and row.
6.2.4
Scope
Once the W3C had colgroups and rowgroups available, they could be extended to do other work
as well as the work for which they were originally intended. And so the
SCOPE
attribute was
born.
The SCOPE attribute is an attribute that you can attach to header cells that are marked with TD
and TH tags. It allows a header cell to be associated not just with a row or a column, but with a
rowgroup or a colgroup. So the four allowable values of SCOPE
are: col, colgroup, row,
rowgroup.
In some ways, SCOPE is HEADERS turned inside out. That is, if you want to associate some
data cell D with some header cell H, you can either code a HEADERS attribute on data cell D, or
a SCOPE attribute on header cell H. The SCOPE attribute is a way for a cell to broadcast its
"headerness" — its ability to function like a header cell — to other cells.
The SCOPE attribute has significant limitations.
1. The hierarchy provided by rowgroups and colgroups is limited to two levels. This
limitation is a result of the original purpose and design of rowgroups and colgroups. This
means that if you have a table with three or more levels of column headings, you cannot
use colgroups to associate data cells with column header cells, and similarly for rows in
which you have three or more levels of row headers.
2. In order to use colgroups and rowgroups for any serious table markup, it is necessary to
mark up the table with COLGROUP and TBODY tags. This adds an extra layer of
complexity to the table markup.
6.2.5
Confusion About the Scope Attribute
It is important to note that a colgroup is not
defined by a
colspan
attribute.
It is a common mistake to code something like the following:
<TH COLSPAN="2" SCOPE= "colgroup"> Some heading text </TH>
In this code, the author has defined a cell that spans two positions, and had added the SCOPE
specification of "colgroup" in order to make the scope of the header cover both of the spanned
columns.
But this is a mistake.
The COLSPAN attribute has no bearing on the effect of the
SCOPE attribute.
SCOPE seems to be widely misunderstood. The W3C's Web site containing the HTML language
specification gives an example of its use that — although correct — is very misleading. And the
Web site of the Access Board (which has the status of a legally binding definition of the
26
44
practices to which Federal agencies must conform in order to be 508-compliant) contains an
example of the use of the SCOPE attribute that is simply wrong.
6.2.6
SCOPE Example in the HTML language specification
Misunderstanding of the use of SCOPE is practically guaranteed by an example in section 11.4.1
of the HTML definition document. That example shows the following table:
The HTML code accompanying the example does not define a COLGROUP anywhere, and the
HTML for the first cell is this.
<TR> <TH colspan="5" scope="colgroup"> Community Courses — Bath Autumn 1997
</TH> </TR>
This markup appears to be using the SCOPE="colgroup" specification without any colgroups
being defined on the table — this makes it easy to jump to the conclusion that a colgroup is
being defined by the
colspan="5"
specification.
What the example does not point out is that — in the absence of explicit COLGROUP tags -- all
tables contain a single implicit colgroup
. That is the only reason this example works — the
colgroup referred to in the SCOPE attribute is the single implicit colgroup that all HTML tables
have by default.
6.2.7
SCOPE Example on the Access Board Web Site
An outright mistake in the use of SCOPE can be found on the Web site for the Access Board,
which contains the following explanation.
How can HTML tables be made readable with assistive
37
45
technology?
...
Using the Scope Attribute The first row of each table should
include column headings. Typically, these column headings are
inserted in <TH> tags, although <TD> tags can also be used.
These tags at the top of each column should include the
following attribute:
scope="col"
By doing this simple step, the text in that cell becomes
associated with every cell in that column.
At first, it looks like the Access Board has merely failed to imagine tables that contain more than
one row of headers. But farther down on the Web page, we find the following example, which is
clearly incorrect. (I have tweaked a few attributes on of the TABLE tag, to make the layout of
the table a bit easier to see.)
<table BORDER="1" cellspacing="0"
cellpadding="5">
<tr>
<th> </th>
<th colspan="2" scope="col" > Winter </th>
<th colspan="2" scope="col" > Summer </th>
</tr>
<tr>
<th> </th>
<th scope="col"> Morning </th>
<th scope="col"> Afternoon </th>
<th scope="col"> Morning </th>
<th scope="col"> Afternoon </th>
</tr>
<tr>
<td scope="row"> Wilma </td>
<td> 9-11 </td>
<td> 12-6 </td>
<td> 7-11 </td>
<td> 12-3 </td>
</tr>
<tr>
21
46
<td scope="row"> Fred </td>
<td> 10-11 </td>
<td> 12-6 </td>
<td> 9-11 </td>
<td> 12-5 </td>
</tr>
</table>
This table is rendered this way:
Winter
Summer
Morning Afternoon Morning Afternoon
Wilma
9-11
12-6
7-11
12-3
Fred 10-11
12-6
9-11
12-5
24
47
This coding is incorrect.
By specifying SCOPE="col" on cells (Winter, Summer) that span two columns, the Access
Board example clearly shows a failure to understand the use of SCOPE. To be correct, SCOPE
must be "colgroup" on the cells that span two columns, and in this table there must be three
COLGROUP elements — one for the stub header column, and two for the major headings. The
colgroups for the major headings must specify SPAN="2". Here is what the correct code would
look like. We have underlined changes to the code and marked them red
. The specification
SPAN="1" on the first COLGROUP is optional, but we have coded it here to make it explicit.
<table BORDER="1" cellspacing="0">
<COLGROUP SPAN="1">
<COLGROUP SPAN="2">
<COLGROUP SPAN="2">
<tr>
<th> </th>
<th colspan="2"
scope="colgroup"
>Winter </th>
<th colspan="2" scope="colgroup"
>Summer </th>
</tr>
... etc. ...
</table>
45
48
6.3
The BASIC algorithm
The BASIC algorithm is described in section 11.4.3
of the W3C specification for HTML 4.01. I
reproduce it here, with the steps numbered for easy reference.
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.)
1.
First, search left from the cell's position
to find row header cells. Then search
upwards to find column header cells. The
search in a given direction stops when the
edge of the table is reached or when a data
cell is found after a header cell.
2.
Row headers are inserted into the list in
the order they appear in the table. For
left-to-right tables, headers are inserted
from left to right.
3.
Column headers are inserted after row
headers, in the order they appear in the
table, from top to bottom.
4.
If a header cell has the headers
attribute
set, then the headers referenced by this
attribute are inserted into the list and
the search stops for the current direction.
5.
TD
cells that set the axis
attribute are
also treated as header cells.
41
49
Let's see how this works in practice. Consider the following table.
Example Table 1
Ruritanian
Population
Survey
By Gender
Males Females
By Region
North
2111
2222
South
4444
5555
The HTML for this table is:
<TABLE BORDER="1" CELLSPACING="0" CELLPADDING="5">
<CAPTION>Example Table 1</CAPTION>
<TR>
<TH ROWSPAN="2" COLSPAN="2"> Ruritanian <BR> Population <BR>
Survey </TH>
<TH ROWSPAN="2"> All <BR> Genders </TH>
</TR>
<TR>
<TH> Males </TH>
<TH> Females </TH>
</TR>
<TR>
<TH ROWSPAN="2"> By Region </TH>
<TH> North </TH>
<TD ALIGN="right"> 2111 </TD>
<TD ALIGN="right"> 2222 </TD>
</TR>
<TR>
<TH> South </TH>
<TD ALIGN="right"> 4444 </TD>
<TD ALIGN="right"> 5555 </TD>
</TR>
</TABLE>
According to the BASIC algorithm, what is the procedure used to construct the ordered list of
headers associated with the cell with value 5555 in this table? And what is the resulting list?
Documents you may be interested
Documents you may be interested