WordPress 6.6 CSS Specificity

One of the goals of WordPress 6.6 is to simplify the process for theme authors to override coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. styles while also maintaining support for Global Styles.

Historically, high CSSCSS Cascading Style Sheets. specificity in core styles has made customization challenging and unpredictable, often requiring complex CSS rules to achieve desired outcomes. Development of the new section styles feature also highlighted a need for uniform CSS specificity to support nesting such styles, facilitating the creation of sophisticated, layered designs.

Uniform 0-1-0 Specificity

WordPress 6.6 introduces several changes aimed at broadly reducing CSS specificity and making it more uniform. These changes generally fall into two categories:

  1. Core BlockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. Styles
  2. Theme.jsonJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. / Global Styles:

Where adjustments to CSS specificity were required, they were achieved by wrapping the existing selector within :root :where(...).

Core Block Styles

The choice of 0-1-0 specificity greatly reduced the changes required to existing core block styles as blocks targeting their default .wp-block- class already have the desired specificity.

Any blocks with Global Styles support using higher specificity selectors had those selectors wrapped in :root :where(...). This also applied to Block Styles (aka block style variations) and their default styles e.g., .wp-block-image.is-style-rounded img was updated to :root :where(.wp-block-image.is-style-rounded img).

Theme.json / Global Styles:

All block styles, including block style variation styles, output by theme.json and Global Styles are now limited to 0-1-0 specificity. Layout styles, e.g., constrained, flex, flow` etc., have also been limited however depending on the specific layout type and definition the final specificity varies slightly from 0-1-0 so they apply correctly.

Usage

The alignment of 0-1-0 specificity for Global Styles to default block selectors, e.g. .wp-block-, greatly reduces the need for updates. It’s recommended for theme and block authors to double-check their designs if they rely on custom CSS using more complex selectors.

Custom blocks

Authors of custom blocks that opt into global styles and apply default styling via a selector with greater than 0-1-0 specificity, should update those selectors wrapping them in :root :where().

An example could be a custom list block that opts into padding block support but defines default padding via:

ul.wp-block-custom-list {
    padding: 0;
}

Without adjusting the specificity of this rule, any customizations of the block type’s padding in Global Styles would be overridden. Wrapping the selector in :root :where() here would allow the style load order to determine which rule takes precedence.

// Block's stylesheet
:root :where(ul.wp-block-custom-list) { // This is a contrived example and could simply be `.wp-block-custom-list`
    padding: 0;
}

// Global Styles - Loaded after the block styles
:root :where(.wp-block-custom-list) {
    padding: 1em;
}

Block Styles (aka Block Style Variations)

Theme authors customizing Block Styles for a core block will need to limit their style’s specificity, so the block style continues to be configurable via Global Styles.

For example, take a theme that tweaks the border radius for the Image block’s rounded block style:

.wp-block-image.is-style-rounded img {
    border-radius: 2em;
}

Without adjustment, this style would override any customizations made to the Rounded block style within Global Styles.

In this case, the theme can tweak its rounded image style to the following:

//. Theme style
:root :where(.wp-block-image.is-style-rounded img) {
    border-radius: 2em;
}

// Global Styles - Loaded after the block styles
:root :where(.wp-block-image.is-style-rounded img) {
    border-radius: 4px;
}

Zero-Specificity, CSS Layers, and the future

Reducing all core styles to zero specificity was explored before settling on 0-1-0 specificity. Zero specificity unfortunately wasn’t robust in the face of common reset stylesheets and required more widespread changes.

CSS Layers were also evaluated but fell short due to not being able to enforce all styles belonged to a layer. This will change in the future at which point a combination of CSS Layers and zero-specificity can be revisited to further the benefits gained in this initial reduction of CSS specificity.

More history and context can be found in this detailed discussion.

Useful Links

Props to @bph and @juanmaguitar for review

#6-6, #core-editor, #dev-note, #dev-notes, #dev-notes-6-6, #gutenberg