Skip to content

Block Supports: Add a PHP helper that returns every support's classes and styles - #86337

Merged
aaronrobertshaw merged 3 commits into
trunkfrom
add/block-supports-classes-and-styles-php-helper
Nov 6, 2026
Merged

aaronrobertshaw merged 3 commits into
trunkfrom
add/block-supports-classes-and-styles-php-helper

Conversation

@aaronrobertshaw

@aaronrobertshaw aaronrobertshaw commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Core backport: WordPress/wordpress-develop#15485

Related:

What?

Adds one PHP helper that returns the classes and styles of every support that has a helper: background, color, border, shadow and spacing.

gutenberg_get_block_supports_classes_and_styles( $attributes, array( 'border', 'shadow' ) );
// array( 'class' => 'has-border-color has-accent-2-border-color', 'style' => 'border-width:2px;box-shadow:...;' )

Blocks call it as wp_get_block_supports_classes_and_styles(). Avatar and Post Navigation Link now use it.

Why?

A block that skips serialization for several supports calls one helper per support, then joins the results by hand. Every such block repeats that code and must get the order right.

How?

The helper calls the five support helpers in the style engine's order and removes duplicate classes. It doesn't check block support or skipped serialization.

The optional second argument limits which supports it includes. Both blocks need it, because they apply other supports to another element.

  • Avatar: border and shadow on the image.
  • Post Navigation Link: background, border and shadow in one call. Spacing stays a separate call because dimensions come between shadow and spacing.
  • Build: wp_get_block_supports_classes_and_styles joins prefixFunctions.

Blocks left as they are

Block Reason
Post Featured Image Size styles sit between border and shadow on the image
Icon Leaves out has-background and has its own color handling
Search Shadow follows the border elements, background follows the color element
Button, Calendar, Comment Author Avatar, Navigation Submenu One support each

Testing Instructions

Nothing visible changes, so there are no screenshots.

On Twenty Twenty-Five, 45 renders of Avatar and Post Navigation Link match trunk byte for byte.

To check by hand:

  1. Add an Avatar and a Post Navigation Link to a post.
  2. Give each a border, a shadow and padding. Give the link a gradient background and a minimum height.
  3. Copy the front end HTML of both blocks on trunk, then on this branch. They should match.

Use of AI Tools

Implemented and tested with Claude Code.

@aaronrobertshaw aaronrobertshaw added [Type] Code Quality Issues or PRs that relate to code quality [Package] Block library /packages/block-library [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Nov 5, 2026
@aaronrobertshaw aaronrobertshaw self-assigned this Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground Preview in Storybook

🎉 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: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>

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


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

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

📦 Bundle size

Size Change: 0 B

Total Size: 8.62 MB

931f00c Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 836f6f3 trunk % Change
timeToFirstByte 33.6 ms +15.63% -3.27% 34 ms +5.44% -3.82% -1.18%
largestContentfulPaint 56 ms +14.29% -0% 60 ms +3.33% -6.67% -6.67%
lcpMinusTtfb 23.5 ms +21.28% -5.96% 23.8 ms +3.15% -4.83% -1.26%
wpBeforeTemplate 17.56 ms +16.17% -2.51% 17.61 ms +4.88% -2.73% -0.28%
wpTemplate 13.15 ms +6.92% -6.16% 13.26 ms +5.58% -5.28% -0.83%
wpTotal 30.59 ms +17.33% -3.4% 31.11 ms +4.73% -4.18% -1.67%
wpMemoryUsage 7.72 MB +0% -0% 7.68 MB +0% -0% 0.44%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric 836f6f3 trunk % Change
timeToFirstByte 27.05 ms +12.38% -1.11% 27.6 ms +10.87% -3.62% -1.99%
largestContentfulPaint 60 ms +10% -0% 64 ms +6.25% -6.25% -6.25%
lcpMinusTtfb 33.6 ms +8.04% -1.19% 35.25 ms +6.24% -5.25% -4.68%
wpBeforeTemplate 15.29 ms +6.8% -0.92% 15.1 ms +5.3% -1.13% 1.26%
wpTemplate 9.6 ms +7.92% -5.52% 9.82 ms +5.5% -5.19% -2.24%
wpTotal 24.84 ms +12.4% -2.13% 25.23 ms +10.98% -3.77% -1.55%
wpMemoryUsage 6.41 MB +0% -0% 6.37 MB +0% -0% 0.54%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric 836f6f3 trunk % Change
mediaProcessingJpeg 218.23 ms +3.02% -1.1% 221.62 ms +1.08% -2.79% -1.53%
mediaProcessingAvif 3555.74 ms +0.18% -0.6% 3614.12 ms +0.36% -0.06% -1.62%
mediaProcessingJpegToAvif 2483.98 ms +0.53% -0.19% 2485.48 ms +0.57% -0.59% -0.06%

media-upload

Metric 836f6f3 trunk % Change
jpegUploadProcessing 1398.66 ms +1.2% -0.94% 1387.7 ms +0.49% -0.43% 0.79%
pngUploadProcessing 168.96 ms +5.3% -1.76% 173.11 ms +3.11% -0.94% -2.4%
largeJpegUploadProcessing 1414.21 ms +0.82% -0.98% 1392.04 ms +0.14% -0.2% 1.59%
multipleImageUploadProcessing 1455.82 ms +0.31% -1.69% 1428.69 ms +0.91% -0.18% 1.9%

post-editor

Metric 836f6f3 trunk % Change
serverResponse 406.65 ms +3.03% -9.79% 410.93 ms +3.97% -5.44% -1.04%
firstPaint 320.74 ms +17.56% -5.42% 351.17 ms +4.91% -8.29% -8.67%
domContentLoaded 799.68 ms +0.68% -0.69% 795.42 ms +2.57% -0.98% 0.54%
loaded 800.51 ms +0.7% -0.66% 796.37 ms +2.57% -0.97% 0.52%
firstContentfulPaint 462.93 ms +1.43% -0.53% 461.5 ms +2.04% -1.73% 0.31%
firstBlock 2000.21 ms +1.02% -1.07% 1980.73 ms +0.37% -0.88% 0.98%
type 16.4 ms +3.48% -12.2% 16.23 ms +8.93% -10.54% 1.05%
typeWithoutInspector 16.73 ms +5.38% -8.31% 16.6 ms +4.22% -8.92% 0.78%
typeWithTopToolbar 21.75 ms +9.38% -7.31% 21.57 ms +3.8% -5.8% 0.83%
typeContainer 7.66 ms +9.79% -3.52% 7.95 ms +13.46% -16.35% -3.65%
focus 116.61 ms +4.81% -6.51% 109.51 ms +4.07% -5.86% 6.48%
firstFocus 238.76 ms +0% -0% 226.29 ms +0% -0% 5.51%
selectAll 351.66 ms +4.37% -2.71% 346.92 ms +3.87% -4.48% 1.37%
undo 29.67 ms +16.21% -4.75% 29 ms +4.45% -3.59% 2.31%
listViewOpen 74.75 ms +11.48% -12.04% 76.11 ms +17.91% -15.31% -1.79%
inserterOpen 39.77 ms +11.01% -6.21% 39.39 ms +12.74% -9.57% 0.96%
inserterHover 11.6 ms +10.95% -13.45% 12 ms +8.25% -8.67% -3.33%
inserterSearch 9.25 ms +2.27% -8.86% 8.1 ms +10.99% -7.04% 14.2%
loadPatterns 642.1 ms +8.62% -0.93% 683.87 ms +48.09% -4.3% -6.11%
wpTotal 397.05 ms +2.83% -9.89% 401.05 ms +4.22% -5.42% -1%
wpMemoryUsage 14.76 MB +0% -0% 14.73 MB +0% -0% 0.24%
wpDbQueries 55 +0% -0% 55 +0% -0% 0%

site-editor

Metric 836f6f3 trunk % Change
serverResponse 318.36 ms +0.33% -9.32% 312.47 ms +0.9% -9.59% 1.88%
firstPaint 301.17 ms +1.69% -15.84% 255.4 ms +17.26% -7.21% 17.92%
domContentLoaded 692.23 ms +2.57% -1.26% 673.24 ms +1.03% -0.58% 2.82%
loaded 693.05 ms +2.58% -1.27% 673.91 ms +1.07% -0.56% 2.84%
firstContentfulPaint 406.23 ms +1.88% -2.28% 387.49 ms +0.34% -1.59% 4.84%
firstBlock 2015.13 ms +2.42% -0.55% 1978.29 ms +0.56% -0.15% 1.86%
type 14.96 ms +1.07% -5.75% 14.65 ms +4.91% -9.01% 2.12%
navigate 89.86 ms +8.57% -2.97% 83.23 ms +15.91% -1.98% 7.97%
loadPatterns 1015.43 ms +7.71% -16.82% 1110.14 ms +2.12% -23.65% -8.53%
loadPages 1005.8 ms +1.47% -1.4% 1013.81 ms +1.21% -0.27% -0.79%
wpTotal 310.07 ms +0.34% -9.58% 304.22 ms +0.9% -9.85% 1.92%
wpMemoryUsage 12.78 MB +0% -0% 12.74 MB +0% -0% 0.27%
wpDbQueries 45 +0% -0% 45 +0% -0% 0%

931f00c 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.

Page List converts to Navigation Links with entity bindings in /test/e2e/specs/editor/blocks/navigation.spec.js, passed after 1 failed attempt.
Error: expect(locator).toContainText(expected) failed

Locator: getByRole('region', { name: 'Editor settings' }).getByRole('tabpanel', { name: 'Content' }).getByRole('button', { name: /Link to:/ })
Expected substring: "test-page-1"
Received string:    "Link to:Cat/catPagePublished"
Timeout: 5000ms

Call log:
  - Expect "toContainText" getByRole('region', { name: 'Editor settings' }).getByRole('tabpanel', { name: 'Content' }).getByRole('button', { name: /Link to:/ }) with timeout 5000ms
  - waiting for getByRole('region', { name: 'Editor settings' }).getByRole('tabpanel', { name: 'Content' }).getByRole('button', { name: /Link to:/ })
    14 × locator resolved to <button type="button" aria-expanded="false" aria-haspopup="dialog" class="components-button link-preview-button is-next-40px-default-size is-secondary">…</button>
       - unexpected value "Link to:Cat/catPagePublished"

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/navigation.spec.js:1949:31

closes the new note form on focus-out only when empty in /test/e2e/specs/editor/various/block-notes.spec.js, passed after 1 failed attempt.

does not select blocks in the canvas preview when editing from the sidebar (Site Editor v2) in /test/e2e/specs/site-editor/navigation-sidebar-list-view.spec.js, passed after 1 failed attempt.
Error: expect(locator).toBeFocused() failed

Locator: getByRole('combobox', { name: 'Search or type URL' })
Expected: focused
Timeout: 5000ms
Error: element(s) not found

Call log:
  - Expect "toBeFocused" getByRole('combobox', { name: 'Search or type URL' }) with timeout 5000ms
  - waiting for getByRole('combobox', { name: 'Search or type URL' })

    at LinkControl.useLinkControlSearch (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/site-editor/navigation-sidebar-list-view.spec.js:416:47)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/site-editor/navigation-sidebar-list-view.spec.js:179:21
should undo without broken temporary state in /test/e2e/specs/editor/blocks/image.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 2
+ Received  + 2

- <!-- wp:image -->
- <figure class="wp-block-image"><img alt=""/></figure>
+ <!-- wp:image {"id":26,"sizeSlug":"full","linkDestination":"none"} -->
+ <figure class="wp-block-image size-full"><img src="http://localhost:8889/wp-content/uploads/2026/11/2f453dc6-e085-4497-bea1-00ee6b0b4b82.png" alt="" class="wp-image-26"/></figure>
  <!-- /wp:image -->
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/image.spec.js:432:49

931f00c Run

@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.

This is great, thanks for all the work on these helper functions! I like the default $supports param, too, in that it means folks can skip specifying the supports and get additional supports kinda "for free" if/when more are added to the helper further down the track.

Smoke-testing well:

Image

LGTM!

Comment thread lib/block-supports/utils.php Resolved
Comment thread phpunit/block-supports/utils-test.php Resolved
Comment thread lib/block-supports/utils.php Resolved
Comment thread phpunit/block-supports/utils-test.php Resolved
… and styles

Combines the background, color, border, shadow and spacing helpers in the
style engine's order. An optional list limits it to the supports a block
applies to one element. Avatar and Post Navigation Link now use it.
@aaronrobertshaw
aaronrobertshaw force-pushed the add/block-supports-classes-and-styles-php-helper branch from 6041354 to 931f00c Compare November 6, 2026 09:21
@aaronrobertshaw
aaronrobertshaw enabled auto-merge (squash) November 6, 2026 09:21
@aaronrobertshaw

Copy link
Copy Markdown
Contributor Author

Appreciate the reviews and testing here folks. Thank you.

I'll look to get this merged.

@aaronrobertshaw
aaronrobertshaw merged commit e7287a2 into trunk Nov 6, 2026
79 checks passed
@aaronrobertshaw
aaronrobertshaw deleted the add/block-supports-classes-and-styles-php-helper branch November 6, 2026 09:41
@github-actions github-actions Bot added this to the Gutenberg 24.5 milestone Nov 6, 2026
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 [Package] Block library /packages/block-library [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants