The Evolution of Background Styling in WordPress
Historically, applying a gradient to a block in WordPress was handled through the Color panel via the color.gradient block support. While this approach worked for basic designs, it introduced a significant technical limitation due to how the CSS was generated. The style engine stored this value at style.color.gradient and rendered it using the CSS background shorthand property.
In CSS, the background shorthand resets all individual background properties that are not explicitly defined within it. This includes background-image, background-position, background-repeat, and background-size. Consequently, if a block developer or site editor attempted to apply both a background image and a gradient to the same block, the gradient’s shorthand declaration would conflict with and completely override the background image. Users were forced to choose between a gradient or an image, or write custom CSS classes and wrapper blocks to achieve a simple overlay effect.
To resolve this conflict, WordPress 7.1 introduces the new background.gradient block support. This feature separates gradient configuration from the Color panel and integrates it directly into the Background panel, allowing gradients and background images to coexist and render together harmoniously.
Introducing the background.gradient Block Support
The core change in WordPress 7.1 is the registration of the background.gradient block support. Instead of saving values to the legacy style.color.gradient path, this new support stores its data at style.background.gradient.
The critical difference lies in how the style engine renders the CSS. Rather than relying on the destructive background shorthand, the new support targets the background-image longhand property. Because it uses the longhand property, it does not reset other background configurations. When both a background image and a gradient are defined on a block, the style engine outputs them as comma-separated values within a single background-image declaration:
background-image: linear-gradient( 135deg, #000 0%, #fff 100% ), url( 'https://example.com/image.jpg' );
In CSS, multiple background images are stacked in the order they are declared, with the first declared item rendered on top. By outputting the gradient first, WordPress layers the gradient directly over the background image, enabling instant overlay effects (such as darkening an image to ensure text readability) directly from the block inspector.
To maintain a clean user interface, when a block opts into background.gradient, the editor automatically suppresses the legacy gradient tab in the Color panel. This prevents duplicate controls from confusing users.
How to Opt-In via block.json
The background.gradient support is an opt-in feature for block developers. To enable this control in your custom blocks, you must declare it within your block’s block.json file under the supports object. You should also define it within the __experimentalDefaultControls object to ensure the control is visible by default in the block inspector.
Here is the exact configuration required to enable both background images and background gradients for a custom block:
{
"supports": {
"background": {
"backgroundImage": true,
"gradient": true,
"__experimentalDefaultControls": {
"backgroundImage": true,
"gradient": true
}
}
}
}
In WordPress 7.1, several core blocks have already migrated to this new support structure. These include:
- Group (
core/group) - Accordion (
core/accordion) - Pullquote (
core/pullquote) - Post Content (
core/post-content) - Quote (
core/quote)
Configuring Gradients in theme.json
Theme developers can define default background gradients globally or on a per-block basis using theme.json. The values are declared under the background styles group.
The following example demonstrates how to set a global default background gradient at the root level, and how to assign a specific theme preset gradient to the Group block:
{
"version": 2,
"styles": {
"background": {
"gradient": "linear-gradient( 135deg, #000 0%, #fff 100% )"
},
"blocks": {
"core/group": {
"background": {
"gradient": "var:preset|gradient|vivid-cyan-blue"
}
}
}
}
}
When referencing theme presets, you can use the standard var:preset|gradient|{slug} syntax. The style engine will resolve this to the corresponding CSS custom property, such as var( --wp--preset--gradient--vivid-cyan-blue ), when rendering the frontend markup. Block-level styles configured by users in the editor will override these theme.json defaults, adhering to the standard WordPress style cascade.
Under the Hood: CSS Longhands and the Style Engine
The WordPress style engine handles the heavy lifting of merging and rendering these styles server-side. When a block is rendered, the style engine checks for the presence of both style.background.gradient and style.background.backgroundImage.
If only a gradient is defined without a background image, the engine outputs the gradient on its own within the background-image property:
background-image: var( --wp--preset--gradient--vivid-cyan-blue );
If both are present, they are merged into the comma-separated list. The style engine checks serialization for the image and the gradient independently. This means a block can opt to skip serialization for one of the properties (for example, if a custom block needs to handle the image rendering manually via inline CSS or a custom wrapper) while still allowing the style engine to output the other.
Sanitization and safecss_filter_attr() Updates
A significant technical hurdle in implementing this feature was WordPress’s built-in CSS sanitization. By default, inline styles on block wrappers are passed through the safecss_filter_attr() function to prevent malicious code execution (such as cross-site scripting attacks via CSS injection).
Prior to WordPress 7.1, safecss_filter_attr() was highly restrictive. If it detected a background-image value that combined a CSS gradient function (like linear-gradient()) with a url() function in a single declaration, it flagged the value as unsafe and stripped it entirely from the rendered output.
To support the new background styling system, WordPress 7.1 updates the parser inside safecss_filter_attr(). The function now safely parses and permits combined gradient and url() values. Developers do not need to register custom sanitization filters or bypass core KSES security protocols to use layered background styles.
Backwards Compatibility and the Future of color.gradient
The introduction of background.gradient is fully additive and backwards compatible. No existing blocks will break, and theme developers do not need to make immediate changes to their themes.
Blocks that continue to use the legacy color.gradient support will function exactly as they did before, storing their values in style.color.gradient and rendering via the background shorthand. However, these blocks will still suffer from the original limitation of not being able to combine gradients with background images.
This new support lays the groundwork for a future migration where gradient handling across all core blocks may eventually transition from color.gradient to background.gradient. This will consolidate background styling into a single, cohesive system. However, this migration is not part of the WordPress 7.1 release, giving developers ample time to update their custom blocks and themes to the new standard.
Frequently asked questions
Can I use background.gradient and color.gradient on the same block?
When background.gradient is enabled for a block, the editor automatically suppresses the gradient control in the Color panel to prevent duplicate controls and user confusion. You should transition your block to use background.gradient if you want to support background images alongside gradients.
What happens if a browser doesn't support multiple background images?
Modern browsers have universal support for multiple background images using comma-separated values in the background-image property. For extremely legacy browsers, they will gracefully degrade to displaying either no background or a fallback solid background color if defined.
Do I need to write custom PHP filters to allow combined gradients and URLs in inline styles?
No. In WordPress 7.1, the core safecss_filter_attr() function has been updated to natively allow combined gradient functions and url() values, meaning they will not be stripped during sanitization.
Primary reference: Review the original announcement for exact release details. This article is an independent explanation and does not reproduce the source text.