Striping a HTML table with merged cells


A common style applied to HTML tables with lots of data is to make them striped, i.e. set the background color of alternate rows. This is easy to do when each tr represents an individual row to be striped, but if you have cells merged across multiple rows then this doesn’t work.

When each tr represents a single row, the standard way of striping a table is with some CSS such as:

1
2
3
table tbody tr:nth-child(even) {
    background-color: #E8E8E8;
}

This will produce a table like the following:

Team Bikes
BMC Racing BMC
Team Movistar Canyon
Team Sky Pinarello

In this case everything works fine, but it goes horribly wrong if you have cells that span multiple rows:

Country Bike Manufacturers
Germany Canyon
Cube
Focus
United Kingdom Raleigh
Ribble
United States Marin
Trek

To solve this problem, use multiple tbody elements by placing all the rows with a common background into their own dedicated tbody. The CSS to stripe such a table becomes:

1
2
3
table tbody:nth-child(even) {
    background-color: #E8E8E8;
}

The following CodePen demonstrates this trick:

See the Pen TableHighlightFail by Tom Auger (@tomauger) on CodePen.