Skip to content

Border: Add a PHP helper for block support classes and styles - #84207

Open
aaronrobertshaw wants to merge 8 commits into
trunkfrom
update/border-classes-and-styles-php-helper
Open

aaronrobertshaw wants to merge 8 commits into
trunkfrom
update/border-classes-and-styles-php-helper

Conversation

@aaronrobertshaw

@aaronrobertshaw aaronrobertshaw commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Follows up on #83122.

Related:

Core backport: wordpress-develop#14094.

What?

Adds a PHP version of the JS getBorderClassesAndStyles(), which turns border attributes into classes and inline styles.

wp_get_border_classes_and_styles( $block_attributes );
// array( 'class' => 'has-border-color has-contrast-border-color', 'style' => 'border-width:2px;' )

The border block support and four blocks now use it.

Why?

Four blocks skip border serialization and rebuild their border styles by hand. Their copies have drifted from the block support:

Unitless 5 Side order
Border block support 5px width, color, style
Avatar, Post Featured Image, Icon dropped color, style, width

0 now outputs 0px, as the block support does.

One helper keeps them all in step.

How?

The helper only builds output. It doesn't check block support.

  • Border block support: keeps its checks, then calls the helper
  • Avatar, Post Featured Image: border functions become one-line wrappers
  • Icon, Post Navigation Link: only their border part changes
  • Build: added to prefixFunctions, so the plugin calls gutenberg_get_border_classes_and_styles()

The only block support output change: a null, false, empty or zero borderColor now falls back to the custom color, as in JS. So does an array, which cannot form a class name.

Testing Instructions

Markup matches trunk

  1. Add an Avatar, a Post Featured Image with an overlay, an Icon and a Post Navigation Link.
  2. Give each a border with a preset color and one wider side.
  3. Compare the front end markup with trunk. It should match, apart from the order of the side declarations in Avatar, Post Featured Image and Icon.

Unitless values

  1. In the code editor, set "radius":5 on the Avatar's border.
  2. View the front end. The image now has border-radius:5px. On trunk it has no radius.

Use of AI Tools

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

@aaronrobertshaw aaronrobertshaw added [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement. [Package] Block library /packages/block-library Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Oct 8, 2026
@aaronrobertshaw aaronrobertshaw self-assigned this Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 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>

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: 0 B

Total Size: 9.05 MB

bc6a069 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric de2aa8e trunk % Change
timeToFirstByte 46.75 ms +1.18% -4.71% 46.15 ms +2.49% -4.44% 1.3%
largestContentfulPaint 80 ms +10% -0% 80 ms +7.5% -5% 0%
lcpMinusTtfb 33.9 ms +14.45% -3.1% 33.05 ms +21.63% -2.57% 2.57%
wpBeforeTemplate 23.36 ms +3.6% -1.54% 23.38 ms +4.45% -3.51% -0.09%
wpTemplate 18.89 ms +5.35% -4.87% 18.41 ms +5% -2.5% 2.61%
wpTotal 43.05 ms +1.63% -4.6% 42.62 ms +2.42% -5.16% 1.01%
wpMemoryUsage 7.65 MB +0% -0% 7.61 MB +0% -0% 0.46%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric de2aa8e trunk % Change
timeToFirstByte 34.65 ms +4.76% -1.3% 38.75 ms +6.32% -4.13% -10.58%
largestContentfulPaint 80 ms +5% -0% 88 ms +4.55% -0% -9.09%
lcpMinusTtfb 45.8 ms +2.51% -0.98% 51 ms +2.75% -1.96% -10.2%
wpBeforeTemplate 21.03 ms +2.09% -1% 20.8 ms +5.82% -2.02% 1.11%
wpTemplate 10.78 ms +3.62% -0.93% 14.46 ms +4.63% -4.08% -25.45%
wpTotal 32.08 ms +4.8% -1.37% 35.67 ms +7.26% -3.92% -10.06%
wpMemoryUsage 6.23 MB +0% -0% 6.30 MB +0% -0% -1.19%
wpDbQueries 9 +0% -0% 13 +0% -0% -30.77%

media-processing

Metric de2aa8e trunk % Change
mediaProcessingJpeg 410.6 ms +0.9% -1.69% 407.73 ms +1.59% -0.32% 0.7%
mediaProcessingAvif 6295.29 ms +0.15% -0.08% 6279 ms +0.18% -0.14% 0.26%
mediaProcessingJpegToAvif 4319.64 ms +0.26% -0.06% 4316.28 ms +0.13% -0.13% 0.08%

media-upload

Metric de2aa8e trunk % Change
jpegUploadProcessing 1694.43 ms +15.91% -15.36% 1438.98 ms +0.33% -0.43% 17.75%
pngUploadProcessing 213.88 ms +10.23% -5.99% 204.89 ms +10.34% -2.03% 4.39%
largeJpegUploadProcessing 1436.27 ms +0.27% -0.74% 1440.19 ms +1.71% -0.87% -0.27%
multipleImageUploadProcessing 2049.87 ms +0.27% -7.82% 2052.11 ms +0.85% -1.67% -0.11%

post-editor

Metric de2aa8e trunk % Change
serverResponse 398.35 ms +6.37% -3.61% 407.79 ms +5.11% -5.81% -2.31%
firstPaint 439.98 ms +9.3% -40.06% 460.49 ms +4.01% -2.93% -4.45%
domContentLoaded 1058.73 ms +4.12% -1.65% 1054.46 ms +1.46% -1.48% 0.4%
loaded 1059.97 ms +4.1% -1.65% 1055.67 ms +1.46% -1.49% 0.41%
firstContentfulPaint 477.61 ms +4.52% -2.04% 463.77 ms +5.36% -0.94% 2.98%
firstBlock 3094.67 ms +1.79% -2.31% 3054.38 ms +1.03% -3.36% 1.32%
type 17.47 ms +5.5% -2.58% 17.48 ms +5.03% -0.4% -0.06%
typeWithoutInspector 17.88 ms +4.08% -1.06% 17.23 ms +1.86% -1.86% 3.77%
typeWithTopToolbar 25.13 ms +3.7% -5.61% 22.09 ms +7.15% -2.85% 13.76%
typeContainer 8.36 ms +10.17% -4.78% 8.75 ms +6.86% -8.23% -4.46%
focus 115.13 ms +9.84% -3.6% 119.06 ms +2.71% -5.48% -3.3%
firstFocus 213.73 ms +0% -0% 220.16 ms +0% -0% -2.92%
selectAll 488.46 ms +1.93% -2.15% 454.18 ms +1.64% -3.13% 7.55%
listViewOpen 79.46 ms +6.58% -7.09% 68.77 ms +17.04% -5.55% 15.54%
inserterOpen 39.88 ms +1.3% -9.63% 38.09 ms +10.5% -3.6% 4.7%
inserterHover 12.18 ms +5.42% -5.67% 12.13 ms +8.66% -5.36% 0.41%
inserterSearch 8.45 ms +11.24% -3.2% 8.47 ms +2.13% -2.36% -0.24%
loadPatterns 659.65 ms +1.07% -5.03% 636.11 ms +8.56% -6% 3.7%
wpTotal 388.66 ms +6.06% -3.84% 398.49 ms +4.69% -6.28% -2.47%
wpMemoryUsage 14.69 MB +0% -0% 14.65 MB +0% -0% 0.26%
wpDbQueries 55 +0% -1.82% 55 +0% -0% 0%

site-editor

Metric de2aa8e trunk % Change
serverResponse 506.2 ms +5.63% -3.45% 508.79 ms +3.07% -1.39% -0.51%
firstPaint 263.72 ms +14.12% -11.28% 275.7 ms +2.84% -4.37% -4.35%
domContentLoaded 1284.38 ms +1.44% -0.57% 1282.8 ms +2.3% -0.44% 0.12%
loaded 1285.46 ms +1.44% -0.55% 1283.93 ms +2.29% -0.45% 0.12%
firstContentfulPaint 516.87 ms +3.51% -3.65% 533.02 ms +1.22% -17.91% -3.03%
firstBlock 4806.11 ms +1.17% -1.16% 4814.32 ms +0.41% -0.31% -0.17%
type 18.74 ms +2.77% -3.15% 18.45 ms +10.84% -3.79% 1.57%
navigate 133.22 ms +9.2% -5.92% 120.49 ms +10.05% -0.53% 10.57%
loadPatterns 1338.17 ms +1.45% -3.9% 1275.98 ms +3.25% -1.74% 4.87%
loadPages 981.71 ms +6.79% -2.73% 1005.67 ms +3.72% -5.89% -2.38%
wpTotal 496.52 ms +5.85% -3.5% 499.16 ms +3.23% -1.38% -0.53%
wpMemoryUsage 12.70 MB +0% -0% 12.67 MB +0% -0% 0.29%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

bc6a069 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
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-21T12:57:08", "date_gmt": "2026-10-21T12:57:08", "description": {"rendered": "<p class=\"attachment\"><a href='http://localhost:8889/wp-content/uploads/2026/10/e79eeb6f-0559-44a2-8f28-4514a06dfce0.png'><img loading=\"lazy\" decoding=\"async\" width=\"10\" height=\"10\" src=\"http://localhost:8889/wp-content/uploads/2026/10/e79eeb6f-0559-44a2-8f28-4514a06dfce0.png\" class=\"attachment-medium size-medium\" alt=\"\" style=\"width:100%;height:100%;max-width:10px;\" /></a></p>
"}, "featured_media": 0, "filename": "e79eeb6f-0559-44a2-8f28-4514a06dfce0.png", "filesize": 80, "guid": {"rendered": "http://localhost:8889/wp-content/uploads/2026/10/e79eeb6f-0559-44a2-8f28-4514a06dfce0.png"}, "id": 223, "link": "http://localhost:8889/?attachment_id=223", "media_details": {"file": "2026/10/e79eeb6f-0559-44a2-8f28-4514a06dfce0.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-21T12:57:08", "modified_gmt": "2026-10-21T12:57:08", "ping_status": "closed", "post": 222, "slug": "e79eeb6f-0559-44a2-8f28-4514a06dfce0", "source_url": "http://localhost:8889/wp-content/uploads/2026/10/e79eeb6f-0559-44a2-8f28-4514a06dfce0.png", "status": "inherit", "template": "", "title": {"rendered": "e79eeb6f-0559-44a2-8f28-4514a06dfce0"}, "type": "attachment"}]
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/single-file-placeholder-drop.spec.js:71:45
restores the blocks when a multi-selection drag is canceled 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:871:3

bc6a069 Run

@aaronrobertshaw
aaronrobertshaw force-pushed the update/border-classes-and-styles-php-helper branch 2 times, most recently from 3b87a31 to 4fb89d6 Compare October 8, 2026 05:55
@aaronrobertshaw aaronrobertshaw added [Type] Code Quality Issues or PRs that relate to code quality and removed [Type] Enhancement A suggestion for improvement. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Oct 8, 2026
@aaronrobertshaw
aaronrobertshaw force-pushed the update/border-classes-and-styles-php-helper branch 2 times, most recently from 6d5fd2d to ce7e5c6 Compare October 13, 2026 04:40
@aaronrobertshaw
aaronrobertshaw force-pushed the update/border-classes-and-styles-php-helper branch 3 times, most recently from 54238c5 to ead2d72 Compare October 20, 2026 05:24
@aaronrobertshaw
aaronrobertshaw force-pushed the update/border-classes-and-styles-php-helper branch from b122008 to bc6a069 Compare October 21, 2026 12:41

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

1 participant