How WordPress 6.9 changed CSS specificity for headings

A client called last week, an agency we work with. They had just rolled out the WordPress 6.9 update on one of their sites, and things suddenly looked broken. The headings inside some custom-built “feature boxes” on the homepage had picked up this odd, chunky padding that was not there before.

It looked like a classic WordPress CSS specificity problem, the kind of thing that eats hours if you do not know what to look for.

The “quick fix” trap

My first instinct, and probably a lot of developers’, was to write a CSS override. Add a more specific selector, maybe an !important if I was feeling lazy, and move on.

That would have worked, for about five minutes.

But that is how you end up with a stylesheet full of patches. A year from now, someone else, or future me, would be trying to work out why this one heading will not style right, only to find my !important rule buried in the code. That is technical debt, plain and simple.

So I dug deeper. It was not a plugin or the theme. It was a small but real change in WordPress core itself.

How WordPress 6.9 fixes heading block CSS

For years, the CSS that added padding to Heading blocks with a background color was too greedy. The selector looked something like this:

h1.has-background,
h2.has-background,
h3.has-background {
  padding: ...;
}

See the problem? That style hits any <h1>, <h2>, and so on that carries the .has-background class. It does not check whether that is a real .wp-block-heading block or just a heading sitting inside another block, like my client’s feature box. The Accordion block runs into the same thing.

WordPress 6.9 fixed this, as the official dev note at https://make.wordpress.org/core/2025/11/12/heading-block-css-specificity-fix-in-wordpress-6-9/ explains. The new selector is more precise:

h1:where(.wp-block-heading).has-background,
h2:where(.wp-block-heading).has-background,
h3:where(.wp-block-heading).has-background {
  padding: ...;
}

The :where() pseudo-class does the real work. It pulls in the .wp-block-heading class so the style hits only genuine Heading blocks, yet it keeps the selector’s specificity down at 0-1-1. That means theme developers can still override it without starting a specificity war.

So what’s the point?

This is a good change. It makes WordPress core styles more predictable and less likely to leak where they do not belong. But if your theme or a plugin was relying on the old, buggy behavior, things may look different after the update.

  • Don’t just patch it. Resist the urge to drop in a quick !important fix.
  • Investigate the selector. Use your browser’s inspector to find where the unwanted style comes from. If it is the core h...has-background style hitting a non-heading block, that is your culprit.
  • The right fix: your theme should add the padding styles to its own components directly, instead of piggybacking on a core style that was never meant for it.

This gets complicated quickly. If you are tired of untangling someone else’s mess and just want your site to work, get in touch with my team. We have probably seen it before.

This is a good example of why the “why” matters more than the “how.” The “how” was a five-second CSS patch. The “why” led to a stable fix and a clearer picture of where the block editor is heading.

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.