Fall Sale! Code FALL2024 takes 25% OFF our Pro Plugins & Books »
Web Dev + WordPress + Security

Horizontally Sequenced Display Order for WordPress Posts in Two Columns

Most WordPress-powered blogs display posts in sequential order within a single column. Like this, for example:

[ Diagram: Default WordPress Post Display Order ]

But what if you wanted to display your posts in two columns, sequentially ordered from left to right? For example:

[ Diagram: Horizontally Sequenced WordPress Post Display Order ]

This is easily accomplished using two default loops and the rewind_posts() function. The first loop will display the posts in the first column, while the second loop will display the posts in the second column. To do this, we use PHP’s modulus operator to filter out every other post from the first loop, which will display posts as follows:

  • the first most recent post
  • the third most recent post
  • the fifth most recent post

..and so on. Meanwhile, the second loop will feature all of the posts that were filtered out of the first loop:

  • the second most recent post
  • the fourth most recent post
  • the sixth most recent post

and so on, depending on the specified number of displayed posts. As you can see, this configuration divides the posts into “odd” and “even” groups. Note that there is nothing inherently “odd” or “even” about the posts in either group; we are arbitrarily assigning “oddness” and “evenness” based on location of each post within the default sequence. Thus, posts with odd-numbered IDs may appear in the “even” loop and vice versa. having said that, let’s examine the code that will make this happen:

<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>

<div id="left-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>

<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>

<?php $i = 0; rewind_posts(); ?>

<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

<div id="right-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>

<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>

With that code in place, oddly numbered posts will appear within a division identified with an attribute of id="left-column". Likewise, even-numbered posts will appear within a division identified with an attribute of id="right-column". Thus, we may apply the following CSS to position the divisions as two adjacent columns:

div#left-column {
	width: 333px;
	float: left;
	clear: none;
	}
div#right-column {
	width: 333px;
	float: right;
	clear: none;
	}

Of course, when it comes to configuring the WordPress loop and styling your page with CSS, anything is possible. Feel free to experiment and adapt this technique to suit your own diabolical purposes ;) For now, let’s continue with an explanation of the functionality behind this dual-loop technique.

Technical Breakdown

Perhaps the most straightforward way to explain the dual-loop code is to break it down line-by-line via comments placed within the code itself:

// initiate the default wordpress loop as usual
<?php if (have_posts()) : while(have_posts()) : 

// set a count variable to increase with each loop
$i++; 

// test the variable modulus against a zero value
// odd values return true, even values return false
// see proceding discussion for more information
if(($i % 2) == 0) : 

// skip to next post if variable is an even number
$wp_query->next_post(); 

// display the post if variable is an odd number
else : the_post(); ?>

// open a division for the left column
<div id="left-column">

// display the title of the post
<h1><?php the_permalink(); ?></h1>

// display the post content
<?php the_content(); ?>

// close the division
</div>

// close the first if statement
<?php endif; 

// close the loop
endwhile; 

// if there are no posts that meet the criteria
else: ?>

// display some alternate content
<div>Alternate content</div>

// close the second if statement
<?php endif; ?>

// reset the count variable to zero
<?php $i = 0; 

// reset the loop
rewind_posts(); ?>

// the second loop is essentially the same as the first
// the only difference is that we are testing the count variable against a non-zero value to display only even numbers
<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

// and of course a unique div id for the right column
<div id="right-column">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>
</div>

<?php endif; endwhile; else: ?>
<div>Alternate content</div>
<?php endif; ?>

As for the crazy PHP modulus operator ( % ), suffice it to say that its purpose is to test the oddness or evenness of the $i variable. The modulus operator returns the numerical remainder resulting from the division of the $i variable by the specified number (“2” in this case). In the first loop, because all even post numbers are evenly divisible by two, the modulus is equal to zero and thus the evenly numbered posts are skipped until the next loop. In the second loop, the odd post numbers are not evenly divisible by two, resulting in a non-zero numerical remainder. Thus, in the second loop, we test that the modulus is not equal to zero, thereby skipping the oddly numbered posts. Perhaps this numerical pattern will help clarify the concept:

  • Post #1: $i = 1 [remainder of 1/2 = 1]
  • Post #2: $i = 2 [remainder of 2/2 = 0]
  • Post #3: $i = 3 [remainder of 3/2 = 1]
  • Post #4: $i = 4 [remainder of 4/2 = 0]
  • Post #5: $i = 5 [remainder of 5/2 = 1]
  • Post #6: $i = 6 [remainder of 6/2 = 0]
  • Post #7: $i = 7 [remainder of 7/2 = 1]
  • Post #8: $i = 8 [remainder of 8/2 = 0]

From this we can see how testing the modulus against zero (or non-zero) results in two groups of (odd and even) numbers. For more mental torture, here is more information on the PHP modulus operator. But enough of this boring math stuff — let’s move on, shall we?

Pure CSS Method

As the astute reader may have observed, displaying two columns of horizontally sequenced posts is also possible using a single, default WordPress loop and a little bit of CSS. Consider the following code:

<div id="container_division">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

<div class="post-block">
<h1><?php the_permalink(); ?></h1>
<?php the_content(); ?>


</div>

<?php endwhile; else: ?>
<?php endif; ?>
</div>

With each post enclosed within a “post-block” division (i.e., <div class="post-block">), we can achieve a two-column post-display similar to that generated via the dual-loop method by declaring a width for each of the post blocks and then placing them within a fixed-width container division. Or, to express this idea visually:

[ Diagram: Two Columns of Horizontally Sequenced Divs ]

With all of the post-block divisions floated to the left, they will automatically “stack” according to the diagram. Here’s an example of CSS that would make this work:

div.post-block {
	width: 333px;
	float: left;
	clear: none;
	}
div#container_division {
	width: 700px;
	}

As useful as this “pure-CSS” technique happens to be, it is not as flexible as the dual-loop version. Independently functioning loops provide greater control over layout and thus greater design flexibility. For example, using two individual loops, the post columns need not appear side-by-side, but may be placed anywhere on the page.

Peace Out

That’s it for this Perishable Press tutorial. If you have any questions, concerns, or criticisms, please share them in the comments section for this article. As always, thanks for reading! :)

About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
The Tao of WordPress: Master the art of WordPress.

58 responses to “Horizontally Sequenced Display Order for WordPress Posts in Two Columns”

  1. @Martin: no problem, my articles tend to be rather long!

    @Matt: I think the easiest way to accomplish a three-column horizontal layout would be to use the CSS method described in the second half of the post. Let me know if you need any help with this.

  2. Hi i want to use this code on my blog. but not for all post.

    I want 3 or 4 full posts and then post in double column

    How?

  3. Hi Jeff,
    first of all very nice site! I’ve read a couple of articles before coming to this page. So I subscribed to your RSS feed.
    Now for the purpose of this comment: I noticed nobody asked where you have to paste this code, so my question will seem stupid… Where do I paste this code? In a theme file or WordPress core files? Or is this tutorial for people building their own themes from scratch?
    I read the article 3 times and I couldn’t find the answer to my question. Everything else is very easy to understand, in my defense. :D And you explained it well, in my offense. LOL
    Thanks in advance,
    Tony. (I hope you don’t mind the keyword phrase in the name field)

  4. Thanks for the explanation Jeff. I will try it on my local test site when/if I feel that I’m up to the task. And no offense taken, we all start somewhere, and there’s always someone more knowledgeable than us, no matter how smart we think we are. hehe
    Sorry about the name thing. I don’t want to look like a spammer. I’m just new (read stupid). Thanks for being honest about it.

  5. Jeff Starr 2008/10/29 4:34 pm

    Any time, Tony — you are always more than welcome here! Thanks for the follow-up comment! :)

  6. Jeff Starr 2008/10/29 4:03 pm

    Hi Tony, thanks for the kind words, but to be honest, the keyword commentator link is a bit much.. I tend to delete comments like this, but since you seem genuine, I will let it slide. [Update: at Tony’s request, I have replaced the keywords with his name]

    As for the location in which this code must be placed, that would depend on your setup. Typically, you put the PHP/XHTML in one or more of your theme files, and then place the CSS in the theme’s CSS file.

    You do raise a good point with this comment; I tend to assume a certain level of familiarity with web design for my readers, but perhaps I should take the time to reach down a little further.. (no offense intended!;)

  7. I seriously don’t understand the logic behind the “I use dirty keywords linking in my comment – suggesting that the purpose of my whole comment is to abuse PP’s ranking – but I apologize for being a jerk at the end.

    You wouldn’t drive into someone’s house on your motorcycle, have a nice conversation with the house owner, and then leave a complete mess behind you and just say “oh I hope you don’t mind “.

    That’s unpolite as hell, and worst, that’s illogical to me!

  8. Jeff Starr 2008/11/02 9:17 am

    @Louis: I agree with you, but Tony has taken the time to email me about this with a request to replace the keywords with his name. From his email, I think he is sincere and that the mistake was genuine. Thanks for keeping ‘em honest, though! ;)

  9. Thanks Jeff!

  10. Hi, I just found your blog tonight and it’s certainly bookmark worthy, so thanks!

    Compliments aside, I’m having problems with this tut. The container div is conflicting with the content div of the theme I’m using. Surely I’m not doing this correctly, so if anyone can help me with this it would be greatly appreciated!

    I want to use the 2nd method in this tut because I want to simply stack 4 columns instead of the two given in the first method. Perhaps this just doesn’t work anymore with the latest version of WP? Either way, if you can push me in the right direction – thanks in advance :]

    Chris

  11. Chris> Sounds like you already know that you’ll have to fix the container div conflict you’ve got. Can’t have 2 divs with the same ID and expect them to behave differently, so you’ll have to rename one of them and update the CSS to reflect the name change accordingly.

    I used the Pure CSS method above (if that’s what you meant by 2nd method). It’s just maths really – take your container width and divide it up into as many columns as you need. Don’t forget to include any padding/margins in your calculations!

    Hope this helps.

  12. Martin: Both of the divs have different IDs, but the problem seems to be with how the ‘content’ div handles what the new div ‘container_division’ lists. It causes the content div to act like it has no actual content in it and just shows the header with the footer directly underneath. Perhaps this will be solved by setting a height to the content div, but i haven’t tried anything yet in hope someone can provide me with a legitimate fix. Hopefully you understand my problem somewhat more and can give me some more advice. Thanks so far :]

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
The Tao of WordPress: Master the art of WordPress.
Thoughts
I disabled AI in Google search results. It was making me lazy.
Went out walking today and soaked up some sunshine. It felt good.
I have an original box/packaging for 2010 iMac if anyone wants it free let me know.
Always ask AI to cite its sources. Also: “The Web” is not a valid answer.
All free plugins updated and ready for WP 6.6 dropping next week. Pro plugin updates in the works also complete :)
99% of video thumbnail/previews are pure cringe. Goofy faces = Clickbait.
RIP ICQ
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.