Avg. Rating 4.6

Problem

I want alternate table rows to have a different background color. I know I can do it by adding a CSS class to every other row, but this means I need to change the code every time an new row is added to the table.

Solution

Use JavaScript or a dynamically-generated table to add a different background color to every other row. This recipe shows you how to do it with Spry, jQuery, or PHP. Alternate colors for table rows not only look more attractive, they increase the readability of tables filled with data.

Detailed explanation

When styling an HTML table with CSS, it's useful to know the order in which browsers build the table and apply the styles. All browsers start with the table itself, followed by column groups, and individual columns. Next come row groups, followed by individual rows, and finally individual cells. What this means is that it's not necessary to apply a class to each row. You can apply one background color to the whole table, and use a class to apply the other color to every other row. Since individual cells are created and styled last, you can use a tag (or type) selector to apply yet another color to the table header ( <th>) cells.

The sample files for this recipe (attached at the foot of this page in stripes.zip) all use the following style sheet:

body {
    background-color: #FFF;
    color: #000;
    font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
}
table {
    background-color:#FFFBD0;
    border-collapse:collapse;
    width:700px;
    margin:10px auto;
}
caption {
    font-variant:small-caps;
    font-size:24px;
}
tr {
    vertical-align:top;
}
th {
    background-color:#B3AB75;
    color:#FFF;
    font-size:18px;
}
td {
    padding:2px 10px;
    font-size:14px;
}
.even {
    background-color:#E8E7B3;
}

Using Spry

Spry is Adobe's JavaScript library that controls widgets such as the Spry Menu Bar and Spry Tabbed Panels. But Spry is capable of much more. This recipe relies on SpryDOMUtils.js, a file that's not included with Dreamweaver, but you can get it by downloading a full version of the Spry framework from the Spry section of Adobe Labs. It's also included in stripes.zip attached at the bottom of this page, but if you're interesting in learning more about Spry, it's worth downloading the full Spry framework, because it comes with lots of sample files and documentation.

Begin by attaching SpryDOMUtils.js to your page with a <script> tag in the <head> of the document like this:

<script type="text/javascript"
src="js/SpryDOMUtils.js"></script>

This assumes the file is located in a folder called js.

Create the following script block immediately after the preceding line of code:

<script type="text/javascript">
function init() {
    Spry.$$('tr:nth-child(2n+1)').addClassName('even');
}
window.onload = init;
</script>

This defines a JavaScript function called init(), and then assigns it to the onload event of the window. Inside the init() function, the Spry selector utility, Spry.$$(), uses a CSS3 selector to skip the first table row (which uses a different color for the table headers), and then add the even class to every subsequent even table row

You can find details of the CSS3 selectors supported by Spry in the online documentation. In this case, the :nth-child() pseudo-class selects every second row ( 2n). The +1 means that it begins counting after the first row.

NOTE: If your page uses other JavaScript functions that are triggered by the onload event in the <body> tag, omit window.onload = init; from the preceding script, and add a semicolon followed by init() at the end of the existing functions. For example, if you have something like this in your opening <body> tag:

<body onload="P7_initPM(1,16,1,-20,10)">

Add init() like this:

<body onload="P7_initPM(1,16,1,-20,10); init()">

For other examples of using the Spry selector utility, see the samples in Adobe Labs.

Using jQuery

If you already use the popular JavaScript library, jQuery, you might prefer to use it instead of Spry. The code is very similar. Add the following to the <head> of your page:

<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
    $('tr:nth-child(2n+1)').addClass('even');
});
</script>

This also uses the CSS3 :nth-child() pseudo-class. Since jQuery has its own on-ready function built in, you don't need to worry about any conflict with events triggered by the onload event.

This script gets the jQuery core file from the Google content distribution network. If you prefer to use your own file, you can download the jQuery library from http://jquery.com/.

Using PHP and a dynamic table

Although the Spry and jQuery solutions are easy to implement, they suffer from the drawback that they won't work if a visitor to your site has JavaScript disabled. While it's true that the vast majority of people do have JavaScript enabled in their browsers, some people don't - either out of choice, or because of restrictions imposed by a corporate system administrator. This problem doesn't arise if you're using PHP to generate the table dynamically.

This solution involves creating a counter variable before the repeat region that displays the table rows, and using the conditional (or ternary) operator inside the opening <tr> tag to insert the class in every other row.

The code for the dynamic table in the sample file originally looked like this:

<table>
  <caption>
    Adobe Creative Suite
  </caption>
  <tr>
    <th scope="col">Product</th>
    <th scope="col">Description</th>
  </tr>
  <?php do { ?>
    <tr>
      <td><?php echo $row_getProducts['program'];
?></td>
      <td><?php echo $row_getProducts['description'];
?></td>
    </tr>
    <?php } while ($row_getProducts =
mysql_fetch_assoc($getProducts)); ?>
</table>

The counter needs to be initialized before the beginning of the repeat region like this:

<?php $i = 0; ?>

Then the following code needs to be added to the opening <tr> tag inside the repeat region:

<?php echo $i++ % 2 ? 'class="even"' : ''; ?>

The ++ increments $i by one each time the repeat region runs the loop. The modulo operator ( %) divides the value by 2 and returns the remainder, so the result is always 0 or 1. PHP treats 0 as false, and 1 as true, so when the result is 1, class="even" is inserted in the <tr> tag. When the result is 0, an empty string (in other words, nothing) is inserted.

The final code looks like this:

<table>
  <caption>
    Adobe Creative Suite
  </caption>
  <tr>
    <th scope="col">Product</th>
    <th scope="col">Description</th>
  </tr>
  <?php $i = 0; ?>
  <?php do { ?>
    <tr <?php echo $i++ % 2 ? 'class="even"' : ''; ?>>
      <td><?php echo $row_getProducts['program'];
?></td>
      <td><?php echo $row_getProducts['description'];
?></td>
    </tr>
    <?php } while ($row_getProducts =
mysql_fetch_assoc($getProducts)); ?>
</table>

NOTE: The sample files include the code for the PHP version, but not the database or MySQL connection. Use the sample file as a guide for adapting a dynamic table of your own.

stripes.zip
[Sample files]

+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes