Want to style all pages under /services/ differently? Learn how to inject parent slugs into WordPress body_class() function.
EN

Adding parent page slug to body classes (WordPress snippet)

5.00 /5 - (33 votes )
Last verified: March 1, 2026
Experience: 10+ years experience
Table of Contents

WordPress themes use body_class() to add helpful CSS classes to the <body> tag. However, by default, it doesn’t clearly indicate if a page is a child of a specific parent section.

If you have a structure like:

  • /services/
  • /services/web-design/
  • /services/seo/

You might want to style all pages under “Services” with a blue background. The default classes like page-id-123 are annoying to maintain.

The problem: Limited CSS targeting

WordPress’s default body_class() function adds classes like:

  • page-id-123 (numeric, hard to remember)
  • page-template-default (generic)
  • page (too broad)

But it doesn’t tell you:

  • What section the page belongs to
  • The page hierarchy (parent/child relationship)
  • The page slug (human-readable identifier)

This makes CSS targeting difficult. You end up with code like:

/* Bad: Hard to maintain */
.page-id-123,
.page-id-124,
.page-id-125 {
    background: blue;
}

Every time you add a new page, you need to update your CSS. This doesn’t scale.

The solution: Add parent slugs to body classes

By adding parent page slugs to the body class, you can target entire sections with a single CSS rule. This makes your stylesheet maintainable and scalable.

The complete snippet

Add this enhanced version to your functions.php:

/**
 * Add page slugs and parent slugs to body classes
 * 
 * Adds:
 * - Current page slug
 * - Parent page slug (if exists)
 * - Grandparent page slug (if exists)
 * - All ancestor slugs
 * 
 * @param array $classes Existing body classes
 * @return array Modified classes array
 */
function wppoland_add_slug_body_class( $classes ) {
    global $post;
    
    if ( ! isset( $post ) || ! is_page() ) {
        return $classes;
    }
    
    // 1. Add current page slug
    $classes[] = 'page-slug-' . sanitize_html_class( $post->post_name );
    
    // 2. Add parent page slug (if exists)
    if ( $post->post_parent ) {
        $parent = get_post( $post->post_parent );
        if ( $parent ) {
            $classes[] = 'parent-' . sanitize_html_class( $parent->post_name );
            
            // 3. Add grandparent slug (if exists)
            if ( $parent->post_parent ) {
                $grandparent = get_post( $parent->post_parent );
                if ( $grandparent ) {
                    $classes[] = 'grandparent-' . sanitize_html_class( $grandparent->post_name );
                }
            }
            
            // 4. Add all ancestor slugs (recursive)
            $ancestors = get_post_ancestors( $post->ID );
            foreach ( $ancestors as $ancestor_id ) {
                $ancestor = get_post( $ancestor_id );
                if ( $ancestor ) {
                    $classes[] = 'ancestor-' . sanitize_html_class( $ancestor->post_name );
                }
            }
        }
    }
    
    // 5. Add template hierarchy classes
    $template = get_page_template_slug( $post->ID );
    if ( $template ) {
        $template_slug = str_replace( '.php', '', basename( $template ) );
        $classes[] = 'template-' . sanitize_html_class( $template_slug );
    }
    
    return $classes;
}
add_filter( 'body_class', 'wppoland_add_slug_body_class' );

Result: Enhanced body classes

Now your <body> tag will include:

<body class="page page-id-123 page-slug-web-design parent-services ancestor-services ...">

Classes added:

  • page-slug-web-design - Current page slug
  • parent-services - Direct parent slug
  • grandparent-company - Grandparent slug (if exists)
  • ancestor-services - All ancestor slugs
  • template-custom - Template file name (if custom)

Usage examples

Example 1: Style all services pages

/* Blue background for ALL services pages */
body.parent-services {
    background-color: #eef;
}

/* Specific styling for services section header */
body.parent-services .site-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Services section footer */
body.parent-services .site-footer {
    border-top: 3px solid #667eea;
}

Example 2: Different layouts per section

/* Full-width layout for documentation */
body.parent-documentation .content-area {
    max-width: 100%;
    padding: 0;
}

/* Sidebar layout for blog */
body.parent-blog .content-area {
    max-width: 1200px;
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 2rem;
}

Example 3: Section-Specific navigation

/* Highlight current section in navigation */
body.parent-services .main-navigation .menu-item-services > a {
    color: #667eea;
    font-weight: bold;
}

/* Show section-specific menu items */
body.parent-services .section-menu {
    display: block;
}

Example 4: Conditional javascript

// Show different features based on section
if (document.body.classList.contains('parent-services')) {
    // Load services-specific scripts
    loadServicesWidget();
}

// Check for multiple ancestors
if (document.body.classList.contains('ancestor-company')) {
    // Company-wide styling
    applyCompanyBranding();
}

Advanced: Custom post types

The snippet works for pages, but you can extend it for custom post types:

function wppoland_add_cpt_slug_body_class( $classes ) {
    if ( is_singular() ) {
        global $post;
        
        // Add post type slug
        $classes[] = 'post-type-' . $post->post_type;
        
        // Add post type archive slug
        $post_type_obj = get_post_type_object( $post->post_type );
        if ( $post_type_obj && $post_type_obj->has_archive ) {
            $classes[] = 'archive-' . $post_type_obj->rewrite['slug'];
        }
        
        // Add taxonomy terms
        $taxonomies = get_object_taxonomies( $post->post_type );
        foreach ( $taxonomies as $taxonomy ) {
            $terms = get_the_terms( $post->ID, $taxonomy );
            if ( $terms && ! is_wp_error( $terms ) ) {
                foreach ( $terms as $term ) {
                    $classes[] = $taxonomy . '-' . sanitize_html_class( $term->slug );
                }
            }
        }
    }
    
    return $classes;
}
add_filter( 'body_class', 'wppoland_add_cpt_slug_body_class' );

Performance considerations

Caching body classes

The body_class filter runs on every page load. For high-traffic sites, consider caching:

function wppoland_add_slug_body_class_cached( $classes ) {
    $cache_key = 'body_classes_' . get_the_ID();
    $cached_classes = wp_cache_get( $cache_key );
    
    if ( false === $cached_classes ) {
        $cached_classes = wppoland_add_slug_body_class( array() );
        wp_cache_set( $cache_key, $cached_classes, '', 3600 );
    }
    
    return array_merge( $classes, $cached_classes );
}

Limiting ancestor depth

For deeply nested hierarchies, limit ancestor depth:

// In the snippet above, limit ancestors:
$ancestors = array_slice( get_post_ancestors( $post->ID ), 0, 3 ); // Max 3 levels

Troubleshooting

Classes not appearing

Problem: Body classes aren’t showing up.

Solutions:

  1. Check if body_class() is called in your theme’s header.php
  2. Verify the filter priority (should be default: 10)
  3. Clear any caching plugins
  4. Check for conflicts with other plugins

Duplicate classes

Problem: Classes appear multiple times.

Solutions:

  1. Use array_unique() to remove duplicates:
    return array_unique( $classes );
  2. Check if other plugins/themes add similar classes

Special characters IN slugs

Problem: Slugs with special characters break CSS.

Solutions:

  1. Use sanitize_html_class() (already in snippet)
  2. WordPress automatically sanitizes slugs, but double-check

Best practices

1. Use semantic class names

// Good
$classes[] = 'parent-services';

// Bad
$classes[] = 'p-serv';

2. Keep it simple

Don’t add too many classes. Stick to:

  • Current page slug
  • Parent slug
  • Maybe grandparent (if needed)

3. Document your classes

Add comments in your CSS:

/* Services Section
 * Applied to all pages under /services/
 * Classes: .parent-services, .ancestor-services
 */
body.parent-services { ... }

4. Test across themes

Body classes work with any theme, but test to ensure compatibility.

Real-World use cases

1. Multi-Site branding

Different sections have different color schemes:

body.parent-services { --primary-color: #667eea; }
body.parent-products { --primary-color: #f093fb; }
body.parent-support { --primary-color: #4facfe; }

2. Section-Specific widgets

Show different sidebar widgets per section:

if ( in_array( 'parent-services', get_body_class() ) ) {
    dynamic_sidebar( 'services-sidebar' );
}

3. Analytics tracking

Track section-specific events:

if (document.body.classList.contains('parent-services')) {
    gtag('event', 'page_view', {
        'section': 'services'
    });
}

Summary

Adding parent page slugs to body classes is a simple but powerful technique that makes CSS targeting scalable and maintainable. Instead of maintaining lists of page IDs, you can target entire sections with a single class.

Key Benefits:

  • ✅ Scalable: Works automatically for new pages
  • ✅ Maintainable: One CSS rule for entire sections
  • ✅ Semantic: Human-readable class names
  • ✅ Flexible: Works with any theme
  • ✅ Performance: Minimal overhead

When to Use:

  • Multi-section websites
  • Different layouts per section
  • Section-specific styling
  • Conditional feature loading

This technique is especially valuable in 2026, where websites are more complex and need flexible, maintainable CSS architectures.

What should you know about Adding parent page slug to body classes (WordPress snippet)?
Adding parent page slug to body classes (WordPress snippet) is an essential aspect of WordPress website management that helps improve site performance, security, and user experience.
How does Adding parent page slug to body classes (WordPress snippet) work?
Adding parent page slug to body classes (WordPress snippet) involves configuring various settings and implementing best practices to optimize your WordPress website.
Why is Adding parent page slug to body classes (WordPress snippet) important for WordPress?
Adding parent page slug to body classes (WordPress snippet) is crucial because it directly impacts your website's search engine rankings, loading speed, and overall success.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles