Adding Classes to Body

WordPress provides many body classes that allow you to narrow CSS to specific contexts. Examples:

  • .post-type-archive-portfolio – Styling to the ‘portfolio’ post type archive.
  • .archive – Styling for any archive page (post type archive, category, tag…)
  • .single-portfolio – Styling for single posts in the ‘portfolio’ post type
  • .single – Styling for any singular post

But sometimes you need to add your own class. The most common area where I add custom classes is when the same template file is used for multiple contexts.

You might have a ‘portfolio’ post type with a ‘project-features’ taxonomy. Both the post type archive and taxonomy term archive should use the same styling since they’re both listing portfolio items. See the link above for how to make the taxonomy use this template file. In the template file itself I’d add the following so they all have the same class, .portfolio-archive:

<?php
/**
* Portfolio Archive Body Class
* @author Bill Erickson
* @link http://www.billerickson.net/wordpress-class-body-tag/
*
* @param array $classes, existing body classes
* @return array $classes
*/
function be_portfolio_archive_body_class( $classes ) {
$classes[] = 'portfolio-archive';
return $classes;
}
add_filter( 'body_class', 'be_portfolio_archive_body_class' );

You can place this in individual template files, or put it in functions.php to control body classes site-wide.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Nur says

    Thanks a ton for this, very helpful to be able to add classes to the body on the fly. I’ve been trying to figure out how to add a class based on a certain custom options setting value being present so I can control color scheme CSS based

      • nur says

        Thanks Eric, yeah I have dynamic color schemes being generated using .less variables, compiling them on the fly and need to create scenario where certain text above the color background can either be switched to light or dark depending on the base color chosen.

        .Less guards should work but for the life of me I can’t get it to work so just thought of adding a switch to make that change and hoped to do so through a boddy class which I think would be easiest.

        As always appreciate your Genesis tips tricks and snippets

  2. Brad Dalton says

    Why do you need to add a function if the field already exists in the layout options for body class?

    Is this a new function which has been added since you published this post?

    • Bill Erickson says

      The filter allows you to add classes programmatically, rather than having to edit pages. It also allows you to add classes to the dynamically generated pages. In the example above, I’m adding a class of ‘category’ to all category archives. You don’t have the ability to edit the body classes of category archives (or any other archives) in Thesis or Genesis.

      But technically you’d never need to use the example above for that specific purpose. WordPress automatically adds a class of .home to the homepage, and .category to the category archives. I just used those as a simple example.

  3. Brent Wallace says

    Hi Bill.
    I have an unusual request, maybe you can help me out.

    I am using a Genesis theme and I need to add a body class to all pages. Normally not a problem from my research except that I need to add the “domain name” as the class to each page.

    I am using a plugin from the repository called: Multiple Domains with Analytics (http://wordpress.org/support/plugin/multiple-domains-with-analytics). It allows me to use different domain names for the same site. My problem is that I would like to be able to use different CSS styling on the site based upon the “domain name” that users use to enter the site.

    You can see the test site that I am setting up here: http://www.nerium.me/. You can also use the following domain names to get there: http://brentsblogs.com or http://brentsblogs.com, but you’ll notice that the domain name always stays the same depending on how you enter the site. I need to apply different styling per domain name.

    I hope I explained this well enough and hope that you might possibly know what code I need to add to my functions.php file.

    Thank you for your time and have a great day,
    Brent

    • Bill Erickson says

      Here you go: https://gist.github.com/billerickson/9326821

      home_url() returns the site’s URL. I’m then replacing elements of it to clean it up (http:// and www are removed, periods and slashes turn to hypens). I then run it through sanitize_html_class() to ensure I didn’t miss any special characters that don’t belong in there, and add it as a body class.

      So if I added this on my site, I’d have a body class of billerickson-net.

      Keep in mind that Google really hates duplicate content, so having your site accessible through multiple domains will most likely result in hurting your search engine rankings.

  4. Brent Wallace says

    Bill thank you so much!!
    Wow, I’ll give it a try!

    Can I not avoid the duplicate content by using a single canonical meta tag for all sites?

    Thanks again,
    Brent

  5. Brent Wallace says

    Hi Bill.

    I used this solution before and it was great. Since then the plugin that I have been using [Multiple Domains with Analytics (http://wordpress.org/support/plugin/multiple-domains-with-analytics)] has quit working and has not been updated for quite a long time. I’d update it if I knew how, but not my expertise 🙁 The #1 solution would be to update the plugin but I have had to try plan B, unless you could update the plugin..?

    What I have had to do in place of the plugin is to redirect a domain name (martahowelljewelry.com) to brentwallace.net like this, to have the domain name show up:

    Options +FollowSymLinks -MultiViews
    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP_HOST} ^(www\.)?martahowelljewelry\.com$ [NC]
    RewriteRule ^ http://brentwallace.net%{REQUEST_URI} [L,NE,P]

    Since doing this my body class of (martahowelljewelry-com) does not show, (brentwallace-net) does. This is based on the code below that I received from you:

    /* Add Site Name as Body Class
    * @author Bill Erickson
    * @link https://www.billerickson.net/wordpress-class-body-tag/
    */
    function be_site_name_in_body( $classes ) {
    $class = str_replace( array( ‘http://’, ‘www.’, ‘.’, ‘/’ ), array( ”, ”, ‘-‘, ‘-‘ ), home_url() );
    $classes[] = sanitize_html_class( $class );
    return $classes;
    }
    add_action( ‘body_class’, ‘be_site_name_in_body’ );

    Can this be altered to fix my problem? All of my extensive CSS is based on the body classes of each domain name. I’m not sure what to do.

    Greatly appreciate your help again!

    Thanks,
    Brent

    • Bill Erickson says

      Why not install a plugin on that specific site that manually adds a body class of ‘marthahowelljewelry.com’ and removes the ‘brentwallace.net’ class?

        • Bill Erickson says

          I don’t understand why you’re using the same install for multiple domains. I don’t have any experience doing something like that so I can’t be of help

  6. Jamie Mitchell says

    Hi Bill

    I add the front-page body class for example to my front-page.php

    but when i click on the pagination link (older posts) the front-page body classes is on page/2, page/3 etc

    is there anyway to keep the body class only on the front page?

    thanks in advance

  7. Jordan Smith says

    Hi Bill,

    Thanks for this article! I’ve been setting this up and for some reason when I try to target is_home(), is_author() or is_category() to add a body class to the page, it breaks scrolling. Any idea what this could be related to? I’m using Genesis.

    Here is my code setup -> http://snippi.com/s/dwk1rnj

    I’ve tried setting up the code every way I can think of as well and it consistently breaks the scrolling on those template. No idea at this point. I was curious if something is getting broken trying to add the classes to those templates?

    Thanks!

      • Jordan says

        Hey Bill,

        It was a CSS issue. I was just stuck in the mindset of thinking it was a PHP issue. I just kept simplifying until I realized it was related to something in style.css rather than functions.php. Thanks again man!