- From: Ernest Cline <ernestcline@mindspring.com>
- Date: Sun, 14 Dec 2003 20:53:52 -0500
- To: "W3C CSS List" <www-style@w3.org>, "W3C HTML List" <www-html@w3.org>
Well, I said earlier on www-style that column styling might require revisiting the XHTML table model, altho I hoped it wouldn't Well, I am now convinced that it will, altho the changes are fairly minor and only affect tables that use the rowspan and/or colspan attributes. A Proposal For the XHTML 2 Table Module and the CSS3 Table Module To Enable Styling By Columns via CSS One of the most requested features for CSS is to provide a mechanism to enable styling columns via CSS. This can actually be done now for simple cases, but complex cases cause problems. Example 1: <!-- An HTML4/XHTML1 table --> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td>5</td><td>6</td></tr> <tr><th>7</td><td>8</td><td>9</td></tr> </table> The selector "tr>*:last-child" selects the cells in the last column quite nicely. More generally, the selector "tr>*:nth-child(k)" selects the cells from column k. The difficulty comes when trying to handle more complicated cases where colspan and rowspan are used, or where unusual values of the display property are chosen.. Example 2: <!-- An HTML4/XHTML1 table --> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td rowspan="2">5<br />8</td><td>6</td></tr> <tr><th>7</td><td>9</td></tr> </table> Here the selector "tr>*:nth-child(2)" will select the cell with content "9" which is actually in the third column. The problem occurs because of the HTML table model which dates from before the time it was decided that separating styling from content would be a good thing to do. There is no need in unstyled HTML to indicate in the third table row anything about the second column to achieve the correct layout. Hence, why include such an element was the thinking, and thus HTML was designed to not use it. Unfortunately, CSS needs to determine style before it can determine layout. The CSS display properties and the table layout algorithm combine to make it impossible to determine the column of an element in a manner that would not be changed if the value of display is changed for one or more of the table elements. However, what if we change the table layout model for unstyled tables. A small change was made between HTML4 and XHTML1 where the table rules were changed to use the CSS 2 table layout algorithm instead. If CSS 3 includes changes to make column selection possible, then a change in the default table layout rules for XHTML2 to support this would be desirable. Changing the rules so that the value of rowspan and colspan do not affect the column that a sibling element is in would enable the selector "tr>*:nth-child(k)" to select the cells from column k. Consider the following example taken from CSS 2.1 Section 17.5: [1] Example 3: <table> <tr><td>1 </td><td rowspan="2">2 </td><td>3 </td><td>4 </td></tr> <tr><td colspan="2">5 </td></tr> </table> Treated as HTML4, this table is erroneous and could be presented with cells 2 and 5 overlapping, while as XHTML1 using the CSS2 table layout rules it would not be overlapping. [2] CSS2 considers overlapping cells to be a bad thing, but is it? Suppose that overlapping cells were allowed and that rowspan and colspan simply indicated the amount of overlap. Example 4: <!-- An XHTMLish table corresponding to Example 2 --> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td rowspan="2">5<br />8</td><td>6</td></tr> <tr><th>7</td><td/><td>9</td></tr> </table> Here the rowspan attribute instead of indicating that there is no need to provide an element in the third row for the second column, indicates that a default visual presentation will cause the contents of the cell in row 2, column 2, to overlap the cell below it. To handle this with CSS requires a new property: --- 'table-cell-overlap' Value: none|clapboard|inherit Initial: none Applies to: 'table' and 'inline-table' elements Inherited: no Percentages: N/A Media: visual Computed value: as specified none Cells are laid out so that they do not overlap. This was the only possibility in the CSS 2 table layout model, which is why this is the initial value of this new property. clapboard Cells are laid out so that the they overlap in the following fashion. Each cell is laid out so that table cell encountered first in the traversal of the table will be in front of later table cell. This effect is similar to that of clapboard siding which is where the name of this value comes from. In interactive media, if focus is placed upon a table cell in a table with this value for table-cell-overlap then it will be presented in front of all other cells in that table. --- There may be other models for overlap that make sense, so this proposed property has been designed so that it is easy to add to, which is another reason why I did not name clapboard, "auto", or any other similar phrase that would tend to indicate that it is the only reasonable possibility. This handles the column problem as far as CSS is concerned adequately, but there is still a problem as far as XHTML2 is concerned. Rowspan and colspan are almost entirely presentational, but not quite. As far as the semantics of the <table> element are concerned, example 2 is a shorthand way of indicating the semantically equivalent table: Example 5 <!-- An HTML4/XHTML1 table --> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td>5<br />8</td><td>6</td></tr> <tr><th>7</td><td>5<br />8</td><td>9</td></tr> </table> combined with a presentation that collapses the two adjacent cells with identical content into a single cell. Example 4 handles the presentation adequately, but not the semantics, as it doesn't indicate what the content of the cell in row 3, column 2 is. Duplicating the content as per example 5 is troublesome if the content is fairly large. Using XML Inclusion (XInclude) would work: Example 6 <!-- An HTML4/XHTML1 table with XInclude--> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td id="a">5<br />8</td><td>6</td></tr> <tr><th>7</td><xi:include xpointer="a" /><td>9</td></tr> </table> Example 6 is essentially the same as example 5 and to achieve a visual presentation of example 6 identical to example 2 one would only need the following style rules: #a {rowspan:2} xi|include {visibility:hidden} assuming that "rowspan" and "colspan" are defined as CSS properties such as: --- 'colspan' 'rowspan' Value: <integer>|inherit Initial: 1 Applies to: 'table-cell' elements Inherited: no Percentages: N/A Media: visual Computed value: as specified --- However, the full capabilities of even a minimal XInclude implementation are not needed for this purpose. We neither need nor want any of the attributes of xi:include other than xpointer. This suggests we may want to use a special purpose element. Example 7 <!-- An XHTMLish table --> <table> <tr><th>1</td><th>2</th><th>3</th></tr> <tr><th>4</td><td id="a">5<br />8</td><td>6</td></tr> <tr><th>7</td><tc tref="a" /><td>9</td></tr> </table> The <tc> element would take but a single attribute tref of type IDREF. If the tref attribute is missing or if it refers to either a non-existent element, an element that is not a table cell in the same table, or itself would be the same as <td/>. Otherwise it would be the same as if the element had instead been an <xi:include> element with the value of the tref attribute used as the value of the xpointer attribute and all other attributes left unchanged. I'm not 100% certain of how XInclude handles ID's and IDREF's, so I don't know if this is going to cause any problems. I don't think it will, altho it might cause a little oddity here or there. I think the intent of my proposal is clear, but if I haven't given an appropriate description of what the result is, let me know. [1] http://www.w3.org/TR/CSS21/tables.html#q7 [2] http://www.w3.org/TR/CSS21/images/table-overlap.png Ernest Cline ernestcline@mindspring.com
Received on Sunday, 14 December 2003 20:57:34 UTC