New Bookstore! Save 20% on books with discount code: LAUNCH
Web Dev + WordPress + Security

Multiple Loops and Multiple Columns with WordPress, (X)HTML and CSS

Recently, I have been getting a lot of requests for multiple-loop configurations in WordPress. It seems that multiple-column, multiple-loop configurations are in high demand these days, especially ones that display posts like this:

  • First column, first loop: display posts #1-5
  • Second column, second loop: display posts #6-10
  • Third column, third loop: display posts #11-15

Using WordPress and a little CSS, this configuration is relatively easy to accomplish. Let’s cut right to the chase..

Step 1: Multiple-Loop, Multiple Column PHP Configuration

The first thing we want to do is replace the standard WordPress loop with the following code:

// FIRST LOOP: display posts 1 thru 5
<?php query_posts('showposts=5'); ?>
<?php $posts = get_posts('numberposts=5&offset=0'); foreach ($posts as $post) : start_wp(); ?>
<?php static $count1 = 0; if ($count1 == "5") { break; } else { ?>

<?php the_title(); ?>
<?php the_content(); ?>

<?php $count1++; } ?>
<?php endforeach; ?>

// SECOND LOOP: display posts 6 thru 10
<?php query_posts('showposts=5'); ?>
<?php $posts = get_posts('numberposts=5&offset=5'); foreach ($posts as $post) : start_wp(); ?>
<?php static $count2 = 0; if ($count2 == "5") { break; } else { ?>

<?php the_title(); ?>
<?php the_content(); ?>

<?php $count2++; } ?>
<?php endforeach; ?>

// THIRD LOOP: display posts 11 thru 15
<?php query_posts('showposts=5'); ?>
<?php $posts = get_posts('numberposts=5&offset=10'); foreach ($posts as $post) : start_wp(); ?>
<?php static $count3 = 0; if ($count3 == "5") { break; } else { ?>

<?php the_title(); ?>
<?php the_content(); ?>

<?php $count3++; } ?>
<?php endforeach; ?>

That’s the juice right there. We have three loops, each displaying five posts. The first loop displays the first five posts, the second loop displays the next five posts, and the third loop displays the next five posts. Thus, this multiple-loop configuration displays the most recent 15 posts, each of which being unique.

To change the number of posts displayed for any given loop, you will need to edit three different arguments:

  • showposts=5
  • numberposts=5&offset=0
  • $count1 == "5"

Notice the pattern here: for the first loop, we are showing the first five posts. The number of posts is set by the showposts=5, numberposts=5, and $count1 == "5". The first two arguments are self-explanatory, and the third simply stops the loop when the indicated number of posts has been processed.

Thus, to change the number of posts displayed in the first loop, change the number “5” to the desired number of displayed posts. After that, you need only specify the loop offset parameter, which lets WordPress know how many posts to skip before displaying the specified number of posts.

For example, an offset value of “0” is used in the first loop so that no posts are skipped and the first five posts are displayed. Then, because the first loop displays the first five loops, we use an offset value of “5” in the second loop so that the loop skips over the first five posts and displays the next five posts in the sequence. Likewise, an offset value of “10” in the third loop ensures that the first 10 posts displayed in the first two loops are not repeated. Thus, if you wanted to display 10 posts in the first loop, the offset value in the second loop would be “10”.

Step 2: Multiple-Loop, Multiple Column (X)HTML Configuration

Now that we have the PHP in place, we are ready to add the (X)HTML markup required for the final three-column configuration. There are many ways to accomplish this, this is merely one of them:

<div id="column_01">

	<!-- FIRST LOOP -->


<div id="column_wrap">

	<div id="column_02">

		<!-- SECOND LOOP -->

	<div id="column_03">

		<!-- THIRD LOOP -->


Here, each of the three loops will be placed into its own div, which then will be styled with a little CSS to transform it into one of the three columns. Note that you may want to change the id names of the divisions to better represent the particular semantics of your document. Now let’s move on to the CSS..

Step 3: Multiple-Loop, Multiple Column CSS Configuration

The final step in the tutorial is to style the markup with CSS. Nothing too fancy, really. Creating the columns is merely a matter of floating the individual divs and applying a width to each of them:

/* three column layout */
div#column_01 {
	float: left;
	clear: none;
	width: 30%;
div#column_wrap {
	float: right;
	clear: none;
	width: 60%;
	div#column_02 {
		float: left;
		clear: none;
		width: 45%;
	div#column_03 {
		float: right;
		clear: none;
		width: 45%;

The trick here is to use width values that will create the correct column widths. The values used in the example produce three columns of approximately equal width. A great way to check how your width values are actually affecting layout is to add the following line of code to each selector:

border: thin solid red;

Adding that declaration to each of the four code blocks will create an outline around each of your divisions, enabling you to see easily the amount of space between each column. I use this trick all the time — it’s a real time-saver. Beyond that, you may specify the width in any units that you wish (e.g., em, px); no need to stick with percentages!

Warp Speed..

There is SO much you can do with WordPress, PHP, (X)HTML, and CSS. The possibilities are virtually endless. The multiple-column configuration presented in this article is a great starting point for creating more elaborate and sophisticated page layouts. Experiment and have fun!!

Jeff Starr
About the Author
Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
USP Pro: Unlimited front-end forms for user-submitted posts and more.

31 responses to “Multiple Loops and Multiple Columns with WordPress, (X)HTML and CSS”

  1. Jeff Starr
    Jeff Starr 2008/10/19 2:54 pm

    My pleasure, damir — thanks for the positive feedback! :)

  2. dear jeff,

    i’ve tried this method on xampp, and it works. but the problem is when i click the next page, it displayed the same post in the first page. can you help me out here?


  3. Hi Jeff:

    i need to develop a website with posts in two columns (the center column and a sidebar column for certain categories) but i need to limit the words in the sidebar posts to mantain the design, i’ve try with the excerpt, but this limit to a few words and no apply to images, there is a code you can bring me to make this?

    Im running 2 loops with diferent queries and i need help on this

    thanks in advance


  4. Jeff Starr
    Jeff Starr 2008/10/29 4:11 pm

    @LuisRaa: Have you looked into using the excellent Excerpt Reloaded plugin (404 link removed 2013/10/15)..? With it, you can configure just about anything you need, including excerpt length, type, format, and much more..

  5. hi jeff, can u solve the paging problem?

  6. Jeff Starr
    Jeff Starr 2008/11/02 9:10 am

    @nazerry: ..and which paging problem might that be..? If you are referring to the infamous next_posts_link and previous_posts_link paging problem, I would recommend a thorough search on Google. The issue is very problematic for many people and I have only discovered temporary workarounds that I cannot recommend to the public..

  7. Very nice and informative!
    Will definitely use this on the theme I am working on now!

  8. Great article… just what I’m looking for. I keep coming back to your site to learn a thing or two or three. I modified your complete code above to display excerpts and images for a category page I have (I’m going for a “grid” view). In comment #7 above, you suggest to Binh to modify query_posts() with the category parameters. I want to do the same thing, but I can’t seem to get it to work. I changed it to read query_posts(‘cat=13&showposts=5’) but it still shows the last 15 posts of all categories.

    What might I be doing wrong?

  9. I want to do the same thing with a category template. How can I do this? cause right now it won’t show posts from that particular category

  10. Jeff Starr
    Jeff Starr 2008/11/17 9:33 am

    @davebach, @Muffin: Perfect timing for both of you! I was getting so many requests for category-specific loop filtering that I just didn’t have time for them all, so I decided to write up a complete tutorial covering the entire process:

    Fruit Loop: Separate any Number of Odd and Even Posts from any Category in WordPress

    Fresh out the oven — posted earlier today! Enjoy :)

  11. @ Jeff RE: davebach and muffin:

    Thanks Jeff, Fruit Loops is another fine tutorial… what I ended up doing to the example you give in this post (so that I can achieve a three column “grid view” using excerpts… follow link above to see) is I added “cat=” to both query_posts and get_posts in each loop. This gave me the result I wanted, however I had to reduce the count to 4 per column because I (currently) have only 12 posts in that category… if it kept looking for more posts than I had it would give an error.

    At some point I’d like to figure out how to get this into 4 columns (or rows of 4 across so that it reads newest to oldest… but I’m still learning the finer points of CSS and I couldn’t get it to look right with 4 excerpts, line break, 4 excerpts, line break, etc.)


  12. Paul Demers 2008/11/18 7:14 am

    Thanks so much for this tutorial. I am just starting to really dig into WordPress and this was a very clear explanation of a fundamental concept. Adding this site to my feedreader as we speak.


Comments are closed for this post. Something to add? Let me know.
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 »
WP Themes In Depth: Build and sell awesome WordPress themes.
Take a screenshot with Firefox (no extension required). Open Developer Tools Settings and enable the “Take a screenshot” button. Then click the button :)
Take a screenshot with Chrome (no extension required). Open DevTools, type Cmd + Shift + P, then type screenshot.
After 10 years working on my 2010 iMac, my upgrade finally arrived. Shiny new iMac shipped from Ireland :)
Too much caffeine weirds me out. But I love the taste of coffee. So once in a while I enjoy a small cup of decaf. Hits the spot.
Chris Coyier is a truly awesome person. One of the finest people I've ever worked with. Just #gottasayit
Excel won't open CSV file because SYLK format? Open it with text editor and add an apostrophe ' at the beginning of the file, save changes, done.
Displaying too many social media buttons and links all over the place imho makes you look desperate and frankly kinda sad.
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.