Filter Hook since 2.7.0

post_class

Filters the CSS classes on a single post's wrapper element

Description

post_class runs once per post inside the loop — unlike body_class, which runs once per page — so keep the callback fast if you're looping many posts.

When it runs

Each time post_class() is called inside The Loop — archives, search results, and single views.

Signature

apply_filters( 'post_class', string[] $classes, string[] $css_class, int $post_id );

Parameters

  • $classes string[] — Post class names.
  • $css_class string[] — Additional classes passed to post_class().
  • $post_id int — Post ID.

Examples

Basic

add_filter( 'post_class', function( $classes, $css_class, $post_id ) {
    if ( has_post_thumbnail( $post_id ) ) {
        $classes[] = 'has-thumbnail';
    }
    return $classes;
}, 10, 3 );

Add a class when the post has a featured image, for CSS targeting.

Common Use Cases

  • Add a class for featured-image presence
  • Highlight sticky or featured posts
  • Add taxonomy-term-based classes
  • Alternate row classes for grid layouts

Common mistakes

  • Running expensive queries (like meta lookups) inside post_class on archive pages with many posts — it fires once per post and can slow the page

Related hooks

FAQ

post_class vs body_class — which one do I use?

body_class targets the <body> tag once per page; post_class targets each individual post wrapper and runs once per post in the loop.

Source: wp-includes/post-template.php

Group wizard

One session: this hook, then each related_hooks entry. Walk it and tell us what to change.

post_class → body_class

functions.php — post_class
functions.php
PHP post_class · Hook 1 of 2 · Step 1 of 6

Practice the post_class WordPress filter hook in our interactive sandbox — a VS Code-style editor with a step-by-step post_class tutorial, add_filter exercises, and instant feedback. No local WordPress install required.