Chapter 17 of the CSS2 specification defines CSS tables and how various properties affect table elements. In describing the effects of the background properties, however, the spec is very ambiguous, making it impossible to write a defensibly correct implementation. The outstanding problems are explained below, using row backgrounds as an example.
In this model, each cell has an individual border. The 'border-spacing' property specifies the distance between the borders of adjacent cells. This space is filled with the background of the table element.
This raises the question of what happens to a row background between cells. Is it rendered invisible over the spacing or does the background strip split at this point, resuming its pattern in the next cell?
The two concepts render as follows:
Rendered as if the cell background were laid out with collapsed spacing and then the cells explode outward to their positions.
Concept Rendering | Final Rendering |
---|---|
Rendered as if the cells are windows looking onto a view of the row background.
Concept Rendering | Final Rendering |
---|---|
Both methods work fine if the table is a strict grid. However, in the explode model, cells spanning more than one column throw off background alignment across rows. This shortcoming appears in the diagram above. Since the window model does not suffer from this problem, it is superior.
From what I gather, the assumption seems to be that row and column backgrounds must be strictly rectangular. There is nothing in the spec that either supports or refutes this. Assuming that row and column boxes must be rectangular, one might have a table that looks like this:
Concept Rendering | Final Rendering |
---|---|
Having a background boundary cut across at an arbitrary point without consideration for the cell's contents looks bad. However, the problem is not merely aesthetic, but also very practical: the contrast between text and background is compromised, and the author has no control over this. It is, of course, possible to explicitly place the background on colspanned cells, but this breaks the continuity of image backgrounds, which is especially noticeable with large patterns, and cannot emulate the layering effects possible with transparent background images.
One way to avoid the contrast problem is to have the background of the cell's originating row cover the cell's entire background area, thus:
Concept Rendering | Final Rendering |
---|---|
Either way, the spec needs clarification.
The strangely specified bounds of table element backgrounds have been commented on before by David Baron, and later brought up by myself. For table rows, the spec says that the rows together cover the entire table. Does this include the space between the table border and the cell borders? Should it include the space between the table border and the cell borders? What about the space between adjacent rows?
The problems with starting the background area in the spacing beyond cell borders is that the author cannot place images so that they line up with the edges of the visible background. Consider this example:
Concept Rendering | Final Rendering |
---|---|
The image appears properly lined up with the cells', and thus the rows' visible, boundaries. If the background area began in the cellspacing, the image's border effect would be lost.
Tim Bagot commented on the somewhat peculiar behavior of "empty-cells: hide" several years ago. It clears the border and background of the table cell to "hide" it, but the table cell is very visible (though without a border) if the background is assigned on a row, column, row group, or column group:
empty-cells: show | empty-cells: hide |
---|---|
Judging from the errata and traditional browsers' behavior, the effect indended seems to be more like:
It certainly looks more self-consistent that way, and if one wanted the effect currently specified, it's easily accomplished by
td:empty, th:empty { border: none; background: transparent; }
To resolve the ambiguity with respect to table backgrounds defined by the CSS2 specification, I propose the following changes:
- The next layer contains the column groups.
Each column group extends from the top of the cells in the top row to the bottom of the cells on the bottom row and from the left edge of its leftmost column to the right edge of its rightmost column. The background extends to cover the full area of all cells that originate in the column group, but this extension does not affect background image positioning.The columns groups are as tall as the table, but they need not cover the whole table horizontally.- On top of the column groups are the areas representing the column boxes.
Each column is as tall as the column groups and as wide as a normal (single-column-spanning) cell in the column. The background extends to cover the full area of all cells that originate in the column, but this this extension does not affect background image positioning.Like column groups, columns are as tall as the table, but need not cover the whole table horizontally.- Next is the layer containing the row groups.
Each row group extends from the top left corner of its topmost cell in the first column to the bottom right corner of its bottommost cell in the last column.Each row group is as wide as the table. Together, the row groups completely cover the table from top to bottom.- The next to last layer contains the rows.
Each row is as wide as the row groups and as tall as a normal (single-row-spanning) cell in the row. As with columns, the background extends to cover the full area of all cells that originate in the row, but this this extension does not affect background image positioning.The rows also cover the whole table.
In this model, each cell has an individual border. The 'border-spacing' property specifies the distance between the borders of adjacent cells.In this space, the row, column, row group, and column group backgrounds are invisible, allowing the table background to show through.This space is filled with the background of the table element.
To improve the behavior of 'empty-cells', I suggest the following changes:
If the value of their 'empty-cells' property is 'hide'these "empty" cells are transparent through the cell, row, row group, column, and column group backgrounds, letting the table background show throughT.if the value of their 'empty-cells' property is 'hide'