I have several pages, which are ordered like this:

- Project 1
-- Project 1 Subpage 1
-- Project 1 Subpage 2
- Project 2
-- ...

And I want to change the background color (in this case of .site-main {} or any other css classes) depending on the page the user is right now.

  1. Currently on Home page (this is the default layout) -> Standard background color light blue
  2. I am on Page Project 1 -> background should be green.
  3. I am on Project 1 Subpage 1 -> background should be green.
  4. I am on Project 2 -> background red or something else

This is the standard layout right now (the lightest part should be changed):

enter image description here

What would be the best/easiest way to achieve this?


What I did know is this:

In my page.php I added this

<div id="main-content" class="main-content <?php echo "roadkill-main-content"; ?>">

This is working fine (I'm getting another color now). What's missing is how to detect if the current page is child or grandchild or whatever of a page with the slug "project1" or others. What is the correct way to do this?

  • 1
    Use the existing body classes which you can grab from the source code. Jan 28, 2014 at 13:07
  • Some more hints please. Any link
    – 4ndro1d
    Jan 28, 2014 at 13:17
  • Link to a sub page on your site. Jan 28, 2014 at 13:24

3 Answers 3


Another solution could be you register a meta box for the project pages which lets you type in whatever class name you want for each page…

function add_project_page_metabox() {
        'project_page_meta',    //  $id
        'Project Meta', 
                        //  $title
        'ppm_callback', //  $callback
        'page', //  $post_type  
        'side',         //  $context
        'low'           //  $priority
add_action( 'admin_init', 'add_project_page_metabox' );

function ppm_callback() {
    global $post;
    $project_class = get_post_meta($post->ID,'project_class',TRUE);
    wp_nonce_field( $_POST['page_meta_noncename'],__FILE__);

    /*  some UI styling */ ?>
<style type="text/css">
#project_page_meta          {display:block;margin:0 0 12px;float:none;}
#project_page_meta label    {display:block;margin:0 1em .6em 0;}
#project_page_meta input    {margin:0 0 .25em;clear:both;float:none;max-width:97%;}
    <label>Add class name</label>
    <input class="project_class" size="35" type="text" name="project_class" value="<?php if($project_class) { echo $project_class; } ?>"/>

    //  process the meta
function project_meta_save($post_id) {
    if(!current_user_can('edit_post', $post_id)) { return $post_id; }
    $accepted_fields['page'] = array(
    foreach($accepted_fields['page'] as $key){
        $custom_field = $_POST[$key];
        //If no data is entered
        if      (is_null($custom_field)) { delete_post_meta($post_id, $key); }
        elseif  (isset($custom_field) && !is_null($custom_field))
                { update_post_meta($post_id,$key,$custom_field); } 
        else    { add_post_meta($post_id, $key, $custom_field, TRUE); }
    return $post_id;
add_action('save_post', 'project_meta_save', 3, 1 );

…then use this in your page.php like class="<?php echo get_post_meta($post->ID,'project_class',TRUE); ?>"


Brad Dalton already gave a bit to answer this — add a body class (<body <?php body_class('nameofyourclass'); ?>>). Then the next step is to have a look at the classes WP adds automatically. Those are (in regard to your example):

Projects:               .page-parent
- Project 1:            .page-parent and .page-child
-- Project 1 Subpage 1  .page-child

Now take advantage of all those in your stylesheet like:

body.nameofyourclass.page-parent            {/* rules for "Projects" */}
body.nameofyourclass.page-parent.page-child {/* rules for "Project 1" */}
body.nameofyourclass.page-child             {/* rules for "Project 1 Subpage 1" */}

Hope, this helps.

  • No, not necessarily! To be precise, this is even what I suggest to avoid this way. Just open your header.php and search for the body tag. I guess you will find <body <?php body_class(); ?>>. Replace that with <body <?php body_class('nameofyourclass'); ?>>, so you only have to add the css of my last code block to your stylesheet and you're done. Jan 28, 2014 at 14:05
  • But keep in mind, that it's not a good idea to handle things like this by applaying a class to the whole site. It's way cleaner to design a template (e. g. project.php, which may even be empty) and only add body_class() when this template gets detected on post. This would mean <body <?php if(is_page_template('project.php')) body_class('nameofyourclass'); ?>> (still talking bout header.php to insert this) Jan 28, 2014 at 14:34
  • @CircuitCircus Please keep comment explosion under control by filing edits to your question/answer instead of adding a comment. Thanks.
    – kaiser
    Feb 9, 2014 at 12:21

This is how I solved my problem:

In my functions.php I added this:

function custom_css_style () {
    global $post;
    $parent = get_page($post->post_parent);
    $grandparent = $parent->post_parent;

    if ( is_page('40') || $post->post_parent == '40' || $grandparent == '40' ) {
        $cssclass = "roadkill-main-content";
    } else {
        $cssclass = "";
    return $cssclass;

And in my page.php I called this function:

<div id="main-content" class="main-content <?php echo custom_css_style(); ?>">

So I am able to define the backgroundcolor for cases I handle in my functions.php like this:

.roadkill-main-content {
     background-color: #9C006B;

I tried to make thos work using slugs, but it seems using the ID's is the only way to do it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.