WordPress Conditional Tags and Adding Class Names to The Body

Updated 07/24/2024, Posted 07/24/2024 by James Parsons James Parsons 0 Comments

Adding class names to the <body> tag is helpful. But, if your body tags all look like this on every page, then you won't be able to target specific pages with your CSS as easily:

<body>

For example, this styling will affect ALL of your <h1> tags, so if you wanted it to appear style your blog (single) posts, you'll have a much harder time:

h1 {
  font-size:40px;
}

Ideally, you'd want it to add a .single class to your single blog posts <body> tag:

<body class="single">

This makes it much easier to be more specific with your CSS, so you can style your blog pages only:

.single h1 {
  font-size:40px;
}

Most WordPress themes ship with this functionality out of the box, and classes are automatically added to your <body> tag. But what if your <body> tag doesn't have class names already added like that? Many custom designed sites leave this out, either accidentally or because they simply didn't bother.

Here's some code you can add to the bottom of your theme's functions.php file to add these:

// Add <body> class names to various conditional tags for easier styling
 
function add_custom_body_classes($classes) {
  if (is_single()) $classes[] = 'single';
  if (is_page()) $classes[] = 'page';
  if (is_archive()) $classes[] = 'archive';
  if (is_search()) {
      $classes[] = 'search';
      $classes[] = have_posts() ? 'search-results' : 'search-no-results';
  }
  if (is_attachment()) $classes[] = 'attachment';
  if (is_404()) $classes[] = 'error404';
  if (is_home()) $classes[] = 'home';
  if (is_category()) $classes[] = 'category';
  if (is_tag()) $classes[] = 'tag';
  if (is_author()) $classes[] = 'author';
  if (is_date()) $classes[] = 'date';
  if (is_post_type_archive()) $classes[] = 'post-type-archive';
  if (is_sticky()) $classes[] = 'sticky';
  return $classes;
}
add_filter('body_class', 'add_custom_body_classes', 20);

function start_output_buffer() { ob_start('modify_body_tag');}
function end_output_buffer() {ob_end_flush();}
function modify_body_tag($buffer) {
  $classes = get_body_class();
  $class_string = implode(' ', $classes);
  $class_string = trim($class_string);
  $buffer = preg_replace_callback(
      '/<body([^>]*)>/i',
      function ($matches) use ($class_string) {
          if (preg_match('/class=["\']([^"\']*)["\']/i', $matches[1], $classMatches)) {
              $newClassAttr = 'class="' . trim($classMatches[1] . ' ' . $class_string) . '"';
              return '<body ' . preg_replace('/class=["\']([^"\']*)["\']/i', $newClassAttr, $matches[1]) . '>';
          } else {
              return '<body' . $matches[1] . ' class="' . $class_string . '">';
          }
      },
      $buffer
  );
  return $buffer;
}
add_action('template_redirect', 'start_output_buffer', 1); 
add_action('shutdown', 'end_output_buffer', 0); 

This adds a new CSS class to your <body> tag on page on your site, for all page types, from category pages to attachment pages to 404 pages.

Before this code, the body tag on our client's site looked like this:

<body>

Their body tag for single blog posts now looks like this:

<body class="post-template-default single single-post postid-462534 single-format-standard logged-in theme-wp woocommerce-no-js">

This makes styling specific page types in CSS much easier. We can now target by the specific post ID, whether or not the user is logged in, by the template name, and more! You'll see your other pages now have these same tags.

Has this helped you? Any questions for me? Leave me a comment below! I'd love to hear from you.

Related Code Snippets

Written by James Parsons

Hi, I'm James Parsons! I founded Content Powered, a content marketing agency where I partner with businesses to help them grow through strategic content. With nearly twenty years of SEO and content marketing experience, I've had the joy of helping companies connect with their audiences in meaningful ways. I started my journey by building and growing several successful eCommerce companies solely through content marketing, and I love to share what I've learned along the way. You'll find my thoughts and insights in publications like Search Engine Watch, Search Engine Journal, Forbes, Entrepreneur, and Inc, among others. I've been fortunate to work with wonderful clients ranging from growing businesses to Fortune 500 companies like eBay and Expedia, and helping them shape their content strategies. My focus is on creating optimized content that resonates and converts. I'd love to connect – the best way to contact me is by scheduling a call or by email.