The Magic of WordPress’ body_class

Over the last month, whilst I’ve been working with WPZOOM in their support forum, I’ve found one of the things that has helped me the most when answering people’s requests for help is the amazing function, body_class.

It was introduced back in WordPress 2.8, but it doesn’t really get the respect it deserves; body_class is awesome. 

If you don’t know what it is,  it’s essentially a piece of code you can add to the <body> element which adds various unique classes to your posts, pages, archives, custom post types etc. Why is this handy? It lets you add CSS to specific posts/pages/whatever. And that’s really handy.

Installation

The installation bit of body_class is really easy. You’ve just got to change your opening <body> tag to <body <?php body_class(); ?>>. And that’s it!

Before we go any further, though, we’re going to add a little custom code to our functions.php file which adds classes for custom post types. Hat tip here to WPEngineer.

function fb_add_body_class( $class ) {
	if ( ! is_tax() )
		return $class;
	$tax   = get_query_var( 'taxonomy' );
	$term  = $tax . '-' . get_query_var( 'term' );
	$class = array_merge( $classes, array( 'taxonomy-archive', $tax, $term ) );
	return $class;
}
add_filter( 'body_class', 'fb_add_body_class' ); // or post_class as hook

So what’s so useful?

In the support forum world, this is really handy because it lets you answer the questions like “can I have a different colour background on this post only?”

Without body_class, the answer is “um, sure; you just need all these conditional template tags”. With body_class, though, you just need to grab the post ID off the site (as it’s listed as one of the classes applied to body) and tell the client to add a line of code to their custom stylesheet:

body.postid-1{ background-color: #fff;  }

And that’s literally all there is to it. This post uses it! It’s made my life so much easier answering support tickets, but let’s look at a more common real life example.

Real life usage: menu highlights

CSS Tricks

This technique’s used on CSS-Tricks, too!

I’m using body_class here on Shout in order to get the menu to highlight depending on what page you’re on on the site. As I want the highlight to show on posts, custom page templates and pages, sometimes with a combination of the two, WordPress’ built in menu builder and the .current class it adds to the “current” page wouldn’t work here — I need to be able to effectively have custom control over which type of content highlights each menu.

With body_class, I can!

If you’ll excuse the cheesyness, you’ll see why I love this function so much. I’ve got the menus set up so that when the body_class adds its classes to certain types of pages, for example the “contact” item highlights when the  class .pagename-contact is active, the “articles” item highlights when one of .archive, .single-post or .pagename-articles (the custom page template used for the archives) are active.

I’ll walk you through a simplified version of the code. There’s not really much to this:

First off, we’ve got the original menu. This uses the id #main-nav and uses something like the following:

#main-nav li a { float:left; list-style:none; margin:0; padding:20px; color:#3a3a3a  }

We’ve then get the “current menu item” style which is something like:

#main-nav li a.current { border-bottom: 5px #f15a23; border-top: 5px #f15a23; background: #f8f8f8; }

As you can see, this just adds a couple of borders and changes the background. So that’s the “current” style sorted. So how do we integrate this with body_class to get this to show when on the pages, posts etc we want?

This bit’s simple — you’ve just got to find the unique classes body_class adds to the particular content types you want to highlight on the menu.

For me, it was things like .single-post and .home, but body_class lets you select content types right down to categories and the IDs of individual posts. All that’s left now is just adding those unique classes to the .current CSS we created earlier, ending up with something like this:

#main-nav li a.current,
/* The homepage */ .home li a
/* Highlights for articles tab */ .archive li a, .single-post li a, .pagename-articles li a,
/* Screencast highlight */ .single-screencast li a,
/* And the contact page*/ .pagename-contact li a
{ border-bottom: 5px #f15a23; border-top: 5px #f15a23; background: #f8f8f8; }

And then you’ve got your highlights sorted! If you want to see exactly how I’ve done it here on Shout, then check out the live site in Firebug/Chrome Web Tools.

Wrapping up

Hopefully this tutorial has been helpful in showing you how to get started with one of my favourite little functions built into WordPress. If you’ve used it recently, please share in the comments!


11 Responses

Comments

  • Jon says:

    Awesome write-up. I’ve used body_class before but I never thought about using it for highlighting the current page.

  • body_class is so awesome it is required to be included with every theme submitted to the WordPress Extend Repository.

    PS: Don’t forget about the equally awesome post_class function. EAC

    • Alex Denning says:

      post_class is awesome too 🙂 Must admit I’ve not actually used it too often – body_class tends to be more handy as it can be used for more or less anything as long as you’ve got enough selectors.

  • Do you need the function for custom post types? I believe if you use the body_class function it will return the custom post type name anyway?

    • Alex Denning says:

      I believe you need it for comprehensive integration – I believe there’s not too much support for custom post types in body_clas, hence the extra function.

  • Ricardo says:

    Quite interesting tutorial. I will test this function into my wordpress sites!

  • converse says:

    awesome i body_class

  • Body_class very useful!
    Thanks for sharing great tips 🙂

  • Hello, i think that i saw you visited my website thus i
    came to “return the favor”.I am attempting to find
    things to improve my website!I suppose its ok to use some of your ideas!
    !

  • When I originally commented I clicked the “Notify me when new comments are added” checkbox and now each time a comment is added
    I get three e-mails with the same comment. Is there any way you can remove me from that service?
    Many thanks!