How do I write a preprocess_node function to add a class to every second/third node it generated?

Scenario: add .last to every 2nd node, so that i can apply margin-right: 0; for the last column in the row.


For node listings for which the node.tpl.php (or a different node template) is being used you have variables like $zebra and $id at your disposal that you can use for this kind of tasks. You can see all the available variables with descriptions in the node modules node.tpl.php file or here.

For example if you want to add the necessary class to this line:

<div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>

you could use code snippets like these:

  • <?php $classes .= ' '.$zebra; ?> - add 'odd' to every first and 'even' to every second node in the list
  • <?php if (!($id % 2)) $classes .= ' last'; ?> - add 'last' class to every second node.
  • <?php if (!($id % 3)) $classes .= ' last'; ?> - add 'last' class to every third node.
  • hm, couldn't find where they have this $zebra function in the core module, need to edit that for every 3third – devric Mar 3 '12 at 1:42
  • 2
    @devric You shouldn't edit the core. I added code snippets to my answer that you can use instead (easier and better). – Madis Mar 3 '12 at 9:31
  • nice! much easier that what i was about to do,...which was trying to use preprocess function to do so. – devric Mar 5 '12 at 13:01

Sounds like you want to use the :nth-child(N) CSS selector:

.table-class td:nth-child(even) {
  margin-right: 0;

Or even better:

.table-class td:nth-child(2) {
  margin-right: 0;

The selector does this:

This pseudo-class matches elements on the basis of their positions within a parent element’s list of child elements. The pseudo-class accepts an argument, N, which can be a keyword, a number, or a number expression of the form an+b.

The selector works on a one-based index, not zero, so "even" will work if you've only got 2 columns; you'd be better using the second example though, which specifically targets the second <td> of a parent <tr> within the given table.

  • using pseudo class is too risky, unless there is absolutely no way to do it from the backend. – devric Mar 3 '12 at 1:33
  • The only real problem with :nth-child is that we still have the greatest-ever browser - IE - alive. IE 8 and below doesn't support that (at least, I don't know what's up with IE9). So if you would like to use that, you have to use a polyfill like Selectivizr (selectivizr.com). – Scorchio Mar 3 '12 at 9:46
  • @scorchio ie7 and below don't support alpha transparency properly - do you therefore never include transparent images in a website because those browsers still exist? I would argue no. If people want to live in the dark ages that's their problem...if everybody dropped this "we must support every version of ie with every website" attitude then the users of those browsers would start seeing a lot more websites that don't work properly...and would be encouraged to upgrade to a real browser :) – Clive Mar 3 '12 at 10:06
  • 1
    @Clive :D really, no - if I really want to support IE with a site I use CSS3 PIE, which provides a fix for those transparency issues. But see, I've just added that comment for completeness sake. Nowadays I don't even bother to test with IE - I work with Chrome (dev) most of the time and tell folks to get a sane browser as soon as I see them using IE. :) – Scorchio Mar 3 '12 at 12:38
  • if i really need to do it that way, i rather use jQuery to select it and use a normal class name. keep in mind that CSS pie will heat up cpu for slower pc when you use it a lot, and you will definitely be tempted to use a lot. @Clive, ie6-7-8 you need to use -ms-filter to achieve alpha. – devric Mar 5 '12 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.