Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsIn a classic WordPress theme, initialize a counter before the Loop, calculate an odd or even class for each rendered post, and pass that class to post_class() on the post wrapper. WordPress then combines your class with its normal post classes.
Classic theme method: add the class in the Loop
Put the counter immediately before the specific post loop. The example below starts counting at zero, so the first rendered post receives even, the second odd, and so on.
<?php
$index = 0;
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
$parity_class = ( 0 === $index % 2 ) ? 'even' : 'odd';
?>
<article <?php post_class( $parity_class ); ?>>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php the_excerpt(); ?>
</article>
<?php
++$index;
endwhile;
endif;
?>
post_class() prints the complete class attribute for the current post and accepts one or more additional class names. The function was introduced in WordPress 2.7.0. See the official post_class() reference.
Style the two classes
.post-list .odd {
/* Styles for alternating odd entries */
}
.post-list .even {
/* Styles for alternating even entries */
}
Apply post-list to the element containing the articles, not to each article. The custom class belongs on the post container, commonly an article or div, where WordPress expects dynamic post classes.
#1 Best Overall
- Used Book in Good Condition
Make the first item “odd” instead
“Odd” and “even” are naming conventions; CSS does not assign meaning to either label. To call the first item odd, start the counter at one or reverse the condition:
$index = 1;
$parity_class = ( 0 === $index % 2 ) ? 'odd' : 'even';
Increment the counter once after each post is output. Do not increment it for markup outside the loop, or the alternation will drift from the visible list.
Rank #2
Keep the counter tied to the posts users actually see
The Loop renders its markup once per post, so the counter should sit inside the same loop that produces the list. For two independent lists on one page, use a separate counter for each list when each alternation should restart at its first entry.
If a custom query or conditional skips a post before rendering, increment only when that post is actually output. This keeps the class sequence aligned with the visible entries rather than with records examined by the query.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Use get_post_class() when you need the class array
When code needs to inspect, modify, or pass classes elsewhere, use get_post_class(). It returns the generated class names as an array and accepts a post ID or post object; the current post is used when no post is supplied. The result includes core post information and passes through the post_class filter. Read the get_post_class() reference.
<?php
$classes = get_post_class( array( $parity_class ) );
$classes[] = 'featured-layout';
?>
<article class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>">
...
</article>
For ordinary templates, calling post_class( $parity_class ) is simpler and lets WordPress handle attribute output and escaping.
Rank #4
Centralize logic with the post_class filter
The post_class filter receives the generated classes, the classes supplied to post_class(), and the post ID. Its arguments do not include a loop index, so a filter cannot know a post’s position unless your code provides that position through another reliable mechanism. Consult the post_class hook reference before adopting this approach.
A filter is useful when one class rule should apply across many templates, but a local counter is usually easier to audit because the position is visible beside the loop that renders it.
Best Value
- Keep track of everything from attendance to test scores
- Spiral bound
- Measures 8-1/2" x 11"
CSS-only alternation with :nth-child()
If the effect is purely visual and the list markup is stable, CSS can stripe direct article children without adding PHP classes:
.post-list > article:nth-child(odd) {
/* First, third, fifth ... */
}
.post-list > article:nth-child(even) {
/* Second, fourth, sixth ... */
}
This keeps the HTML free of parity classes, but the selector depends on the articles remaining direct children of .post-list. Inserted notices, wrappers, or other child elements can change the pattern. It also does not provide a semantic class for JavaScript, integrations, or other server-side logic.
Block themes and the Query Loop
In a block theme, the Query Loop block repeats content through its Post Template block. Its documented Advanced settings let you add a static value under “Additional CSS Class(es)” to the block, but the documentation does not provide a native per-post odd/even class control. See the Query Loop block documentation.
Use a static block class when you only need to target the whole query. For per-entry alternation, choose a CSS structural selector when the generated markup is dependable, or implement the list in a PHP template where you control the counter and post wrapper.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choosing the right approach
| Approach | Best when | Trade-off |
|---|---|---|
post_class() plus a PHP counter |
The class must appear in rendered HTML and the theme uses a classic PHP loop | You must maintain the counter in the correct loop |
CSS :nth-child() |
Alternation is visual only and the list’s direct-child markup is stable | No semantic HTML class; DOM changes can alter the pattern |
| Query Loop block class setting | A block theme needs a static class on the block or repeated template | Documented settings do not show dynamic odd/even classes per post |
Checklist before you publish
- Place the counter before the exact loop that renders the list.
- Increment it once for every post container output.
- Decide whether the first visible entry should be named
oddoreven. - Call
post_class()on each post wrapper, not on the outer list container. - Use a separate counter when separate lists should restart their alternation.
- Keep class names consistent between PHP and CSS; WordPress escapes additional names when generating the class list.
WordPress documents the Loop as the default mechanism for outputting posts through theme template files in its Theme Handbook explanation of the Loop. Its guidance on dynamic post styling likewise places post_class() around each post; see the Post Formats documentation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

