WordPress 2.8 and the body_class() Function

Back on February 7th, I was casually browsing the WordPress trunk code, and discovered a very cool new function in the wp-includes/post-template.php file.

Beginning in WordPress 2.8, themes will be able to take advantage of the body_class() function to place location-specific classes on the opening <body> tag, usually located in the header.php file of most themes.

Why is this significant? Easy … this opens up the ability to change the look of nearly everything with CSS only.

Before we get into the application of the body_class() function, let’s cover some technical details first.

What body_class() Generates

The body_class() function operates in nearly the exact same manner as the post_class() function that was introduced in WordPress 2.7. The only differences are the classes it generates. The body_class() function will generate the classes mostly based on where your viewer is on your site.  For instance, if a viewer is on your homepage and you haven’t set a static page for your homepage, then the classes the function might generate might look like this:

<body class="home blog">

Notice, those are two separate classes, either of which you can use as a selector.

However, if you are on a particular post, the body tag might look like this:

<body class="single postid-64">

And if you are currently looking at a page, then body_class() will generate something like this:

<body class="page page-id-3 parent-page-id-0 page-template-default">

Essentially, body_class() will generate dynamic CSS classes based on the type of content, and under what circumstances, you are currently browsing. For instance, if you are a registered user, and are currently logged in, body_class() will generate a logged-in class on the body tag.

The following is a full list of possible body classes (HT: WPEngineer.com):

  • rtl
  • home
  • blog
  • archive
  • date
  • search
  • paged
  • attachment
  • error404
  • single postid-(id)
  • attachmentid-(id)
  • attachment-(mime-type)
  • author
  • author-(user_nicename)
  • category
  • category-(slug)
  • tag
  • tag-(slug)
  • page
  • page-parent
  • page-child parent-pageid-(id)
  • page-template page-template-(template file name)
  • search-results
  • search-no-results
  • logged-in
  • paged-(page number)
  • single-paged-(page number)
  • page-paged-(page number)
  • category-paged-(page number)
  • tag-paged-(page number)
  • date-paged-(page number)
  • author-paged-(page number)
  • search-paged-(page number)

How To Add body_class() to My Theme

This is actually the easy part. Assuming you are running WordPress 2.8 (currently in beta, soon to be released), all you have to do is add a new template tag. You’ll need to locate which template file generates the opening <body> tag. This is usually the header.php file.

After you’ve located the <body> tag, just change it to this:

<body <?php body_class(); ?>>

Save the file (and upload to your server, if necessary), and you’re done!

Using Dynamic Body Classes

So, we now have body classes. What’s the big deal? I’ll explain:

With the exception of the HTML element, the <body> tag wraps around all other HTML code. Therefore, by having classes on <body> allows us to target any other element on the page, specific to the current <body> class.

It may just be easier to explain by example.

Let’s say that I have a <div id="content"> that renders on the left, and a <div id="sidebar"> that renders on the right, both within a 960px wide <div id="container">. The content div is 600px wide, and the sidebar is 360px wide. But, when viewing a single post (as opposed to the homepage), I have told my theme to not display the sidebar. Now, we’re left with just a content column. Unfortunately, our container is 960px wide, and our content div is only 600px wide.

We’re stuck with a large blank space where the sidebar used to be. How do we fix that? With a <body> class, it’s easy. We just target the <div id="content"> when it is being displayed on a single post. It would looks something like this in CSS:

.single #content {
	width: 960px;
}

By doing this, we’re saying “if we’re viewing a single post, make the #content div 960px wide”.

We’re basically adding a simple conditional system to CSS.

Adding Classes to body_class()

In some cases, you will want to add your own class(es) to the list of classes that body_class() generates. If you find yourself in this situation, here are a couple of ways to do it.

The first, and easiest, way to add a class to the list of classes the function generates is to simply pass your custom class as a function argument to body_class(). Here’s how you would do that:

<body <?php body_class('my-class'); ?>>

By doing this, we’ve now told the body_class() function to add ‘my-class’ to the list of classes to output.

The second, and harder (but more flexible) way is to use take advantage of a WordPress Filter to add new body class(es). In this case, we’ll be using the body_class filter provided in the get_body_class() function. If you don’t understand how filters work, I’ll do a post on that in the future. Until then, see if you can just follow along. You may pick it up pretty easily.

Here’s an example of how to add a class by using a filter:

<?php
add_filter('body_class','my_body_classes');
function my_body_classes($classes, $class) {
	// add 'my-class' to the $classes array
	$classes[] = 'my-class';
	// return the $classes array
	return $classes;
}
?>

By using this method, we allow ourselves to use conditionals, and other cool things, that we would not be able to use with the first method.

Further Reading

If you want to know more about the body_class() function, here are a few resources I’d recommend:

100 Replies to “WordPress 2.8 and the body_class() Function”

  1. […] 2009-06-01. Added link to Nathan Rice on the body_class() function […]

  2. […] posted here: WordPress 2.8 and the body_class() Function — Nathan Rice You May Like Linking To UsHello and welcome to our blog, you may consider linking to us, because […]

  3. This is a feature I’ve been waiting for. This is really going to help me style sites where users can login in and view things differently.

  4. I see so much potential in this one new feature; all of the ideas you have mentioned here will be just the beginning.

  5. […] be happy to know that it’s been reported (I haven’t confirmed it yet, but I soon will) that WordPress 2.8 makes this function obsolete […]

  6. […] WordPress 2.8 and the body_class() Function — Nathan Rice […]

  7. […] I wrote an article introducing and unwrapping the new WordPress body class function that will be included in WordPress 2.8. Today, I want to take it a step further by giving […]

  8. […] the full list of classes generated by this function, check this post by Nathan Rice. 3. Extended control over widgets If you take a look at wp-includes/widgets.php, you’ll be […]

  9. […] body_class()?? ?? 6th, 2009 by Epile ???? » ???WordPress 2.8 and the body_class() Function ???Epile […]

  10. […] WordPress 2.8 and the body_class() Function Back on February 7th, I was casually browsing the WordPress trunk code, and discovered a very cool new function in the wp-includes/post-template.php file. – By Nathan Rice […]

  11. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  12. […] WordPress 2.8 and the body_class() Function […]

  13. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  14. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  15. […] WordPress 2.8 e a função body_class() – Nathan Rice […]

  16. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  17. […] WordPress 2.8 and the body_class() Function […]

  18. […] Custom Taxonomies in WordPress 2.8 – Justin Tadlok Build A WordPress 2.8 Widget – WP Engineer WordPress 2.8 and the body_class() Function – Nathan Rice Authentication in WordPress 2.8 – Will Norris Loading JavaScript in Footer in […]

  19. […] Taxonomies in WordPress 2.8 – Justin Tadlok * Build A WordPress 2.8 Widget – WP Engineer * WordPress 2.8 and the body_class() Function – Nathan Rice * Authentication in WordPress 2.8 – Will Norris * Loading JavaScript in Footer in […]

  20. right on, this helped thanks for the post 😛

  21. […] 5. WordPress 2.8 and body_class() function – Nathan Rice […]

  22. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  23. […] ????? ?? WordPress 2.8 ???????? body_class() ???????? 2.8 ?????????? ???????? 2.8 ????? ?????’??? ?? wp_widget […]

  24. […] WP Engineer??WordPress 2.8??Widget API, ????Widget????????WordPress 2.8 and the body_class() Function – Nathan RiceWordPress […]

  25. […] 2.8 introduced a very useful new tag called body_class which normally will be used like […]

  26. […] Taxonomies in WordPress 2.8 – Justin Tadlok * Build A WordPress 2.8 Widget – WP Engineer * WordPress 2.8 and the body_class() Function – Nathan Rice * Authentication in WordPress 2.8 – Will Norris * Loading JavaScript in Footer in […]

  27. […] WordPress 2.8 and body_class() function – Nathan Rice […]

  28. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  29. […] the website. Basically, each page needed the main drop-down menu styled specifically for that page. WordPress 2.8 supports that feature out of the box! *and there was much […]

  30. This can also be done with PHP constants (the define() function). I’ve been using that, but body_class() will negate the need for it now. 🙂

  31. […] WordPress 2.8 e a função body_class() – Nathan Rice […]

  32. […] WordPress 2.8 e la funzione body_class() […]

  33. […] The new body_class function is a great addition.  It will let you easily do things like have different styles for different categories.  It was possible to do this in the prior versions, it just took a little work.  Tom and  I did something like this manually  to change the header image on the Rotair site design.  But now anyone can do it as described by Nathan Rice. […]

  34. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  35. Yay it finally arrives. Wanted this function badly for my employer last year, I had to do it drupal way I am familiar with. Now that it’s here I should no longer worry. More and more powerful indeed.

  36. Not sure why the official WordPress site doesn’t have documentation this.

  37. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  38. […] WordPress 2.8 and the body_class() Function […]

  39. […] konuda  “WordPress 2.8 – body_class function – Natran Rice” adl? yabanc? kaynaktan […]

  40. downloaded 2.8 and i can’t get my thumbnails to insert anymore, also when i approve a note, it doesn’t show anymore….. any advise…….. thanks

    1. You’ll have to ask the folks at the WordPress.org/support forum. Your question has nothing to do with the body_class() function.

  41. […] A <body> tab completion function with the new body_class(); function, for its use, read this great article by Nathan Rice: WordPress 2.8 and the body_class() Function. […]

  42. […] WordPress 2.8 and the body_class() Function – Nathan Rice […]

  43. […] tijdje terug heeft Nathan Rice hier ook al over geschreven, maar voor de mensen die dat nog niet wisten (en/of niet zo goed in […]

  44. […] A <body> tab completion function with the new body_class(); function, for its use, read this great article by Nathan Rice: WordPress 2.8 and the body_class() Function. […]

  45. […] just learned that, as of WordPress 2.8, browser-specific classes are now included in the body_class() function.  HOORAY!!!!  So, feel free to start writing your CSS for specific […]

  46. super article. good and thanks

  47. thanks for articles.

  48. Is it possible, perhaps via a filter to add the category slug(s) for a single post as a class to the body_class function output?

    Or is there something that can be coded right in the body_class() function call?

    Thanks,
    Michael

  49. Hi there… I really enjoyed the post and have had fun using the body_class() function–successfully–for the ‘home’, ‘single’ and ‘page’ classes. However, I’m trying to figure out how to use the function with “specific WP pages” and for some reason I can’t figure it out. In other words, how can I set up a body class that applies only to particular WP page (e.g. page ID 19)? Any help you can offer would be much appreciated. Thanks.

    Best, Chris

    1. It will output classes based on page IDs. For instance, on my About page, this is the body_class() output:

      
      <body class="page page-id-3 page-template page-template-default">
      

      Notice the page-id-3 class? That means that we’re viewing a page with an ID of 3. Use that to style specifically to target that page.

  50. Still looking for help with getting the ‘category-slug’ to be added to the body_class function output.

    All it seems to output by default for single posts is: <body class="single postid-309">

    Thanks,
    Michael

  51. Thanks for getting back to me so quickly… I really appreciate it. Well, I thought I understood your reply, and tried implementing your suggestions (several different ways). Sadly, I still can’t figure it out. Any chance you want to try and walk me through it one more time? If so, here’s some details.

    Here’s the URL that I’m working on:

    http://www.thomas-holden.com

    Here’s the code that I have placed in the header file:

    <body >

    Here’s the CSS that I’ve been working with:

    .single #logo {
    background: #ffffff url(images/blog_header.jpg) no-repeat;
    }

    .home #logo {
    background: #ffffff url(images/blog_header.jpg) no-repeat;
    }

    .page #logo {
    background: #ffffff url(images/teaching_header.jpg) no-repeat;
    }

    .page page-id-19 page-template page-template-default #logo {
    background: #ffffff url(images/cv_header.jpg) no-repeat;
    }

    If you click on some of the navigation, you’ll see that the background image for the #logo div changes. Everything except for the page specific (i.e. page-id-19) styling is working fine. Where did I go wrong? Thanks again for your help.

    1. hi, chris

      i’m tackling this exact same problem. putting a different logo on About vs Blog vs News, etc.

      i’m using the kubrick theme.

      i appears your question wasn’t answered. or was it?

      i found this link helpful: http://fearlessflyer.com/2009/05/how-to-change-the-background-dynamically-in-your-wordpress-theme/

  52. Thanks for this really detailed article. WP 2.8 rocks. I mentioned you in a comment here: Styling Each WordPress Page Differently.

  53. Please forget my last post… I’m an idiot and just figured out what my problem was. Thanks.

    1. What was your problem?

    2. Nevermind, i figured it out.

      body.pageid-51{background-image: url(“images/bg.jpg”);}

  54. Yo Nathan, where do you lay this code down? In the the header.php or in the post-template.php file?

    Thanks,
    L

    1. You would replace <body> with <body <?php body_class(); ?>> in your header.php file

      Hope that helps!

  55. I’m using 2.8, so it’s already there! It’s like I’m on a date with Sasha Grey and have no dick ATM!! 😛

    L

  56. Hey man, thanks for taking the time to create this article for us. I am still somewhat new to coding. You gave me some good tips that I am gonna try out in an upcoming project. Thanks again Austin Estate Planning

  57. Hi, this only shows the parent one level up. On a page a few levels down in the navigation, there’s no way to tell what the top level ancestor id is, sadly.

    For example, consider

    Top
    Sub
    SubSub

    If you;re on SubSub, it would be nice to have a class of the “Top” page ID, since it is an ancestor. But, the included WP functionality won’t do it. It will show you Sub’s page ID.

  58. Oh my word! I’ve been building WordPress sites with my own kludged together get_body_class function for the last year or so.

    This evening I decided to try moving my function into functions.php, but this was breaking WordPress. I searched all the source code and a broad grin broke across my face when I discovered the ‘official’ get_body_class function – that’s how I found this blog post and that’s why I wanted to say thanks, to you and to WordPress.

    I’m still grinning 😀

  59. […] WordPress 2.8 and the body_class() Function — Nathan Rice — 8:19am via Delicious [ This entry was written by admin, posted on 8 ? 25, 2009 at […]

  60. Wow, your example solves the EXACT problem I had : I don’t show the sidebar on the homepage, and wanted to let the main contents occupy the whole width, so thanks mate!

    bookmarked and tagged

  61. […] use ‘body_class’ as the hook, as Nathan describes in his original article (see here for a more in-depth […]

  62. I’m trying to style a specific page link only when I’m actively on that page.

    What do I output in my body class if my page id ‘about’ has a class of ‘page-item-6’ and it’s php template file is about.php.

  63. nvrmind. Figured it out!~

  64. […] The function works well both with just getting the current category for content manipulation, as well as adding an extra class to the body tag, as mentioned in this post via the body_class function. […]

  65. thanks admin for post

  66. […] already about this that deal with adding your own custom classes, one of the best being “WordPress 2.8 and the body_class() Function“, but I ran into a specific need for a project I’m working on, and wanted to chare my […]

  67. hello, all:

    i’m confused about leveraging the body class in 2.8. i believe you’re saying that in 2.8 we do not have to copy/paste the following in the header.php because it’s already there, yeah?

    let’s say i have a page called about, and my blog page is called news.

    if i want to change the body bg color (using Kubrick theme) on either of these pages, how would i go about doing so? Why can’t i simply put the following into my css:

    body.about {background: orange;}
    or
    body.news {background: red;}

    i’ve had success with following (.page {background: green;}, but need more granular control, because both the News and About are equally effected by that snippet of css. And i need those 2 pages to have different bg colors.

    thanks!

  68. Hi,

    i’m using the following code :

    body.category-title1 #page-top { background: url("images/page_top1.jpg") no-repeat; }
    body.category-title2 #page-top { background: url("images/page_top2.jpg") no-repeat; }
    body.category-title3 #page-top { background: url("images/page_top3.jpg") no-repeat; }
    body.category-title4 #page-top { background: url("images/page_top4.jpg") no-repeat; }
    body.category-title5 #page-top { background: url("images/page_top5.jpg") no-repeat; }</code

    The result is one header for each category of my blog. However, it doesn't work for the posts of my categories (it works only on the category pages).

    Any idea, please ?

    1. check out the source code for the posts page. look at the body tag and you’ll see what classes you can leverage.

  69. thanks to this post, I am looking for article like this to solve my site

  70. The tip on how to use wordpress filters to add new body classes is money! Never thought about doing that, tedious but your right! Much more flexible.

    Thanks

Comments are closed.