How to Add Custom Body Classes in WordPress

December 14, 2025
How to Add Custom Body Classes in WordPress

The <body> class attribute is one of the most powerful (and often underused) tools in WordPress theming. By adding custom body classes, you can target specific pages, post types, templates, or conditions with clean, maintainable CSS and JavaScript — without relying on inline styles or messy selectors.

This article explains how to add custom body classes properly in WordPress, with practical examples you can use in real projects.


What Are Body Classes?

WordPress automatically outputs contextual classes on the <body> tag using body_class().

Example output:

<body class="home blog logged-in admin-bar">

These classes reflect the current page type, login state, template, and more — making them ideal hooks for styling and behavior.


Always Use body_class() in Your Theme

First, make sure your theme outputs body classes correctly.

<body <?php body_class(); ?>>

If body_class() is missing from header.php, none of the techniques below will work.


How to Add Custom Body Classes (The Right Way)

Use the body_class filter. This is safe, future-proof, and compatible with plugins.

add_filter( 'body_class', function( $classes ) {

  $classes[] = 'my-custom-class';

  return $classes;
} );

This adds my-custom-class to every page.


Add Body Classes Conditionally

In most cases, you want classes only on specific pages or conditions.

Add a class only on the homepage

add_filter( 'body_class', function( $classes ) {

  if ( is_front_page() ) {
    $classes[] = 'is-front-page';
  }

  return $classes;
} );

Add a class only on single posts

add_filter( 'body_class', function( $classes ) {

  if ( is_single() ) {
    $classes[] = 'is-single-post';
  }

  return $classes;
} );

Add a class for a specific page slug

add_filter( 'body_class', function( $classes ) {

  if ( is_page( 'contact' ) ) {
    $classes[] = 'page-contact';
  }

  return $classes;
} );

This is useful for landing pages and one-off designs.


Add Body Classes for Custom Post Types

Class for all posts of a CPT

add_filter( 'body_class', function( $classes ) {

  if ( is_singular( 'product' ) ) {
    $classes[] = 'single-product-page';
  }

  return $classes;
} );

Different class per CPT archive

add_filter( 'body_class', function( $classes ) {

  if ( is_post_type_archive( 'event' ) ) {
    $classes[] = 'archive-event';
  }

  return $classes;
} );

Add Body Classes Based on Page Template

WordPress already adds a template-based class, but you can customize or simplify it.

add_filter( 'body_class', function( $classes ) {

  if ( is_page_template( 'templates/landing.php' ) ) {
    $classes[] = 'tpl-landing';
  }

  return $classes;
} );

Add Body Classes Based on User State

Logged-in vs logged-out

add_filter( 'body_class', function( $classes ) {

  if ( is_user_logged_in() ) {
    $classes[] = 'user-logged-in';
  } else {
    $classes[] = 'user-logged-out';
  }

  return $classes;
} );

This is useful for UI differences without PHP conditionals in templates.


User role–based body class

add_filter( 'body_class', function( $classes ) {

  if ( is_user_logged_in() ) {
    $user = wp_get_current_user();
    if ( ! empty( $user->roles ) ) {
      $classes[] = 'role-' . esc_attr( $user->roles[0] );
    }
  }

  return $classes;
} );

Example output:

role-administrator

Add Body Classes Based on Taxonomy

Single post with a specific category

add_filter( 'body_class', function( $classes ) {

  if ( is_single() && has_category( 'news' ) ) {
    $classes[] = 'cat-news';
  }

  return $classes;
} );

Custom taxonomy term

add_filter( 'body_class', function( $classes ) {

  if ( is_tax( 'genre', 'rock' ) ) {
    $classes[] = 'genre-rock';
  }

  return $classes;
} );

Sanitizing Dynamic Body Classes

If you generate classes dynamically, always sanitize them.

add_filter( 'body_class', function( $classes ) {

  if ( is_page() ) {
    $slug = get_post_field( 'post_name', get_queried_object_id() );
    if ( $slug ) {
      $classes[] = 'page-' . sanitize_html_class( $slug );
    }
  }

  return $classes;
} );

Never trust raw values for class names.


Where to Put This Code

  • Best: Code Snippets plugin (easy to manage and disable)
  • Also OK: Child theme functions.php
  • Best for many rules: Small custom plugin

Common Mistakes to Avoid

  • Hardcoding classes directly in header.php
  • Forgetting to return $classes in the filter
  • Adding too many highly specific classes unnecessarily
  • Using unsanitized dynamic values

Why Body Classes Matter for Clean CSS

Instead of writing CSS like this:

.page-id-42 .site-main .content .title {}

You can write:

.page-contact .title {}

This improves readability, maintainability, and long-term scalability.


Conclusion

Custom body classes give you a clean separation between logic and presentation. By using the body_class filter correctly, you gain precise control over styling and behavior without cluttering templates or writing fragile selectors.

Key takeaway:
Add body classes via filters, keep them meaningful, and let CSS and JS do the rest.

This small technique makes a big difference in professional WordPress theme development.

Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.