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:
- Study the source code for the get_body_class() function.
- Check out Demetris’s thoughts on the new WordPress 2.8 features.
- Browse the WordPress 2.8 Overview at the Codex.
- Take a look at the trac ticket that got the ball rolling.
- WPEngineer.com has a good summary of the body_class() function.
- PerishablePress has some good stuff on body_class() usage.
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.
This is going to be much easier than my manual work around: http://fearlessflyer.com/2009/05/how-to-change-the-background-dynamically-in-your-wordpress-theme/
I see so much potential in this one new feature; all of the ideas you have mentioned here will be just the beginning.
right on, this helped thanks for the post :P
This can also be done with PHP constants (the
define()function). I’ve been using that, butbody_class()will negate the need for it now. :)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.
Not sure why the official WordPress site doesn’t have documentation this.
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
You’ll have to ask the folks at the WordPress.org/support forum. Your question has nothing to do with the
body_class()function.super article. good and thanks
thanks for articles.
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
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
It will output classes based on page IDs. For instance, on my About page, this is the
body_class()output:Notice the
page-id-3class? That means that we’re viewing a page with an ID of 3. Use that to style specifically to target that page.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
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.
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/
Thanks for this really detailed article. WP 2.8 rocks. I mentioned you in a comment here: Styling Each WordPress Page Differently.
Please forget my last post… I’m an idiot and just figured out what my problem was. Thanks.
What was your problem?
Nevermind, i figured it out.
body.pageid-51{background-image: url(“images/bg.jpg”);}
Yo Nathan, where do you lay this code down? In the the header.php or in the post-template.php file?
Thanks,
L
You would replace
<body>with<body <?php body_class(); ?>>in yourheader.phpfileHope that helps!
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!! :P
L
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
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.
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 :D
FYI:
http://digwp.com/2009/08/wordpress-body-class-plus/#comment-1355
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
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.
nvrmind. Figured it out!~
thanks admin for post
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!
adana çiçek sipari?i
adana çiçek sipari?i
adana çiçek sipari?i
adana çiçek sipari?i
adana çiçek sipari?i
adana çiçek sipari?
adana çiçek sipari?
adana çiçek sipari?
adana çiçek sipari?
adana çiçek sipari?
adana çiçek gönder
adana çiçek gönder
adana çiçek gönder
adana çiçek gönder
adana çiçek gönder
adana çiçek yolla
adana çiçek yolla
adana çiçek yolla
adana çiçek yolla
adana çiçek yolla
adana çiçek gönderimi
adana çiçek gönderimi
adana çiçek gönderimi
adana çiçek gönderimi
adana çiçek gönderimi
adana çiçek
adana çiçek
adana çiçek
adana çiçek
adana çiçek
adana çiçekçi
adana çiçekçi
adana çiçekçi
adana çiçekçi
adana çiçekçi
adana çiçekçileri
adana çiçekçileri
adana çiçekçileri
adana çiçekçileri
adana çiçekçileri
adanada çiçekçiler
adanada çiçekçiler
adanada çiçekçiler
adanada çiçekçiler
adanada çiçekçiler
adana çiçek dünyas?
adana çiçek dünyas?
adana çiçek dünyas?
adana çiçek dünyas?
adana çiçek dünyas?
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 ?
check out the source code for the posts page. look at the body tag and you’ll see what classes you can leverage.
thanks to this post, I am looking for article like this to solve my site
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