WordPress Conditional Tags and Adding Class Names to The Body

James Parsons by James Parsons Updated Jul 24th, 2024 6 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

James Parsons is the founder and CEO of Content Powered, a premier content marketing agency that leverages nearly two decades of his experience in content marketing to drive business growth. Renowned for founding and scaling multi-million dollar eCommerce businesses through strategic content marketing, James has become a trusted voice in the industry, sharing his insights in Search Engine Watch, Search Engine Journal, Forbes, Entrepreneur, Inc, and other leading publications. His background encompasses key roles across various agencies, contributing to the content strategies of major brands like eBay and Expedia. James's expertise spans SEO, conversion rate optimization, and effective content strategies, making him a pivotal figure in the industry.