ColdFusion Muse

Alternating Row Color Tip

Mark Kruger September 27, 2005 6:49 PM Coldfusion Tips and Techniques Comments (7)

Before you read this, if you are a bona fide CSS guru, don't laugh at me. Remember I'm just a Coldfusion code jockey with only a bare minimum of aesthetic sensibility and I see CSS with the same approximate mystery as I see women's obsession with shoe shopping. That being said, this is a neat trick for alternating row colors. You know what I mean - you have this long query that is going to be displayed in tabular HTML. You'd like to alternate each row to make the data stand out and be easier to read.

Now in lots of my old code there are CFIF statements like this

<td bgcolor="<cfif currentrow mod 2>##FFFFF<cfelse>##CCCCC</cfif>">#columname#</td>
Ooh! Just looking at it probably gives you a shudder. Looking at more recent code you might see something like this:
<td style="background-color: <cfif currentrow mod 2>##FFFFF;<cfelse>##CCCCC;</cfif>">#columname#</td>
Well, it's better, but it's still ugly.

Now very recent code might have 2 classes in the CSS file like this:

<style type="text/css">
   td.results {
      padding-top: 2px;
      padding-bottom: 2px;
      border-right: 1px solid #000000;
      padding-left: 3px;
      padding-right: 3px;
      background-color: #E0DFCB;
   }
   td.results2 {
      padding-top: 2px;
      padding-bottom: 2px;
      border-right: 1px solid #000000;
      padding-left: 3px;
      padding-right: 3px;
      background-color: #FFFFF;
   }
</style>
Followed by the following type Coldfusion code:
<td class="<cfif currentrow mod 2>results<cfelse>results2</cfif>">#columname#</td>
Ok, now we are getting somewhere. I can style a number of elements besides just the background color using the class - nice! The only thing that bugs me is that "cfif" - it's so ugly. How about leveraging that little extra "feature" that comes with CFMX that allows you to encapsulate the output of an expression that results in a primitive variable. Uh... that means you can put expressions that have output right in between pound signs and the output of the expression is sent to the output buffer. For example, if you did #currrentrow MOD 2# "in-line" it would result in a 0 or a 1 being sent to the output buffer. We can use that little trick to our advantage with some creative class names like this:
<style type="text/css">
   td.results0 {
      padding-top: 2px;
      padding-bottom: 2px;
      border-right: 1px solid #000000;
      padding-left: 3px;
      padding-right: 3px;
      background-color: #E0DFCB;
   }
   td.results1 {
      padding-top: 2px;
      padding-bottom: 2px;
      border-right: 1px solid #000000;
      padding-left: 3px;
      padding-right: 3px;
      background-color: #FFFFF;
   }
</style>
Then we can simply output "results#currentrow mod 2#" in the class attribute - as in this example:
<td class="results#currentrow mod 2#">#name#</td>
      <td class="results#currentrow mod 2#">#street#</td>
      <td class="results#currentrow mod 2#">#city#</td>
      <td class="results#currentrow mod 2#">#state#</td>
      <td class="results#currentrow mod 2#">#Zip#</td>
This results in HTML output that has class="results0" followed by class="results1" for every other row. Now, some CSS guru is going to light me up and tell me how this could be done much easier using JUST CSS - no Coldfusion at all. Bring it on!

  • Share:

7 Comments

  • Giampaolo Bellavite's Gravatar
    Posted By
    Giampaolo Bellavite | 9/27/05 5:58 PM
    With only CSS you can use the td:even and td:odd pseudo-selectors, but they aren't supported by Internet Explorer.

    A better way for doing what you write is:

    /* css --- */
    tr.even td {
    background-color:red;
    }
    tr.odd td {
    background-color:green;
    }

    /* CFML --- */
    <tr class="<cfif currentrow mod 2>even<cfelse>odd</cfif>">
    <td>#myColumnName1#</td>
    <td>#myColumnName2#</td>
    <td>#myColumnName3#</td>
    </tr>
  • mark's Gravatar
    Posted By
    mark | 9/27/05 6:35 PM
    Giampaolo - I've tried it with a class in the <tr> tag - but I've can't always seem to get it to work. Is there a trick to working with the "tr" tag?

    Nice tip on the odd/even thing by the way. Maybe ie7 will support more of these features.
  • Neculai Macarie's Gravatar
    Posted By
    Neculai Macarie | 9/28/05 6:28 AM
    Mark - I think the trick is the "tr.class td" selector which is more specific then a simple "td". I'm actually using a function that returns the class for the row: <tr class="#getPagingNextClass( CurrentRow )#"> because the #currentrow mod 2# syntax doesn't work in CF5.

    Giampaolo - :nth-child() pseudo classes are part of CSS3 Selectors module and I suspect it will be a while before IE supports that (they announced improved support for CSS 2.1 for IE7).
  • Mark's Gravatar
    Posted By
    Mark | 9/28/05 6:46 AM
    Neculai - so I I did tr.results0 td { ... } and tr.results1 td {... } I could then JUST define the class inside the TR tag. Gotcha - thanks!
  • john ivanoff's Gravatar
    Posted By
    john ivanoff | 9/28/05 5:08 PM
    how about this?

    <style type="text/css">
    table{
       border: 1px solid #000;
       border-right: 0px solid #000;
    }
    tr{
    background-color: #E0DFCB;
    }
    .results1 {
       background-color: #fff;
    }
    td{
    padding: 2px 3px;
    border-right: 1px solid #000;
    }
    </style>

    --- table ---- final html to look like.....

    <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    </tr>
    <tr class="results1">
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    </tr>
    <tr>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    </tr>
    <tr class="results1">
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    </tr>
    </table>

    this isn't 'valid' xhtml but i hopr it helps look ok in firefox and ie on win
  • john ivanoff's Gravatar
    Posted By
    john ivanoff | 9/28/05 5:10 PM
    sometime me english is ungood.
  • Mark's Gravatar
    Posted By
    Mark | 9/28/05 5:17 PM
    John - your code is fine and it works, but I'm not so sure it is better than simply alternating classes. Thanks for the input though - every little bit helps my understanding and enhances my blog :)