One of the most often asked and most easily accomplished tasks is styling elements differently on different pages. Before proceeding I would encourage you to review the general CSS tutorials found at W3 Schools. A basic understanding of how CSS works is required.
The great thing about Body Class is that you don’t need to use any php to make significant site changes from one page to the next. Let’s start by looking at how to style the home page. If you use FireBug, an extension for FireFox, or another developer tool set available for most browsers you can easily look at the elements in any given webpage. The home page of this site currently has this showing in FireBug.
Notice the class on the body element. It has “home, blog, logged-in, header-image, and content-sidebar” listed. “Header-image” and “content-sidebar” are classes assigned by Geneses based on theme settings. This allows the style sheet to dynamically present the correct layouts. The remaining items are part of the WordPress body class output. Any of these items may be used to change the layout via CSS selectors.
You can quickly present a different layout for logged-in users with the .logged-in
selector, or a home page layout with the .home
selector. This is how you might use the home class to setup a different background and header.
body.home { background: none #333333; }
This would show a dark gray background without an image.
.home #header { height: 120px; } .home #header #title-area { background: url(images/home-logo.png) no-repeat transparent; } .home #title-area, .home #title-area #title, .home #title-area #title a { height: 120px; }
This would make the header 120px tall on the home page and show the home-logo.png instead of logo.png. Notice that I don’t include .header-image
along with .home
. Both of these are body classes so cannot be simultaneously used as selectors.
This same concept may be applied to pages, categories, and posts.
Looking at this image from a category you will see the body class options include “archive, category, category-getting-started …” This allows styling for all archive pages, all category pages, or the “getting-started” category. To style for a specific category you will need to use “category-%slug%” since categories often have names that include spaces or other characters that would not work for a class selector. The same principles apply. Put your body selector in front of the selector you are overriding for page specific styling.
Pages can also receive styling based on the template being used and the page ID.
All pages are styled with .page
while a specific page may be styled with .page-id-xx
where “xx” is the page ID. This page is using a page template, which is based on the file name. In this case the selector is .page-template-sitemap-php
. Posts work the same way with “page” being replaced with “single …” and no options for a template.
One major short coming with working with posts is the lack of being able to style all posts from a specific category the same way. To deal with this I have written a small php filter to add the first category a post in filed under to the body class.
//adds new body class for post category add_filter('body_class', 'add_category_class_single'); function add_category_class_single($classes){ global $post; if(is_single()) { $category = get_the_category($post->ID); $slug = $category[0]->slug; $classes[] = 'post-category-' . $slug; } return $classes; }
This allows the new style selector .post-category-%slug%
This means the post I showed above would have the class post-category-getting-started
By looking at the body tag you can quickly find the correct selectors for tags, attachment pages, custom post types, custom taxonomies, and more. You can also use the filter I provided as a template for adding new body class items based on your own function.
Summer says
The category filter is definitely a neat trick, one I can use in several cases.
But is the > supposed to be in the code example? It’s in there twice…
Summer says
What I meant was, should it be the greater than symbol rather than the actual HTML code for the greater than symbol (darned comment filters) 🙂
nickthegeek says
Thanks for catchign that, yes it should be an actual greater than symbol, I went back and fixed it.
Chris says
You just saved me from a potential massive headache. This is just what I needed for a project I am working on!
Thanks!
Bharat Chowdary says
Thanks for the useful code snippet 🙂
Sara Greenlaw says
Thank you so much exactly what I needed.
janet says
Hi, please am trying to have my home widget title to have background colour, I’ve tried the below code but it doesnt work I dont know what am doing wrong
.home #widget-title {
background-color:red
}
But if I use the below it works it’s just that it fillled all widget on home page with the same colour but I only want it for the home middle widget
.widget h4, .widget-area h4 {
background: none repeat scroll 0 0 red;
text-transform: uppercase;
}
Thanks for your help in this matter
nickthegeek says
your widget are probably has a class or ID in the div around that sidebar. you should be able to use that to target just the one area.
Matt Orley says
thanks, worked like a charm first try- i included this on a separate template page and i no longer have to remember to call it special…AWESOMENESS of wp and genesis.
John says
So where do I put the body class code filter in your last example for posts in a specific category? functions.php?
nickthegeek says
The bottom of the functions.php file. If there is a closing ?> put it just before that line.
wendy says
Hi Nick,
I’ve been searching the forums but am unable to find a way to REMOVE a body class. I am also using the Streamline theme and am using the green color for the home page (and a few other pages). What I want to do is to use the blue or orange color on other pages and posts. Is there a function to do this? I was working on something like the code below, but cannot seem to make the “streamline-green” body class to go away on those pages. My goal is to change the color scheme for the content and sidebar links. I would also like to have different banners per page or category.
Thanks in advance for your help.
/** Remove custom body class for certain pages or categories */
remove_action( ‘body_class’, ‘remove_green_class’ );
function remove_green_class( $classes ) {
if ( in_category( ‘4’ ) OR ( is_page( 164 || 351 || 240 || 191 || 243 || 68 )))
$classes[] = ‘streamline-green’;
return $classes;
}
/** Add custom body class to the head for certain pages or categories */
add_action( ‘body_class’, ‘add_orange_class’ );
function add_orange_class( $classes ) {
if ( in_category( ‘4’ ) OR ( is_page( 164 || 351 || 240 || 191 || 243 || 68 )))
$classes[] = ‘streamline-blue’;
return $classes;
}
nickthegeek says
removing a body class is trickier. Here is a discussion on how to remove a specific string from an array
http://stackoverflow.com/questions/4120589/remove-string-from-php-array
Todd says
This is really cool. However I’m trying to figure out how to do this based on the date. I want dynamically change the backgrounds and theme elements based on the date. I’m at a loss.
Katie Price says
Thank you Nick! Once again you saved the day with an easy to follow tutorial!
Brian Novak says
Nick,
Thank you for pointing me to this article! Works perfectly.
Cheers,
Brian
Alia says
Hi Nick
I’d like to have the background image change when a user logs in. I get how to change the body class, and I have done that, but I don’t understand how to show a different image depending upon login status.
Thank you!
Alia
nickthegeek says
There is a body class for that, “logged-in.”
Brian says
NIck,
I’m using category body class to change the logo on each of my category pages. Can you tell me how to get the individual posts in those categories to use the same logo as the parent category?
Thanks,
-B
Lisa says
Now that Genesis 2.0 has been released, how does this affect the use of these dynamic body classes? Some of the classes will no longer be classes (i.e., #wrap now becomes .wrap).