Zebra Striping

Let’s kick off with something easy—zebra stripes! What’s that, you ask? It’s what we call it when rows alternate between two colors, usually light and dark. Here’s an example:

Zebra Stripe Example

Contrasting row colors make it much easier to read. The reader’s eye can easily follow along the row to associate the state with the dollar amount. It’s a useful technique whenever you are outputing reports or lists of data. I’ll demonstrate three ways to do it.

In all three solutions, the first step is to use CSS to set the background style of either a table row or a div. I’ll use a table row in my examples. And my two colors will be white (#FFFFFF) and gray (#CCCCCC). (Other good colors to use are #E2E2E2, a lighter gray for subtle contrast, and #999999, a darker gray for stronger contrast.)

We can do that with inline styles:

1
<tr style="background: #FFFFFF;"><td>content</td></tr>

Or with a class:

1
<tr class="odd-row"><td>content</td></tr>

As we output rows in a loop, that will give us all rows with white backgrounds. It’s a style placeholder until we add the contrasting color and make it dynamic. Next, we’ll need a way to keep track of which row we are on. Here’s where the three solutions diverge.

Solution 1: Counting Rows

We can initialize a counter variable and then add one to it each time the loop progresses. Then each time we loop through the code we can test whether the counter value is even or odd and display a different background color based on the result. (I’ll leave it up to you whether to output the whole row in each case or just vary the background color or style.)

Modulo is perfect for this test. Modulo returns the remainder of division: the modulo of dividing 22 by 7 is 1, the modulo of dividing 21 by 7 is 0. We’ll use modulo to divide our counter by 2 and get the remainder. If the remainder is 0 then the counter divided evenly and is an even number; if not, it’s an odd number.

In PHP, we can use fmod (floating point modulo).

1
2
3
4
5
6
7
8
9
10
11
12
<?php // PHP version
  $i = 0;
  // have_rows_to_output is a stand-in for your loop's code
  while (have_rows_to_output) {
    if (fmod($i, 2) == 0) { // it's an even number
      output_even_style_row;
    } else { // it's an odd number
      output_odd_style_row;
    }
    $i++;
  }
?>

Ruby has a modulo function too: i.modulo(2) or i % 2. But if we are using Rails then we can also take advantage of even? which does the same thing.

1
2
3
4
5
6
7
8
9
10
11
<% # Rails version
  i = 0
  for (row in @rows_to_output)
    if i.even?          # same as (i % 2 == 0)
      output_even_style_row
    else
      output_odd_style_row
    end
    i += 1
  end
%>

Solution 2: Rocking Values

Instead of counting the rows, you could instead alternate your counter between two values. It’s worth looking at because, beyond zebra striping, this technique can be useful for anytime you need to “rock a value” back and forth while going through a loop.

We could write an if-statement that would test and assign true/false or “even”/”odd” as the values, but the easiest way is just to use 0 and 1. That way, instead of incrementing our counter, we’ll subtract the counter from 1 to “rock it” to the other value. We can skip the modulo/even/odd test because the counter will always be either 0 or 1. It will make more sense if we look at a loop and walk through a few iterations.

1
2
3
4
5
6
7
8
9
10
11
12
<?php // PHP version
  $i = 0;
  // have_rows_to_output is a stand-in for your loop's code
  while (have_rows_to_output) {
    if ($i == 0) {
      output_even_style_row;
    } else {
      output_odd_style_row;
    }
    $i = 1 - $i;
  }
?>

The only change is in the last line. The first time through the loop, $i is 0. Then $i gets set to 1 - 0 which is 1. The next time through the loop, $i is 1. Then $i gets set to 1 - 1 which is back to 0. And so on.

1
2
3
4
5
6
7
8
9
10
11
<% # Ruby/Rails version
  i = 0
  for (row in @rows_to_output)
    if i == 0
      output_even_style_row
    else
      output_odd_style_row
    end
    i = 1 - i
  end
%>

Solution 3: Cycle values (Rails only)

If you are using PHP or Ruby on its own, then you’ll need to stick with first two solutions, but if you are using Rails, there is a very cool, much easier solution. Rails has a method called cycle. Cycle creates an object that increments every time it is called. So we won’t need a counter at all! No counter initializing, no counter incrementing. And because cycle can store the values we want to alternate between, we can skip the if-statement tests too! We can cut straight to the chase and use the values we want.

1
2
3
4
5
6
<% # Rails only
  for (row in @rows_to_output) %>
    <tr style="background: <%= cycle('#FFFFFF', '#CCCCCC') %>;">
      <td>content</td>
    </tr>
<% end %>

As a bonus, cycle will take more than two values. So you can have it alternate between three colors or every color in the rainbow.

Final thoughts

One parting note, if your listing has a header row, make sure your first row background color contrasts with the header background color.

Bad Contrast Good Contrast
Zebra Bad Contrast Zebra Good Contrast

Pick the technique that you like best and stick with it. But whichever you choose there’s no excuse for not having easily readable rows of information in your web application from now on.

Bookmark and Share

One Response to “Zebra Striping”

  1. Jessica Enders Says:

    Hello

    As someone who has written about zebra striping in the past, I thought you might be interested in this video.

    http://au.video.yahoo.com/video/play?vid=1472613

    It’s about a study I have done into whether zebra striping actually improves readability.

    Feel free to contact me for more information.

    Warm regards,
    Jessica

Leave a Reply