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.
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.
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;
}
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.
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/.
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.
+