2026年11月12日

2026年11月12日

WordPress CSS Selectors: body_class, post_class and Block Classes

This article is a localized edition of the Japanese original. Read the Japanese original

In a WordPress theme, the <body> tag and the element that wraps each post automatically get classes describing the page being shown and the state of the post. With them you can write rules such as "front page only" or "only posts in this category" without looking up page IDs.

The class names in this article were checked against the source code of WordPress 6.9 as of November 2026 (get_body_class() and get_post_class() in wp-includes/post-template.php).

First, check which classes are actually there

Classes vary by theme and by page, so the quickest reliable approach is to check them in the browser before you write anything.

  1. Open the page, right-click and choose "Inspect" (Chrome, Edge) or "Inspect" (Firefox).
  2. In the "Elements" panel of the developer tools, look at the contents of <body class="…">.
  3. For the post itself, look at the classes of the element that wraps it, such as <article class="…">.

If there are no classes at all, the theme does not call body_class() or post_class(). In your own theme, write the <body> tag in header.php like this:

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

Inside the Loop, the element that wraps each post looks like this:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

Main classes added by body_class()

Page being shown Example classes
Front page home
Posts page (the page set as the posts page under Reading settings, or the front page if it shows your latest posts) blog
Single post single single-post postid-123
Page page page-id-42
Page using a page template page-template page-template-full-width page-template-full-width-php
Category archive archive category category-news category-5
Tag archive archive tag tag-wordpress
Search results search search-results or search-no-results
404 page error404
Logged in logged-in
Admin bar showing admin-bar

home is the class for the front page; there is no front-page class. Page template classes are built from the template's file name (full-width.php becomes full-width).

/* Make the header transparent on the front page only */
body.home .site-header {
    background: transparent;
}

/* Narrow the content width on single posts only */
body.single-post .entry-content {
    max-width: 720px;
}

/* A different color per category archive (slugs news and event) */
body.category-news {
    --color-accent: #2271b1;
}
body.category-event {
    --color-accent: #d63638;
}

/* Only the page with ID 42 */
body.page-id-42 .hero {
    min-height: 100vh;
}

/* Pages using the full-width.php template */
body.page-template-full-width .site-main {
    max-width: 100%;
}

Classes such as category-news are added to the category archive page, not to the single pages of posts in that category. To style single posts by category, use the post_class() classes described next.

Fixing a fixed header that overlaps the admin bar

When you are logged in, the admin bar appears at the top of the screen, and a header with position: fixed can end up hidden behind it. The WordPress admin bar is 32px tall on screens wider than 782px and 46px tall at 782px and below.

body.admin-bar .site-header {
    top: 32px;
}

@media screen and (max-width: 782px) {
    body.admin-bar .site-header {
        top: 46px;
    }
}

At 600px and below, the admin bar scrolls up with the page, so a gap can appear above a fixed header. If that bothers you, adjust it on real devices, for example by setting top: 0 back at that width.

Main classes added by post_class()

Condition Example classes
Every post post-123 post type-post status-publish hentry
Post format (if the theme supports it) format-standard format-video format-quote
Has a featured image has-post-thumbnail
Password protected post-password-required
Categories and tags category-news tag-wordpress
Sticky post sticky (only on the first page of the posts list)

hentry is added to every post; it does not mean "the post being shown." And sticky is not added anywhere except the first page of the posts list (not on single pages, not on page 2 and later).

/* Add a border to sticky posts */
.post.sticky {
    border-left: 4px solid #2271b1;
    padding-left: 1rem;
}

/* Posts with the quote format */
.post.format-quote blockquote {
    font-size: 1.25rem;
    font-style: italic;
}

/* Show a label before the title of posts in the news category */
.post.category-news .entry-title::before {
    content: "NEWS";
    display: inline-block;
    margin-right: 0.5rem;
    padding: 0.15rem 0.5rem;
    border-radius: 2px;
    background: #2271b1;
    color: #fff;
    font-size: 0.7rem;
}

Classes of block editor blocks

In content built with the block editor, many blocks get a wp-block-blockname class. Not every block does, though.

Block Element and class on the front end
Paragraph <p>. No wp-block-paragraph class
Heading <h2 class="wp-block-heading"> and so on (WordPress 6.2 and later)
Image <figure class="wp-block-image">
Buttons .wp-block-button inside .wp-block-buttons; the link is .wp-block-button__link
Columns .wp-block-column inside .wp-block-columns
Cover .wp-block-cover; the content is .wp-block-cover__inner-container
Quote <blockquote class="wp-block-quote">
Table <table> inside <figure class="wp-block-table">

Because paragraph blocks get no class, target paragraphs in your content through the element that wraps the content, as in .entry-content p (the name .entry-content differs by theme).

/* Paragraphs in the content */
.entry-content p {
    line-height: 1.8;
}

/* Headings in the content (heading block, WordPress 6.2 and later) */
.entry-content .wp-block-heading {
    margin-top: 2.5em;
}

/* The button of a Buttons block */
.wp-block-button .wp-block-button__link {
    border-radius: 4px;
}

/* Images aligned "Full width" or "Wide width" */
.wp-block-image.alignfull {
    margin-left: 0;
    margin-right: 0;
}

To change just one particular block, enter your own class name under "Advanced" → "Additional CSS class(es)" in the block settings sidebar and target that class in your CSS. Other blocks are not affected.

Shorter selectors with newer pseudo-classes

Pseudo-class Use it to
:is() Group several selectors. Specificity is that of the most specific one inside
:where() Group several selectors. Specificity is 0, so it is easy to override later
:not() Exclude some elements
:has() Select a parent by whether it contains a child. Supported in Chrome 105, Safari 15.4, Firefox 121 and later
/* h2 to h4 in the content at once */
.entry-content :is(h2, h3, h4) {
    line-height: 1.3;
}

/* Set default spacing with specificity 0 (easy for theme rules to override) */
:where(.entry-content) > * + * {
    margin-top: 1.5rem;
}

/* Remove the underline except on links whose class contains button */
.nav-menu a:not([class*="button"]) {
    text-decoration: none;
}

/* Remove the top padding of the body only in cards that contain an image */
.card:has(img) .card-body {
    padding-top: 0;
}

How specificity works is explained in detail in the article on CSS specificity, and the difference between :is() and :where() in the article on :is() and :where().

Making the editor look like the front end

In a classic theme, to apply your theme's CSS to the block editor screen as well, load it in functions.php like this. The path is relative to the theme folder.

<?php
add_action( 'after_setup_theme', function () {
    add_theme_support( 'editor-styles' );
    add_editor_style( 'css/editor-style.css' );
} );

In css/editor-style.css, write ordinary rules with the same selectors as on the front end. WordPress rewrites the selectors for the editor when it loads them (for example, body becomes .editor-styles-wrapper). So you do not need to write internal editor class names such as .editor-styles-wrapper yourself.

/* css/editor-style.css */
body {
    font-family: -apple-system, "Hiragino Sans", sans-serif;
    font-size: 1rem;
    line-height: 1.8;
    color: #1d2327;
}

.wp-block-quote {
    border-left: 4px solid #2271b1;
    padding-left: 1rem;
}

Things to watch

  • Class names and HTML structure inside blocks can change with WordPress updates (the heading block only got wp-block-heading in 6.2). Check the front end after major updates.
  • Selectors based on IDs, such as page-id-42, stop working when you recreate the page or move to another site and the ID changes. For rules you want to keep long term, page templates or additional CSS classes are easier to maintain.
  • Stacking !important makes later overrides difficult. Adjust selector specificity first.

Summary

  • For page-level rules, use the body_class() classes (home, single-post, page-id-42, category-news and so on). There is no front-page class.
  • For post-level rules, use the post_class() classes. hentry is on every post, and sticky appears only on the first page of the posts list.
  • Paragraph blocks have no wp-block-paragraph class, so target them through the element that wraps the content.
  • Load editor CSS with add_editor_style() and write it with the same selectors as the front end.

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲