When the task calls for it and its appropriate, we need to use tables to display tabular data. When formatting these tables, we routinely need to do things like style alternate rows to enhance the user’s ability to quickly identify the data in those rows. In the past this was commonly done with a little bit of either server or client-side programming to apply a class to those alternate rows. Granted, not a difficult task, just something additional to do.
Now, with the advent of some new bits of CSS3, we can take care of all of this without any scripting. First, let’s take a look at these new structural pseudo-classes:
:nth-child(n) - nth child of parent :nth-last-child(n) - nth child of parent counting backwards :nth-of-type(n) - nth element of its type within the parent :nth-last-of-type(n) - nth element of its type counting backwards
Now you’re asking yourself “what values can I use in place of n?” Here are some common values:
odd - every odd element even - every even element 4 (or any number) - meaning the 4th element in this case 3n - every third element (3,6,9,...) 3n+6 - every third element starting with 6
Let’s do a little example. Let’s style a table of the top 10 films produced by Paramount Pictures.
<table id="paramount">
<caption>Paramount Top Grossing Movies</caption>
<thead>
<tr>
<th>Rank</th>
<th>Movie Title</th>
<th>Total Gross</th>
<th>Theaters</th>
<th>Opening Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Titanic</td>
<td>$600,788,188</td>
<td>3,265</td>
<td>12/19/97</td>
</tr>
<tr>
<td>2</td>
<td>Transformers: Revenge of the Fallen</td>
<td>$402,111,870</td>
<td>4,293</td>
<td>6/24/09</td>
</tr>
<tr>
<td>3</td>
<td>Transformers: Dark of the Moon</td>
<td>$352,390,543</td>
<td>4,088</td>
<td>6/29/11</td>
</tr>
<tr>
<td>4</td>
<td>Forrest Gump</td>
<td>$329,694,499</td>
<td>2,365</td>
<td>7/6/94</td>
</tr>
<tr>
<td>5</td>
<td>Shrek the Third</td>
<td>$322,719,944</td>
<td>4,172</td>
<td>5/18/07</td>
</tr>
<tr>
<td>6</td>
<td>Transformers</td>
<td>$319,246,193</td>
<td>4,050</td>
<td>7/3/07</td>
</tr>
<tr>
<td>7</td>
<td>Iron Man</td>
<td>$318,412,101</td>
<td>4,154</td>
<td>5/2/08</td>
</tr>
<tr>
<td>8</td>
<td>Indiana Jones and the Kingdom of the Crystal Skull</td>
<td>$317,101,119</td>
<td>4,264</td>
<td>5/22/08</td>
</tr>
<tr>
<td>9</td>
<td>Iron Man 2</td>
<td>$312,433,331</td>
<td>4,390</td>
<td>5/7/10</td>
</tr>
<tr>
<td>10</td>
<td>Star Trek</td>
<td>$257,730,019</td>
<td>4,053</td>
<td>5/8/09</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2">Total Sales:</th>
<td colspan="3">$3,532,627,807</td>
</tr>
</tfoot>
</table>
Nothing special here, just a well-formatted table. Now let’s put some basic style, color and rounded corners on some elements in the thead and tfoot:
table{ margin:1em auto; font-size:80%; } th { background: #193441; } thead th:first-child { /* selects the first th inside of the thead */ border-top-left-radius: 5px; /* we need to apply the rounding to the th because the tr doesn't support this property */ } thead th:last-child { /* selects the last th inside of the thead */ border-top-right-radius: 5px; } tfoot th:first-child { /* selects the first th inside of the tfoot */ border-bottom-left-radius: 5px; } tfoot td:last-child { /* selects the last td inside of the tfoot */ border-bottom-right-radius: 5px; background: #193441; font-size: 140%; height: 2em; }
Here’s where we’re at now:
Now let’s add some alignment and padding to the cells:
th, td { padding: .2em 1em; } thead tr th:nth-of-type(1), tbody tr td:nth-of-type(1) { /* this selector selects the first th and td in each row...in other words, the first column */ text-align: right; } thead tr th:nth-of-type(2), tbody tr td:nth-of-type(2) { /* second column */ text-align: left; } thead tr th:nth-of-type(3), tbody tr td:nth-of-type(3) { /* third column */ text-align: right; } thead tr th:nth-of-type(4), tbody tr td:nth-of-type(4) { /* fourth column */ text-align: right; } thead tr th:nth-of-type(5), tbody tr td:nth-of-type(5) { /* fifth column */ text-align: right; }
The table so far:
Not bad. It’s getting there. Now let’s add some color to alternating rows:
tbody tr:nth-child(odd) { /* select the odd-numbered rows */ background: #FCFFF5; } tbody tr:nth-child(even) { /* selects the even-numbered rows */ background: #D1DBBD; } tbody tr:hover { /* changes styles of the row when hovered */ background: #3E606F; color: #FFF; font-style: italic; }
Here’s the completed table:
That’s really it. What we’re left with is a nice clean table and the styling completely separated from presentation. You can use these CSS3 selectors now as they are supported in all major browsers except ie8 and earlier.