Block Supports: Add background clip support to facilitate text gradients#76033
Block Supports: Add background clip support to facilitate text gradients#76033aaronrobertshaw wants to merge 14 commits intotrunkfrom
Conversation
Adds a new `backgroundClip` style definition to both the JavaScript and PHP style engines. When the value is `text`, the engines emit the additional vendor-prefixed properties (`-webkit-background-clip` and `-webkit-text-fill-color: transparent`) needed to clip backgrounds to text, enabling gradient text effects.
Update the background block support PHP render filter to handle backgroundClip alongside backgroundImage. Each support now independently checks for both feature support and serialization skip. Add background.backgroundClip support to heading and paragraph blocks.
Introduces a new BackgroundClipControl component using the Composite + Composite.Item pattern for selecting background-clip values (border-box, padding-box, content-box, text) with static CSS-based background-clip previews Use actual background-clip CSS on preview elements instead of static SVGs, so each option visually demonstrates the clipping behavior it represents.
In global styles, all supported controls should be visible by default. The backgroundClip control was missing from DEFAULT_CONTROLS, so it was hidden behind the tools panel dropdown menu.
Like textIndent, backgroundClip may not exist in parent settings if the theme hasn't opted in via appearanceTools. When a block declares backgroundClip support, default the setting to true so the control is visible in global styles.
…k inspector Reverts the shared useSettingsForBlockElement change which incorrectly forced backgroundClip on in both contexts. Instead, enables backgroundClip in the settings only within the global styles screen-block, following the same pattern as disableBlockGap and disableAspectRatio.
The camelCase keys WebkitBackgroundClip and WebkitTextFillColor were being converted via paramCase to webkit-background-clip (missing the leading dash). Use the literal CSS property names instead, matching the PHP style engine which already uses -webkit-background-clip and -webkit-text-fill-color.
…tput The compute_style_properties method in WP_Theme_JSON generates CSS from PROPERTIES_METADATA directly, bypassing the style engine. When background-clip is set to 'text', the -webkit-background-clip and -webkit-text-fill-color declarations were missing from the generated global styles CSS. The block supports render filter and inline styles already handled this via the style engine, but global styles output did not.
kebabCase() strips the leading dash from vendor-prefixed properties like -webkit-background-clip, producing webkit-background-clip. Skip kebabCase conversion for keys that already start with '-', as these are already valid CSS property names. Fixes the issue in both the style engine's compileCSS and the global styles engine's render output.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @jnz31, @CreativeDive, @insaineyesay. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +2.61 kB (+0.04%) Total Size: 6.87 MB
ℹ️ View Unchanged
|
I'm not convinced background-clip is useful as a block support in itself. Reading the issues requesting gradient support for text, I was more thinking this should be an option you could set in text colour. So you'd click color > text, and in the popover you'd have "color" and "gradient" tabs like we currently have in background. Then, if you selected a gradient for text color, background color would either be disabled, or we'd pop up a warning saying that background color doesn't apply to blocks with text color gradients. Does that make sense? Apart from simplifying the UI, this would have the advantage of not exposing the implementation. Using |
|
Thanks both for the thoughtful feedback 👍 These are exactly the concerns I had in the back of my mind when putting this together, and I should have called them out in the description along with some of the ideas I'd discussed privately (adding a section now). I agree that a user wanting gradient text will think "text color", not "background clip". That said, I'd push back slightly on calling One idea I've been turning over, was as touched on already: the block support could adaptively change what control it renders based on which clip values are allowed. Similar to the enum setting used for the Line Indent block support, we could allow themes to define which background clipping options they wish to expose. Alternatively, we could lean on the default controls to be displayed like the Border control. Displaying only the text option by default would be the equivalent to setting only If a theme opts into In other words, I'm aligned with @ramonjd on splitting the concerns: text gradient UX → color panel, clip-to-box UX → background panel. Both ultimately write to There's no rush to land this, so happy to wait for design input before settling on the right UI direction. In the meantime, I might see if I can throw up a quick PoC on splitting the concerns. |
I don't mean background-clip being deprecated or anything, but other ways of adding gradients to text may become available. But my main concern here is with exposing background-clip as a tool in the UI. Aside from the text gradient, it doesn't feel useful. Anyone wanting to apply a background color to the content box only can achieve similar effects by using margins instead of padding, so as a control background-clip doesn't add much value in itself. Is it worth the extra complexity introduced by a new block support? Personally I don't think so. It would be good to have @WordPress/gutenberg-design opinions on this before proceeding. |
I'm not sure margins are a reliable substitute here. Padding creates space inside the border, margins outside it. So as soon as a block has a visible border, you can't replicate Then there's
It's worth noting that a new block support is needed either way. Even if we only ever expose the text gradient use case, that still requires a new block support whether it's under the banner of the color group of supports or background. It still requires The UI concern is real, though, and I agree that surfacing background clip directly isn't ideal for most cases. I'm exploring that separately at the moment, the idea being that the text gradient use case gets a friendlier home in the colour panel and the box-clipping values only appear if a theme explicitly opts into them. So in practice, most users would never encounter a "background clip" control at all other than the text gradient control. |
I can imagine padding-box in particular being useful. I'm just looking at the examples at https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/background-clip |
|
A proof of concept is taking shape, though a number of problems were encountered while trying to build the combined text gradient control on top of The proof of concept in #76171 addresses this by building on the proposed There are still a number of rough edges in the UI so it isn't ready for demo or testing yet, but should be by later this week or early next. One consideration worth raising: combining the background gradient and background clip into a single text gradient control removes the ability to clip a background image to text rather than a gradient. While testing, this turned out to produce some interesting aesthetics, particularly on large, chunky headings. Once the proof of concept is more fleshed out, it would be worth evaluating whether the hybrid approach strikes the right balance between a streamlined text gradient flow and split controls (background image + background clip) for clipping a background image to text |
It would be very cool to clip to an image. I'm just speaking for myself 😄
This is pretty out there, but this reminds me of this idea: #60401 (comment)
|
This is an early morning vague thought, I've no idea if relevant. But you could: I.e. you don't have to put the clip part inside the shorthand selector, it can still exist separately to it, so long as it's below the shorthand declaration. I use this often with things like background and background-position. Adding a background image is certainly interesting. But it's a difficult balance we're trying to strike here; the ability to add a "gradient" tab to the color panel seems so straight-forward and relatively intuitive, that I think it will make an excellent UI for this. Whereas the alternative can very easily get complex, UI wise. It's also arguably a bit of an edge-case to use images for this, so I'd personally be comfortable relegating this to requiring custom CSS for now. However, and connecting back to #38577, one option to explore in the future, would be to add a 3rd tab, "Pattern" (or "Image") to the text color flyout, which would let you pick from a couple of bundled pattern images, or pick your own. Provided we could find the space for it (not much room for more tabs) and phrasing, that could unlock the UI for it. I think it'd be fine to explore, but I'd still keep it separate for now. Is that fair? |
|
Just to be clear, I'm fully on board with adding a gradient tab to the Color panel's text section. The questions are really about what it builds on and how much of the underlying functionality we expose.
Thanks @jasmussen. The issue isn't about CSS declaration order, though. Block support styles are applied as React inline style objects, and React throws a runtime error when a style object contains both a shorthand property and a longhand it covers, in this case There are actually two separate questions. The first is which gradient support the text gradient control should build on. The second is whether theme authors should have access to the full On the first question, a few things worth laying out:
On the second question, the tradeoff with On the image clipping point, agreed it's a niche case for now, and custom CSS is a reasonable fallback. The "Pattern/Image" tab idea is worth keeping in mind for later. The main concern is that collapsing clip into the gradient control and the So yes, broadly fair, with the caveat that the path to a gradient tab in the Color panel probably runs through I hope all that makes sense 🤞 |
I have a bias toward fixing the If it can be done under the hood, and it allows us to tread lightly in the UI and open up more design options for discussion I'm all for it! Thanks for the laying out the issues and the great discussion 🙇🏻 |




What?
Closes #30982
Closes #49642
Introduces
background-clipas a new block support and Global Styles feature.Heading and paragraph blocks opt in by default.
A new
BackgroundClipControlcomponent lets users select from the four standardbackground-clipvalues —border-box,padding-box,content-box, andtext— with live CSS-based previews for each option.When
textis selected, the required companion declarations (-webkit-background-clip: text,-webkit-text-fill-color: transparent,color: transparent) are emitted automatically, enabling gradient text effects when combined with a background gradient or image.Why?
Users have long been able to apply gradients and background images to blocks, but had no way to clip that background to the text content — the CSS technique used to create gradient-coloured text. Achieving this required hand-written CSS (see #49642).
Adding
background-clipas a first-class block support resolves that gap and fits naturally alongside the existingbackgroundsupport group (backgroundImage,gradient). It also provides a clean integration point that avoids the current tension betweencolor.gradientandbackground.gradient, since both surface a gradient onbackground-imageand can now be combined with clip behaviour in a backwards-compatible way.How?
backgroundClipstyle definition that generatesbackground-clipand, when the value istext, the three companion vendor-prefixed declarations. Fixed akebabCaseconversion bug that was stripping the leading dash from vendor-prefixed properties (e.g. producingwebkit-background-clipinstead of-webkit-background-clip).WP_Theme_JSON::compute_style_propertiesbypasses the style engine, so vendor-prefixed declarations fortextclipping were added there separately.backgroundClipalongsidebackgroundImage, with independent checks for feature support and serialization skip.headingandparagraphblock.json files opt in viasupports.background.backgroundClip. The setting defaults totruewhen a block declares support, so the control appears even when the theme hasn't enabledappearanceTools.BackgroundClipControlcomponent (usingComposite/Composite.Item) renders interactive previews using actualbackground-clipCSS, so each option visually demonstrates the clipping behaviour it represents. The control appears in the Background panel in Global Styles and is included inDEFAULT_CONTROLSso it is visible without needing to enable it from the dropdown.disableBlockGapanddisableAspectRatio.background-clipand vendor-prefixed variants to the allowed CSS properties.UI/UX considerations for further iteration
The current PR exposes
background-clipas a direct block support control. There is an open question about whether this is the right UI surface — particularly for the common use case of gradient text, where users are unlikely to look in a "background clipping" control.A future iteration could hide the implementation detail and instead surface an ergonomic gradient picker inside the Color → Text panel, which writes to both
backgroundandbackgroundClipbehind the scenes. The block support could adaptively show:textclipping is enabledThis mirrors the approach used by the
borderblock support for toggling subfeature controls. Design input would be valuable here before finalising the UI direction.Still todo
BackgroundClipControlUI (currently aComposite-based popover) has been assembled as a functional prototype and needs design review before this is considered complete. Feedback on the control layout, option labels, and preview style is welcome.Testing Instructions
Appearance → Editor).textclip value (e.g. Border box) and confirm the gradient reverts to a standard background fill.-webkit-background-clip: text,-webkit-text-fill-color: transparent, andcolor: transparentare all present when Text clip is active, and absent otherwise.Testing Instructions for Keyboard
Screenshot
Demo
Screen.Recording.2026-03-01.at.10.55.13.pm.mp4