DiggingIntoWordPress

by Chris Coyier & Jeff Starr

6 Ways to Display WordPress Post Content in Multiple Columns

Posted by on

Most blogs display their content in single columns, but it’s also possible to display content in multiple columns. Multiple-column layouts are perfect for newspaper and magazine-style themes. Here are six ways of getting the job done.

  1. Using CSS3 and progressive enhancement
  2. Multiple columns by filtering the_content
  3. More flexible multiple columns
  4. Multiple loops displayed in multiple columns
  5. Display your posts in horizontal display order with two columns
  6. Bonus: Display your category list in two columns

1. Using CSS3 and progressive enhancement

I think the easiest way to display your content in multiple columns is to apply a little CSS3 in progressively enhancing fashion. Let’s say you have the following markup:

<div class="content">
	<p>Lorem ipsum..</p>
	<p>Lorem ipsum..</p>
	<p>Lorem ipsum..</p>
</div>

We can add the following CSS to display the content in multiple columns:

.content {
	  -moz-column-count: 3;
	  -moz-column-gap: 10px;
	  -moz-column-rule: none;
	  -webkit-column-count: 3;
	  -webkit-column-gap: 10px;
	  -webkit-column-rule: none;
	column-count: 3;
	column-gap: 10px;
	column-rule: none;
	}

This will display your content in three columns with a 10px gap between each. This technique is a great way to enhance the display of your content for people running cool modern browsers like Safari and Firefox. What about folks visiting with Internet Exploder or older browsers? They will see your content displayed in a single column, just like they would have before you applied the multiple columns. Note that you can specify any number of coulmns and any width for the gap.

2. Multiple columns by filtering the_content

If you need something a little more “universal” than what is currently available with CSS3, we can always dig into our template files, modify things at the PHP/(X)HTML level, and then style accordingly. Here is the technique provided by Kriesi.at:

function my_multi_col($content) {

	$columns = explode('<h2>', $content);
	$i = 0;

	foreach ($columns as $column) {
		if (($i % 2) == 0) {
			$return .= '<div class="content_left">'."\n";
			if ($i > 1) {
				$return .= "<h2>";
			} else {
				$return .= '<div class="content_right">'."\n <h2>";
			}
			$return .= $column;
			$return .= '</p></div>';
			$i++;
		}
		if(isset($columns[1])) {
	    		$content = wpautop($return);
		} else {
	    		$content = wpautop($content);
		}
		echo $content;
	}
}
add_filter('the_content', 'my_multi_col');

Just place that into your active theme’s functions.php file and then apply the following CSS:

.content_right, .content_left{
	float: left;
	width: 45%;
	}
.content_left{
	padding-right: 5%;
	}

Once implemented, this multi-column technique creates a a column for each instance of <h2> found within the post content. Thus, be sure to limit the number of <h2> elements to two in order to avoid layout breakage. Note that you could also modify the code to use a different element if the <h2> tag isn’t good for you. Multiple columns doesn’t get much easier, but just in case you need an alternate method for whatever reason, read on for some more great techniques.

3. More flexible multiple columns

The previous method works nice for two columns and no fuss, but for three or more columns we’re going to need something a little more robust. fortunately, Rob Searles shares a technique that allows any number of columns with completely different content in each. This technique creates columns based on multiple instances of the <!--more--> tag. There are several caveats, so check the orginal article for all the details.

Here are the steps involved in implementing this technique:

  1. Add the my_multi_col_v2 function to your functions.php file
  2. Add another snippet to your theme template file, for example page.php
  3. Add some CSS to format the markup into columns
  4. Add a couple of <!--more--> tags in your post or page to create the three columns

1. Let’s go through these steps, beginning with the main function that you should place into your theme’s functions.php file:

function my_multi_col_v2($content){
	// run through a couple of essential tasks to prepare the content
	$content = apply_filters('the_content', $content);
	$content = str_replace(']]>', ']]&gt;', $content);
 
	// the first "more" is converted to a span with ID
	$columns = preg_split('/(<span id="more-\d+"><\/span>)|(<!--more-->)<\/p>/', $content);
	$col_count = count($columns);
 
	if($col_count > 1) {
		for($i=0; $i<$col_count; $i++) {
			// check to see if there is a final </p>, if not add it
			if(!preg_match('/<\/p>\s?$/', $columns[$i]) )  {
				$columns[$i] .= '</p>';
			}
			// check to see if there is an appending </p>, if there is, remove
			$columns[$i] = preg_replace('/^\s?<\/p>/', '', $columns[$i]);
			// now add the div wrapper
			$columns[$i] = '<div class="dynamic-col-'.($i+1).'">'.$columns[$i].'</div>';
		}
		$content = join($columns, "\n").'<div class="clear"></div>';
	}
	else {
		// this page does not have dynamic columns
		$content = wpautop($content);
	}
	// remove any left over empty <p> tags
	$content = str_replace('<p></p>', '', $content);
	return $content;
}

2. Once that’s in place, replace your the_content() tag with the following code:

$content = get_the_content('',FALSE,''); // arguments remove 'more' text
echo my_multi_col_v2($content);

3. The last bit of code that we need to setup is the CSS to make it all sweet:

/* dynamic columns */
div.dynamic-col-1 { float: left; width: 38%; padding-right: 2%;}
div.dynamic-col-2 { float: left; width: 38%;padding-right: 2%;}
div.dynamic-col-3 { float: left; width: 20%;}
div.clear { clear: both; }

4. And last but not least, remember to add the two <!--more--> tags in your post/page content to create the three columns.

That’s all there is to it. Pretty good stuff, but even so, there are even more alternatives available. next we’ll look at a technique for displaying multiple loops in multiple columns.

4. Multiple loops displayed in multiple columns

Not too long ago, I wrote a post at Perishable Press explaining how to display multiple loops with multiple columns. The final product will look display something 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: Setup the multiple loops

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. See the original post for more information, options and details.

Step 2: Markup your theme template file(s)

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>

<div id="column_wrap">

	<div id="column_02">

		<!-- SECOND LOOP -->

	</div>
	<div id="column_03">

		<!-- THIRD LOOP -->
	
	</div>

</div>

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: Styling the columns with CSS

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. Again, for more information on the details of this technique, see the original post.

Once you get everything setup, your posts should display your multiple-loop content in multiple columns, with each column showing the contents of a different loop. This is a great way to customize your theme, making it possible to present lots of disparate information within an easy-to-understand layout. Even so, this technique may not do it for you either. If so, we’ve got a couple more WordPress tricks up our sleeve!

5. Display your posts in horizontal display order with two columns

That’s a mouthful, isn’t it? What we’re doing in this section is changing the order in which your two-column posts appear on the page. Typically, your two-column layout displays posts like this:

Post #1   |   Post #4
Post #2   |   Post #5
Post #3   |   Post #6
 .        |    .
 .        |    .
 .        |    .

All of the multi-column methods we’ve discussed so far result in this sort of post-display order. So now we want to change things up a bit and display our two-column posts in horizontal display order, like so:

Post #1   |   Post #2
Post #3   |   Post #4
Post #5   |   Post #6
 .        |    .
 .        |    .
 .        |    .

How is this accomplished? As explained in my horizontal-display tutorial, 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 in horizontal order.

To make this happen, first replace your default WordPress loop with the following code:

<?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 ;) As with the other methods described in this DiW post, much more information is available for this technique at the original article, including a nice, CSS-only method that is sure to leave you breathless.

6. Bonus: Display your category list in two columns

Using a little PHP magic, we can get WordPress’ wp_list_categories() to display our categories in two columns. As Blog Oh Blog (404 link removed 2013/07/10) explains, all you need is the following code placed in your theme file:

<?php // display categories in two columns
$cats = explode('<br />', wp_list_categories('title_li=&echo=0&depth=1&style=none'));
$cat_n = count($cats) - 1;
for ($i = 0; $i < $cat_n; $i++):
	if ($i < $cat_n/2):
		$cat_left = $cat_left.'<li>'.$cats[$i].'</li>';
	elseif ($i >= $cat_n/2):
		$cat_right = $cat_right.'<li>'.$cats[$i].'</li>';
	endif;
endfor; ?>

<ul class="left">
	<?php echo $cat_left; ?>
</ul>
<ul class="right">
	<?php echo $cat_right; ?>
</ul>

Just use that code where you would like the categories to appear and enjoy the results.

Wrapping it up

Hopefully these techniques will inspire and enable you to break out of the “single-column” mindset and explore some multi-column possibilities. Using multiple columns for your content is a great way to enhance the visual appeal of your design and readability of your content.

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

33 Responses

  1. Hy Jeff,
    next to CSS3, i think one of the best solutions is the plugin Page Columnist from Heiko.
    This waorks fine and it give not the problems hwo with the own functions and bad content.

    • Jeff Starr

      I should have known all of this was in vain ;)

      Thanks for the tip — I’ll add it to the growing list of multi-column possibilities.

      • Hi Jeff, Hi Everyone.

        I’m using #1 and it works great. Only thing is,
        I actually want a post split where the image shows on the left and meta(post title, etc and text) on the right.

        An perfect example is http://www.wmagazine.com/artdesign/2012/06/yoko-ono-and-sean-lennon-collaboration

        I would really appreciate any help I can get with this.

        Thank you so much.

  2. If running multiple loops I guess it would be better to use the WP_Query object instead of the query_posts tag.

    • Jeff Starr

      Good call, Michael — thanks!

    • I’m interested in the general theory here…

      Is this so the original query doesn’t get messed with? can’t you either just save that to a variable before you start or reset it with wp_reset_query() before you need to run an unaltered loop?

      I just ask because I almost never use WP_Query for querying posts, but if there is some big compelling reason to I’d like to know about it.

      • Jeff Starr

        Either method will work, as far as I know, but most WP users that I have heard from seem to think that WP_Query is better for some reason.

        I usually just stick with the variable method for multiple loops to keep the original query intact, but that’s just me.

  3. kylegetsspam March 16, 2010

    #5 is more easily done by wrapping each post in a div with a set width and then floating them all left.

  4. 20 years in the newspaper business.
    #1 is so lovely it brings a tear to my eye ;)

  5. Hello Jeff!
    Thanks for this splendied article. Regarding method 4: I have tried it, but it didn’t work. I posted the issue in WP Forum here: http://wordpress.org/support/topic/376808?replies=1

    The first loop continues into the endless and won’t break. And each post image is equal to the latest posts image, not the individual posts image (added via custom fields). It seems as the first loop just continues forever and that loop 2 & 3 never happens, and the page will not display either the sidebar nor the footer, so something must be wrong with the never ending loop. I guess.

    • Jeff Starr

      Looking at your forum post, it looks like you are using a heavily modified version of only part of the code from method #4. Even so, I just triple-checked that it works as advertised and didn’t see any endless loops or other funny business. Note that once you begin modifying the original code, it’s up to you to make it work. I would begin with the original code, verify that it works, and then build up from there.

  6. Ive been using a method i found online, which takes the idea of the {switch} code from expression engine.

    <?php // class style switch
           $style_classes = array('col','col', 'last');
           $styles_count = count($style_classes);
           $style_index = 0;
    ?>

    Then add the following code into the div

    <?php echo $style_classes[$style_index++ % $styles_count]; ?>

    Im not sure of its merits over any of the options you’ve posted here, but its worked for me.

    • Jeff Starr

      Interesting, so it looks like a different class name is echoed for each post div, correct? Then are each of the posts floated to create the columns? Otherwise it seems like you would have as many columns as you have posts. (But then again, it is pretty early for me, so I may be missing something obvious here.)

      • Jeff, thats exactly it. You can add as many class names to the array as needed.

        I apply a float left and a margin right to the .col and just a float left to the .last which gives me the 3 columns.

  7. FlossieT March 17, 2010

    Interesting. I’ve been trying to achieve something similar with wp_list_authors(), using your final suggestion – but there’s obviously something about the way wp_list_authors is put together that’s significantly different, as I end up with the authors all listed in <li>s, and then the <ul>s dumped after wards…. sigh. Baby steps here.

  8. Quick question about #4… what code do I add to limit the amount of a post shown?

    I want to do a newspaper style layout with a center column (latest post displayed in full) with smaller columns on the right and left showing the last four posts (partially displayed with the “read more…” statement.)

    The only thing I don’t know is the code to limit the amount of a post shown. Can anyone help?

  9. Thank you for this post! I’ve actually been working on a project that requires this. Good timing!

  10. Matthew Muro March 31, 2010

    I’ve written a similar function for my categories and tags that outputs everything into 3 columns.

    There were tons of tutorials on how to split everything into two columns, but nothing for three columns so I had to write my own.

    Hope that helps someone!

  11. Yeah that’s great but is there any easier method to get the two column look? Some plugin or something else? Regards

  12. hello,

    i need help on this as i’ve already tried many times.
    i want to do:
    5) Display your posts in horizontal display order with two columns

    where my products can be made of two columns.
    is there anyone out there who is willing to help me on this?

    i will b real grateful!
    thanks so much!

  13. Fantastic post. In fact, the most detailed and comprehensive post about columns in wordpress I found on the net. Well done!

    I have a question about example 5, though.

    Where should I add the code for previous and next post navigations? Here is a simple example:

    <?php endwhile; ?>

           <div class="navigation">
                  <span class="previous-entries"><?php next_posts_link('Previous Entries') ?></span> <span class="next-entries"><?php previous_posts_link('Next Entries') ?></span>
           </div>

    <?php else : ?>

    Should I add this for each column, or is there a way it would make sense for the entire page as a whole, considering both left and right column?

    Once again congratulations on the post.

  14. I **THINK** found out an error on the example 5

    I have added 3 posts, and instead of them following this listing:

    Post #1 | Post #2
    Post #3 |

    It is following this instead:

    Post #1 | Post #2
    | Post #3

    Any ideas?

    • Just a quick one: I used the web developer plug-in of FireFox and I found out that this is what is happening

      left-column | left-column
      right-column | right-column
      left-column | left-column
      ... | ...

      Now I did exactly what has been explained in example 5. I simply copy and pasted the code into my index.php file (replacing the loop for posts with this code) then I added the provided CSS at the bottom of my CSS file. But the result I get is the above… I tried to move the provided CSS code to the top of my CSS file (after body of course) but it didn’t work either…

      Any ideas? Any help is greatly appreciated.

  15. Manda May 16, 2010

    I love these techniques but I have a problem as my posts excerpts are different lengths so I get a lot of vertical white space between some of the posts. Is there any way to force the posts to sit on top of each other when the posts are of different lengths?

    Thanks

  16. salsa May 18, 2010

    I love you!!!!!

  17. Hi there! I’m working on a new template that focuses on pictures and I want to show all these in 3 columns. You can see the template that I’m working on here. Example #1 works great, but since it’s not crossbrowser-friendly, I’d wanna try something else. #4 didn’t work out for me, since I couldn’t get it to show the rest of all the posts on the other pages. (It would only show post 1-15 so page navigation was more or less useless). I think that #3 could work, but the thing is that I don’t show any of the content on the frontpage, all that is shown is the first picture of that specific post.

    I’ve looked everywhere for a solution, but all that works for me is the css3 way. Please help!

  18. Thanks. This is a great tutorial!

  19. Patrick June 12, 2010

    I was wondering if anyone can make a plugin to allow columns to be setup in main page, and then widgets can be drag just like what is done with the side bars?

    It will really make WordPress even more flexible.

  20. Hi Jeff, Hi Everyone.

    I’m using #1 and it works great. Only thing is,
    I actually want a post split where the image shows on the left and meta(post title, etc and text) on the right.

    An perfect example is http://www.wmagazine.com/artdesign/2012/06/yoko-ono-and-sean-lennon-collaboration

    I would really appreciate any help I can get with this.

    Thank you so much.

  21. Mayeenul Islam July 1, 2012

    Thanks very much for the detailed code, brother. Nice blog indeed.

    For the first option with CSS3:
    “1. Using CSS3 and progressive enhancement”

    It seems don’t work using <p> tag for each column. It works if-

    option#1:

    <p>Lorem ipsum..<br/>
    Lorem ipsum..<br/>
    Lorem ipsum..</p>

    or, option#2:

    <div>Lorem ipsum..</div>
    <div>Lorem ipsum..</div>
    <div>Lorem ipsum..</div>

    And Opera 10.10 doesn’t show columns (may be the later version enables CSS3)

    But thanks very much for your nice blog, it will help in future, inshALLAH.
    Thanks a lot.

Comments are closed. Contact us with any critical information. Thank you!

Code is poetry