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
$classesstring[] — Post class names.$css_classstring[] — Additional classes passed to post_class().$post_idint — 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