Highlight alternating items in Liquid templates

How to apply alternating styles in Liquid loops—but you probably should just use the CSS :nth-of-type(odd) selector.

I wanted to apply alternating stylings for my blog’s index page, similar to highlighting alternate rows in a table.

In my first attempt below, I used increment to create a counter variable. Each time through the loop, I’d increment it and divide by two. When the remainder was a 1, an additional class was applied to the div.

This worked, but increment returns it’s value which mucked up my html.

<div class="page blog-index">
  <h1>Blog</h1>    
    {% for post in site.posts %}
      {% increment counter %}
      {% assign alternate = counter | modulo: 2 %}
      <div class="listings {% if alternate == 1 %} alternate {% endif %}">
        <h4><a href="{{ post.url }}">{{ post.title }}</a> | {{ post.date | date: '%B %d, %Y' }}</h4>
        <p>{{ post.excerpt }}</p>
      </div>
    {% endfor %}
</div>

If at first…

My second attempt eliminated increment in favor of creating a counter variable (via assign) and incrementing the counter variable myself. This worked, although it was inelegant and unnecessarily complex.

<div class="page blog-index">
  <h1>Blog</h1>
    {% assign counter = 0 %}    
    {% for post in site.posts %}
      {% assign alternate = counter | modulo: 2 %}
      <div class="listings {% if alternate == 1 %} alternate {% endif %}">
        <h4><a href="{{ post.url }}">{{ post.title }}</a> | {{ post.date | date: '%B %d, %Y' }}</h4>
        <p>{{ post.excerpt }}</p>
      </div>
      {% assign counter = counter | plus: 1 %}
    {% endfor %}
</div>

Best approach

While reviewing CSS selectors, I came across the nth-of-type selector which lets you select the specified nth child, odd, or even.

This allowed me to eliminate four lines of Liquid that were cluttering up my for loop.

.blog-index .listings:nth-of-type(odd) {
  border-left: 5px solid #CCA400;
}