Somacon.com: Articles on web development, software, and hardware
§ Home > Index > Web Development

How to Alternate Table Row Colors in CSS and HTML

This article describes how to create tables with alternating row colors in CSS and HTML. Script examples are provided for ASP and PHP. The method described here accomplishes the effect with very little code.

When printing tables with many rows, alternating the background color of each row can increase readability. For the sake of simplicity, assume that the text color is black, and the rows alternate between two, light background colors. You can modify the technique below for more complex situations.

Inefficient Alternating Table Row Colors

The first example shows an inefficient way of alternating the colors. There are three reasons why this is inefficient. First, the class attribute must be written for every TD tag, which we will see is more than necessary. Second, the class name itself is long, which also increases code size. Finally, alternating between the class names "datacellone" and "datacelltwo" may require several lines of code in the script that prints the table.

<style type="text/css">
td.datacellone {
	background-color: #CC9999; color: black;
}
td.datacelltwo {
	background-color: #9999CC; color: black;
}
</style>
<table>
<tr><td class="datacellone">One</td><td class="datacellone">Fish</td></tr>
<tr><td class="datacelltwo">Two</td><td class="datacelltwo">Fish</td></tr>
<tr><td class="datacellone">Red</td><td class="datacellone">Fish</td></tr>
<tr><td class="datacelltwo">Blue</td><td class="datacelltwo">Fish</td></tr>
</table>
OneFish
TwoFish
RedFish
BlueFish

Efficient Alternating Table Row Colors

To produce the same effect with less code, instead define two types of TR classes. Then, use inheritance to the TD tag. Read the example and the explanation will follow.

<style type="text/css">
tr.d0 td {
	background-color: #CC9999; color: black;
}
tr.d1 td {
	background-color: #9999CC; color: black;
}
</style>
<table>
<tr class="d0"><td>One</td><td>Fish</td></tr>
<tr class="d1"><td>Two</td><td>Fish</td></tr>
<tr class="d0"><td>Red</td><td>Fish</td></tr>
<tr class="d1"><td>Blue</td><td>Fish</td></tr>
</table>
OneFish
TwoFish
RedFish
BlueFish

As you can see, the style sheet includes two row styles. Each style defines a background color for all TD tags subordinate to a specific class of TR tags. This allows us to define the class once for the row, and have the background color applied to all the cells within that row. This technique is available today because all modern browsers support this type of CSS inheritance.

The choice of the class names is deliberate and purposeful. The class names are only two characters, which saves bandwidth by condensing the resulting HTML code. By alternating between 0 and 1, we can use the AND operator against a row counter to alternate the class name in the script. This can be done inline without losing code readability. CSS class names must begin with an alphabet character (a-z or A-Z), otherwise we could have named the classes with just the single digit. (See 4.1.1 Tokenization in the CSS 2.1 Specification for the precise naming rules.) Because class names are case-sensitive, we use a convention of all lower-case class names for simplicity.

In the scripts below, you can see how simple and uncluttered the code is when the alternating row colors are defined at the TR tag. The code below shows how to request data from a database and print it in HTML. The code is mostly complete except it leaves out database connection opening and closing, and error handling.

ASP and PHP Script Examples for Alternating Table Row Colors

' ASP Version
strsql = "SELECT Adjective, Noun FROM DrSeussLines"
objRS.Open strsql,objCN,adOpenForwardOnly,adLockReadOnly,adCmdText
i = 0
Response.write "<table>"
Do While Not objRS.EOF
	i = i + 1
	Response.write "<tr class=""d" & (i And 1) & """>"
	Response.write "<td>" & objRS(0) & "</td>"
	Response.write "<td>" & objRS(1) & "</td>"
	Response.write "</tr>" & vbCrLf
	objRS.MoveNext
Loop
objRS.Close
Response.write "</table>"

// PHP Version
$query = "SELECT Adjective, Noun FROM DrSeussLines";
$result = mysql_query($query);
$i = 0;
print "<table>";
while(($row = mysql_fetch_row($result)) !== false) {
	$i++;
	print "<tr class=\"d".($i & 1)."\">";
	print "<td>".$row[0]."</td>";
	print "<td>".$row[1]."</td>";
	print "</tr>\n";
}
mysql_free_result($result);
print "</table>";

A More Realistic Style Sheet

The style sheets above are minimal, and only show how to alternate colors. In real code, you would probably want the styles to only apply to particular tables. We can use CSS inheritance again to achieve this. Below is a more realistic style sheet for the table. Note that by using the table.sample td selector, we can apply a style to all the TD cells in the table without repeating the common aspects in the style of each row type.

<style type="text/css">
table.sample {
	border: 6px inset #8B8378;
	-moz-border-radius: 6px;
}
table.sample td {
	border: 1px solid black;
	padding: 0.2em 2ex 0.2em 2ex;
	color: black;
}
table.sample tr.d0 td {
	background-color: #FCF6CF;
}
table.sample tr.d1 td {
	background-color: #FEFEF2;
}
</style>
<table class="sample">
<tr class="d0"><td>One</td><td>Fish</td></tr>
<tr class="d1"><td>Two</td><td>Fish</td></tr>
<tr class="d0"><td>Red</td><td>Fish</td></tr>
<tr class="d1"><td>Blue</td><td>Fish</td></tr>
</table>
OneFish
TwoFish
RedFish
BlueFish

Alternating Table Column Colors and Styles

You might ask, can we use a similar technique to alternate row colors of columns? Alas, there is currently no simple way to do this using style sheets. Although CSS defines the mechanisms, browser support is very limited as of mid-2005. Luckily, tables with many columns are infrequent on the web. If color or text alignment must be specified for a column, then the technique is to define the style at each TD tag of each row of the column. This technique increases code size significantly, but is reliable.


Created 2005-08-07, Last Modified 2011-07-24, © Shailesh N. Humbad
Disclaimer: This content is provided as-is. The information may be incorrect.