I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

TitleJapanese TitleYear of ReleaseRun Time
Rashomon羅生門195088 minutes
IkuruI生きる1952143 minutes
Seven Samurai七人の侍1954207 minutes
Throne of Blood蜘蛛巣城1957105 minutes
The Hidden Fortress隠し砦の三悪人1958139 minutes
Yojimbo用心棒1961110 minutes
Ran1985160 minutes
Hover to highlight rows, click on table headers to highlight columns

Dynamic Customized Tables With CSS3

css / tables

Estimated reading time: 3 minutes

The demarcation between the appropriate roles for , and in modern web development can be a grey area. Perhaps one of the easiest ways to make this distinction clear is with tables. For example, in the table to the left, we want to accomplish several goals:

  • A background image that automatically resizes as we add and remove table data
  • Alternate appearance of table rows, to make them clearer
  • Highlight the row that the user places their cursor in
  • Make it clear which column our user is interested in.

All of this is just CSS. I've touched on almost all of the techniques I'm about to use in past articles, and will reference them as I go; the parts that are new and interesting are under-utilized and almost unknown tags that we'll use as markup to add more semantic "hooks" for our CSS to modify: <col />, <thead> and <tbody>.

Extended Table Markup

The code for our table looks something like this:

<table id=kurosawa>
<col /><col /><col />
<caption>The Masterworks of Akira Kurosawa</caption>
<th>Year of Release</th>
<th>Run Time</th>
<tr><td>Rashomon</td><td>1950</td><td>88 minutes</td></tr>
<tr><td>Ikuru</td><td>1952</td><td>143 minutes</td></tr>
<tr><td>Seven Samurai</td><td>1954</td><td>207 minutes</td></tr>

<thead> and <tbody> are fairly straightforward: they make clear what in the table is data versus header sections (<tfooter> is also possible). The caption tag is used for accessibility. What's new here is col.


When we construct HTML tables, we do so by row, creating table cells each row. Columns are implied, but they are not explicit. <col> is a reference to make that association clear: each <col> tag refers to the column of cells immediately below it when the table is rendered in the browser. Therefore, you would normally have the same number of cols declared as you have <td> cells in each row, as we do here.

(It is possible to have a <col /> take responsibility for multiple columns by using the span attribute: <col span=2>, for example).

Table Customisation

First, some base CSS:

table#kurosawa { background-image:url(seven-samurai.jpg); background-size: cover; border-collapse: collapse; }
table#kurosawa caption { font-size: larger; padding: 1em; }
table#kurosawa td { padding: .5em; }
table#kurosawa thead tr { background: #000; color: #fff; }

We've used a dynamic background image to fill the table and are using <thead> as a parent in a descendant selector to change the header row; aside from that, the CSS is fairly straightforward. Next, we want to zebra-stripe the rows in the table body:

table#kurosawa tbody tr:nth-child(odd) { background: rgba(0,0,0,0.3); }

To highlight the rows on hover:

table#kurosawa tbody tr:hover { background: rgba(0,0,0,0.8); color: #fff; cursor: pointer; }

Finally, we want to be able to highlight each column. Unfortunately, <col /> supports very few CSS properties, and can't take most pseudo-selectors. Instead, we'll use :target from links in the table header section. To do so, we'll modify the markup slightly:

<table id=kurosawa>
<col id=filmtitle>
<col id=releasedate>
<col id=runtime>
<caption>The Masterworks of Akira Kurosawa</caption><thead>
<th><a href=#filmtitle>Title</a></th>
<th><a href=#releasedate>Year of Release</a></th>
<th><a href=#runtime>Run Time</a></th>

Now each table header cell has an anchor link to the <col /> it is part of. Next, we customize the links:

table#kurosawa thead tr th a { text-decoration: none; color: #fff; background: #000; padding: .5em; display: block; }
table#kurosawa thead tr th a:hover { background: #777; }

And then the neat part: make each column highlight when it is targeted by the appropriate link.

table#kurosawa col:target { background: rgba(255,0,0,0.5); color: white; }

<col> can be placed almost anywhere in a table: I've put the tags at the very top in order to minimize "bouncing" of the page when the local anchor link is followed. Because col elements are rendered on "top" of the existing content, using rgba colours creates a nice layered effect. It's also possible to "zebra stripe" cols using CSS; for example:

table#kurosawa col:nth-child(odd) { background: rgba(255,0,0,0.3); }
comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.