Skip to content

Global Styles: List the blocks that override an element - #84671

Open
aaronrobertshaw wants to merge 10 commits into
trunkfrom
add/global-styles-element-applies-to
Open

aaronrobertshaw wants to merge 10 commits into
trunkfrom
add/global-styles-element-applies-to

Conversation

@aaronrobertshaw

@aaronrobertshaw aaronrobertshaw commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Related:

What?

Element screens in Global Styles (Headings, Links, Buttons) now list the block types whose own styles override the element. Each item opens that block's screen.

Why?

A site owner sets Headings to bold and the Title stays regular. Twenty Twenty-Three gives the Title block its own font weight, and a block-type style beats the element style. Nothing on the Headings screen says so.

How?

  • Map: the block-to-element map behind getElementLayers is now a table. Its inverse, getBlockTypesForElement(), is a block editor private API.
  • Overrides: resolveStyle runs with and without block styles. A block type is listed when a leaf the element sets comes from the block layer.
  • Heading levels: the list is the same on All and H1 to H6.
  • Lint: element-block-overrides.tsx keeps a no-restricted-imports suppression for ./lock-unlock, like the 13 other files in this package that call unlock.

Limits

  • Core blocks only.
  • Blocks that contain an element, such as a Paragraph with a link, are not listed.
  • Block style variations are not considered.
  • The list ignores state: with Hover selected on Links or Buttons, it still shows default-state overrides.

Testing Instructions

  1. Activate Twenty Twenty-Three.
  2. Styles > Blocks & Elements > Headings > All headings: "Applies to" lists Title, Site Title and Comments Title.
  3. Click Title: the Title block screen opens.
  4. Links, Buttons and Captions list nothing.
  5. On the Blocks screen, give Read More its own text colour and font weight. It now appears under Links.
  6. Repeat in the extensible site editor (gutenberg-extensible-site-editor experiment).

Screenshots or screencast

composite

Use of AI Tools

Implemented and tested by a Claude Code agent from a predefined task.

@aaronrobertshaw aaronrobertshaw self-assigned this Oct 14, 2026
@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label Oct 14, 2026
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

📦 Bundle size

Size Change: +525 B (+0.01%)

Total Size: 9.05 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 606 kB +69 B (+0.01%)
build/scripts/edit-site/index.min.js 423 kB +22 B (+0.01%)
build/scripts/editor/index.min.js 619 kB +434 B (+0.07%)

5557e6f Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric cd1b4de trunk % Change
timeToFirstByte 55.4 ms +6.95% -2.08% 54.4 ms +10.11% -1.75% 1.84%
largestContentfulPaint 92 ms +8.7% -2.17% 96 ms +2.08% -8.33% -4.17%
lcpMinusTtfb 36.6 ms +14.21% -5.87% 36.1 ms +14.82% -7.89% 1.39%
wpBeforeTemplate 29.86 ms +11.79% -1.88% 29.44 ms +4.93% -3.06% 1.43%
wpTemplate 21.23 ms +5.18% -1.65% 21.53 ms +3.07% -5.48% -1.39%
wpTotal 51.37 ms +7.96% -1.85% 50.74 ms +9.42% -1.77% 1.24%
wpMemoryUsage 7.66 MB +0% -0% 7.63 MB +0% -0% 0.47%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric cd1b4de trunk % Change
timeToFirstByte 43.65 ms +11% -1.95% 46.85 ms +5.23% -2.03% -6.83%
largestContentfulPaint 94 ms +6.38% -2.13% 102 ms +1.96% -1.96% -7.84%
lcpMinusTtfb 49.7 ms +3.92% -1.31% 54.85 ms +3.1% -1.55% -9.39%
wpBeforeTemplate 28.13 ms +10.7% -2.24% 26.9 ms +3.38% -1.23% 4.57%
wpTemplate 12.65 ms +8.7% -1.58% 16.52 ms +4.84% -2.06% -23.43%
wpTotal 40.74 ms +11.68% -2.11% 43.78 ms +5.57% -2.12% -6.94%
wpMemoryUsage 6.24 MB +0% -0% 6.32 MB +0% -0% -1.18%
wpDbQueries 9 +0% -0% 13 +0% -0% -30.77%

media-processing

Metric cd1b4de trunk % Change
mediaProcessingJpeg 406.75 ms +1.5% -0.74% 407.46 ms +1% -0.8% -0.17%
mediaProcessingAvif 6111.4 ms +0.19% -0.1% 6114.61 ms +0.09% -0.42% -0.05%
mediaProcessingJpegToAvif 4211.71 ms +0.2% -0.36% 4215.95 ms +0.17% -0.13% -0.1%

media-upload

Metric cd1b4de trunk % Change
jpegUploadProcessing 1455 ms +35.69% -1.76% 1431.19 ms +0.65% -0.5% 1.66%
pngUploadProcessing 207.27 ms +7.07% -12.42% 205.02 ms +13.15% -9.64% 1.1%
largeJpegUploadProcessing 1421.95 ms +2.3% -0.48% 1428.6 ms +0.86% -0.91% -0.47%
multipleImageUploadProcessing 2047.73 ms +2.38% -1.67% 1634.14 ms +22.71% -1.54% 25.31%

post-editor

Metric cd1b4de trunk % Change
serverResponse 477.26 ms +12.99% -4.36% 515.88 ms +7.27% -3.92% -7.49%
firstPaint 486.79 ms +4.51% -49.53% 319.54 ms +68.56% -18.53% 52.34%
domContentLoaded 1192.46 ms +4.29% -3.43% 1211.43 ms +0.73% -2.91% -1.57%
loaded 1193.57 ms +4.29% -3.42% 1212.6 ms +0.74% -2.9% -1.57%
firstContentfulPaint 508.45 ms +2.94% -4.96% 527.96 ms +3.74% -7.03% -3.7%
firstBlock 3535.53 ms +6.83% -2.34% 3677.82 ms +0.71% -3.43% -3.87%
type 18.54 ms +2.32% -3.13% 18.35 ms +4.31% -2.02% 1.04%
typeWithoutInspector 17.54 ms +4.39% -4.16% 18.53 ms +4.86% -6.26% -5.34%
typeWithTopToolbar 23.43 ms +5.38% -2.73% 23.23 ms +4.43% -2.24% 0.86%
typeContainer 8.88 ms +14.41% -4.39% 8.66 ms +3.58% -6.58% 2.54%
focus 121.9 ms +11.46% -2.31% 127.64 ms +4.72% -6.75% -4.5%
firstFocus 240.38 ms +0% -0% 227.44 ms +0% -0% 5.69%
selectAll 596.91 ms +1.23% -0.67% 612.09 ms +0.97% -7.3% -2.48%
listViewOpen 88.26 ms +4.49% -9.08% 80.52 ms +5.23% -11.1% 9.61%
inserterOpen 42.93 ms +4.52% -11.37% 40.77 ms +13.91% -6.89% 5.3%
inserterHover 12.24 ms +9.97% -11.76% 11.42 ms +8.76% -5.43% 7.18%
inserterSearch 8.57 ms +3.73% -7.7% 8.1 ms +3.7% -2.84% 5.8%
loadPatterns 645.68 ms +0.53% -4.51% 651.44 ms +2.57% -4.02% -0.88%
wpTotal 466.8 ms +13.36% -4.52% 505.69 ms +7.48% -4.06% -7.69%
wpMemoryUsage 14.70 MB +0% -0% 14.64 MB +0% -0% 0.37%
wpDbQueries 55 +0% -1.82% 55 +0% -1.82% 0%

site-editor

Metric cd1b4de trunk % Change
serverResponse 503.54 ms +2.33% -4.19% 494.54 ms +6.61% -5.12% 1.82%
firstPaint 248.44 ms +19.01% -9.58% 278.68 ms +10.07% -14.05% -10.85%
domContentLoaded 1273.61 ms +0.46% -0.99% 1281.85 ms +1.02% -0.51% -0.64%
loaded 1274.63 ms +0.45% -0.95% 1283.01 ms +1.02% -0.51% -0.65%
firstContentfulPaint 505.44 ms +4.14% -3.01% 521.31 ms +2.12% -8.61% -3.04%
firstBlock 4766.84 ms +0.42% -0.37% 4772.51 ms +0.97% -0.34% -0.12%
type 18.24 ms +3.73% -4.93% 19.65 ms +4.38% -4.53% -7.18%
navigate 125.47 ms +6.2% -2.73% 129.26 ms +6.24% -4.12% -2.93%
loadPatterns 1285.66 ms +10.35% -6.54% 1324.56 ms +4.29% -0.38% -2.94%
loadPages 993.21 ms +2.72% -0.59% 1005.82 ms +3.38% -5.15% -1.25%
wpTotal 493.82 ms +2.43% -4.36% 484.56 ms +6.85% -5.11% 1.91%
wpMemoryUsage 12.71 MB +0% -0% 12.68 MB +0% -0% 0.29%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

5557e6f Run

🏁 Flaky tests

Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

Regression: updating a specific option will only change its value and will not corrupt others in /test/e2e/specs/editor/various/core-settings.spec.js, passed after 1 failed attempt.
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 1
+ Received  + 1

  Array [
    "rewrite_rules",
-   "SERIALIZED DATA",
+   "",
  ]
    at forEach (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:46:26)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:43:35
does not save CRDT document for auto-draft posts in /test/e2e/specs/editor/collaboration/collaboration-persistence.spec.ts, passed after 1 failed attempt.
Test timeout of 100000ms exceeded.
drags a multi-selection from anywhere inside it in /test/e2e/specs/editor/various/draggable-blocks.spec.js, passed after 1 failed attempt.
TypeError: Cannot read properties of null (reading 'y')
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/draggable-blocks.spec.js:824:57
    at dragSelectionBelowLanding (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/draggable-blocks.spec.js:823:3)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/draggable-blocks.spec.js:844:3
refuses the drop and uploads nothing in /test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js, passed after 1 failed attempt.
Error: expect(received).toHaveLength(expected)

Expected length: 0
Received length: 1
Received array:  [{"_links": {"about": [{"href": "http://localhost:8889/wp-json/wp/v2/types/attachment"}], "author": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/users/1"}], "collection": [{"href": "http://localhost:8889/wp-json/wp/v2/media"}], "curies": [{"href": "https://api.w.org/{rel}", "name": "wp", "templated": true}], "replies": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/comments?post=223"}], "self": [{"href": "http://localhost:8889/wp-json/wp/v2/media/223", "targetHints": {"allow": ["GET", "POST", "PUT", "PATCH", "DELETE"]}}], "wp:attached-to": [{"embeddable": true, "href": "http://localhost:8889/wp-json/wp/v2/posts/222", "id": 222, "post_type": "post"}]}, "alt_text": "", "author": 1, "caption": {"rendered": ""}, "class_list": ["post-223", "attachment", "type-attachment", "status-inherit", "hentry", "entry"], "comment_status": "open", "date": "2026-10-22T07:27:42", "date_gmt": "2026-10-22T07:27:42", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/10/eb5770e5-eabb-45cd-9955-7553ed17297b.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/10/eb5770e5-eabb-45cd-9955-7553ed17297b.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "eb5770e5-eabb-45cd-9955-7553ed17297b.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/10/eb5770e5-eabb-45cd-9955-7553ed17297b.png"}, "id": 223, "link": "http://localhost:8889/?attachment_id=223", "media_details": {"file": "2026/10/eb5770e5-eabb-45cd-9955-7553ed17297b.png", "filesize": 80, "height": 10, "image_meta": {"alt": "", "aperture": "0", "camera": "", "caption": "", "copyright": "", "created_timestamp": "0", "credit": "", "focal_length": "0", "iso": "0", "keywords": [], "orientation": "0", "shutter_speed": "0", "title": ""}, "sizes": {}, "width": 10}, "media_type": "image", "meta": [], "mime_type": "image/png", "modified": "2026-10-22T07:27:42", "modified_gmt": "2026-10-22T07:27:42", "ping_status": "closed", "post": 222, "slug": "eb5770e5-eabb-45cd-9955-7553ed17297b", "source_url": "http://localhost:8889/wp-content/uploads/2026/10/eb5770e5-eabb-45cd-9955-7553ed17297b.png", "status": "inherit", "template": "", "title": {"rendered": "eb5770e5-eabb-45cd-9955-7553ed17297b"}, "type": "attachment"}]
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js:71:45

5557e6f Run

@aaronrobertshaw aaronrobertshaw changed the title Global Styles: List the block types that override an element ("Applies to") Global Styles: List the block types that override current global styles element Oct 14, 2026
@aaronrobertshaw
aaronrobertshaw force-pushed the add/global-styles-element-applies-to branch from 6f08e65 to 5fc785f Compare October 15, 2026 10:48
@github-actions github-actions Bot added [Package] Editor /packages/editor [Package] Edit Site /packages/edit-site labels Oct 15, 2026
@aaronrobertshaw
aaronrobertshaw force-pushed the add/global-styles-element-applies-to branch from 5fc785f to c1a295b Compare October 15, 2026 11:00
@github-actions github-actions Bot removed [Package] Editor /packages/editor [Package] Edit Site /packages/edit-site labels Oct 15, 2026
@aaronrobertshaw
aaronrobertshaw force-pushed the add/global-styles-element-applies-to branch from c1a295b to 0e5b364 Compare October 16, 2026 11:42
@jasmussen

Copy link
Copy Markdown
Contributor

Noting that I like this a lot, mostly at a glance.

@aaronrobertshaw
aaronrobertshaw force-pushed the add/global-styles-element-applies-to branch from 0e5b364 to 723ec71 Compare October 20, 2026 06:42
Lift the getElementLayers switch into a table keyed by element and add
getBlockTypesForElement, exposed as a private API, so Global Styles can
list the block types an element paints.
On the Headings, Links and Buttons screens, show an "Applies to" list of
the block types whose own styles beat the element for a property it sets,
each linking to the block's screen. Overrides come from the inherited
value resolver, with and without block styles.
@aaronrobertshaw
aaronrobertshaw force-pushed the add/global-styles-element-applies-to branch from f6b0ea1 to 6a4e9ba Compare October 21, 2026 05:19
Move getOverridingBlockTypes and its helpers into element-block-overrides.tsx, reuse BlockMenuItem for the items and ScreenBody for the padding, and drop the extra style rule.

Make the state test cover the state filter, drop the unreachable nested elements check, and trim the tests. Rename the component test to .jsx, like screen-header.jsdom.test.jsx, so lint:tsconfig passes without a dev project.

Export getBlockTypesForElement from the global-styles index instead of its own private-apis import.
@aaronrobertshaw aaronrobertshaw changed the title Global Styles: List the block types that override current global styles element Global Styles: List the blocks that override an element Oct 21, 2026
Give global-styles-ui a dev project, as the TypeScript packages do: tsconfig.build.json builds src, and tsconfig.json checks the tests. Point the packages and routes that reference it at the build project.

Rename the component test back to .tsx, type it, and drop its two lint suppressions.
@github-actions github-actions Bot added [Package] Editor /packages/editor [Package] Edit Site /packages/edit-site labels Oct 21, 2026
@aaronrobertshaw aaronrobertshaw added [Type] Enhancement A suggestion for improvement. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Oct 22, 2026
Drops the package tsconfig split, so the PR no longer touches any tsconfig file.
@github-actions github-actions Bot removed [Package] Editor /packages/editor [Package] Edit Site /packages/edit-site labels Oct 22, 2026
@aaronrobertshaw
aaronrobertshaw marked this pull request as ready for review October 22, 2026 07:58
'core/accordion-heading',
'core/heading',
'core/post-title',
'core/site-title',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some themes (like TT4 and TT5) set "level":0 for site title, which will render as <p />

See

https://github.com/WordPress/wordpress-develop/blob/trunk/src/wp-content/themes/twentytwentyfive/patterns/header.php#L21

https://github.com/WordPress/gutenberg/blob/add/global-styles-element-applies-to/packages/block-library/src/site-title/edit.jsx#L44

How should we handle those cases do you think?

Maybe we could drop them if they're level 0, e.g.,

.filter(
	( blockType ): blockType is BlockType =>
		!! blockType &&
		// Renders as a paragraph unless a heading level is picked.
		blockType.attributes?.level?.default !== 0
)

@ramonjd

ramonjd commented Oct 22, 2026

Copy link
Copy Markdown
Member

While testing I discovered the "Reset all" on typography doesn't clear the color of the site title text:

2026-10-22.19.23.53.mp4

Fix here

@andrewserong andrewserong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the ability to drill down from the elements screen to other blocks that use the element! While the PR description (and linked discussions) help explain the rationale for only showing those blocks that have overrides for the element, while testing I found myself wondering the following when I saw the UI:

  • "Applies to" doesn't show the Heading block, does that mean this isn't meant to apply to the Heading block?
  • Likewise since Accordion Heading isn't listed does that mean this isn't meant to apply to the accordion?
Image

So, my first impression was that the drilldown here was meant to list every block that contains that element so that you can go from Heading element down to whichever other heading blocks you want to customise.

I think for me this comes down to the label that's used. Would it help to label this something like "Blocks that override this element"? Terrible example of wording to actually use, but I guess what I'm trying to say is, "Applies to" seems a bit general / possibly ambiguous, and I'm wondering if there's a way to be more specific here, either via the label or adding help text? 🤔

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new helper lacks a runtime compatibility guard, and override detection can both omit affected blocks and list unaffected ones.

4 open issues
What changed in this PR

Adds an “Applies to” list to Global Styles element screens so users can navigate to blocks whose styles override the selected element.

Changes:

  • Extracts a shared block-to-element map and exposes its inverse through a block-editor private API.
  • Adds override detection and linked block lists to the shared element screen.
  • Adds focused tests, a changelog entry, and a lint suppression.
File Description
tools/​eslint/​suppressions.json Adds a restricted-import suppression.
packages/​global-styles-ui/​src/​test/​screen-block-list.jsdom.test.js Tests override detection and exclusions.
packages/​global-styles-ui/​src/​screen-element.tsx Displays the override list.
packages/​global-styles-ui/​src/​screen-block-list.tsx Exports the reusable block menu item.
packages/​global-styles-ui/​src/​element-block-overrides.tsx Detects overriding blocks and renders navigation links.
packages/​global-styles-ui/​CHANGELOG.md Documents the element-screen enhancement.
packages/​block-editor/​src/​components/​global-styles/​test/​inherited-value-context-elements.jsdom.test.ts Tests inverse element mappings.
packages/​block-editor/​src/​components/​global-styles/​inherited-value-context.ts Extracts the shared map and adds inverse lookup.
packages/​block-editor/​src/​components/​global-styles/​index.ts Exposes the inverse lookup through private APIs.

Review effort: Balanced

config: GlobalStylesConfig | undefined,
element: string
): string[] {
const blockNames: string[] = getBlockTypesForElement( element );
Comment on lines +209 to +210
return Object.hasOwn( ELEMENT_BLOCK_TYPES, key )
? ELEMENT_BLOCK_TYPES[ key ]
const elements = getElementKeys( element );
// Any block name works here: with block styles dropped, only root and element layers remain.
const { sources: elementSources } = resolveStyle(
{ ...config, styles: { ...config.styles, blocks: undefined } },
( path ) =>
isOwnStylePath( path ) &&
sources[ path ].layer === 'block' &&
elementSources[ path ]?.layer === 'element'

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants