CSS: table caption background image

Styling a table caption with CSS can actually be a little tricky if you don't know exactly how CSS styles must be applied to it. To start with, here's a basic table:

<table summary="Test">
<caption>Test table</caption>

<tr>

<th scope="col">Table header</th>
<th scope="col">Table header</th>
<th scope="col">Table header</th>
<th scope="col">Table header</th>

</tr>

<tr>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>

<tr>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>

<tr>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>

<tr>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
<td>Table cell</td>
</tr>


</table>

We want to apply a tiled background image to the table caption. The relevant styles are as follows:

table {

    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;

}

caption {

    width: 100%;
    margin: 0;
    height: 2.7em;
    line-height: 2.7;
    background: url(img/table_header.jpg) repeat-x;
    color: #fff;
    font-weight: bold;
    text-align: center;
    text-transform: uppercase;

}

th, td {
    border-bottom: 1px solid #cbcbcb;
    vertical-align: top;
    text-align: left;
    padding: 5px;
}

tr:nth-child(even) {

    background: #cbcbcb;

}

The only thing to notice here is that we didn't turn the caption element into a block-level element. If you do this, the background image won't stretch to cover the entire width of the table. This happens because in this case the shrink-to-fit algorithm comes into play. In other words, when the caption is a block-level element, its width is computed according to the amount of content contained inside of it. Nothing less, nothing more. You can see the final result below.

Absolute positioning and CSS tables

CSS specifications don't define the behavior of absolute positioning within table elements. I ran a couple of tests (like this (XML)) that show clearly how browsers handle such situations. Basically, in XHTML and HTML browsers tend to honor the specified styles by using their default algorithms for tables, but in XML they full honor the specs that don't say much about this issue. In a nutshell: layouts look fine in HTML and XHTML, but they're completely broken in XML. So don't try this at home! However, it would be useful to be allowed to absolutely position elements within table elements, though in this case the CSS specifications show a lack in their definitions, mainly due to the correct rules to handle a block formatting context (BFC) in elements such as table cells.