Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout: Add layout aware margin styles output for blocks in global styles #47399

Conversation

andrewserong
Copy link
Contributor

@andrewserong andrewserong commented Jan 25, 2023

What?

The idea in this PR is to add additional output for margin styles in themes that opt-in to blockGap, to introduce layout aware margin rules that are particular to the layout types. Since the existing flow and constrained layouts borrow their margin/spacing logic from the idea of the Stack layout as described in Every Layout book, the approach in this PR is inspired by the idea of exceptions, by outputting additional margin rules. Where the approach in this PR differs is that it uses direct values as output, rather than CSS variables.

So, in a block theme that opts-in to block gap, if a user or theme sets margin styles on the Group block, then this PR will output additional rules. Example output:

/* Standard margin output is still output so that blocks that appear outside of layout blocks still receive margin rules */
.wp-block-group {
  margin-top: 25px;
  margin-bottom: 50px;
}
/* Layout aware margin output, to override margins for the direct child of the layout type, if it matches the block's selector */
.is-layout-flow > .wp-block-group {
  margin-top:25px;
  margin-bottom:50px;
}'

Why?

As described in #43404, the existing layout rules currently override margin rules set at the block level in global styles. A previous attempt looked at trying to reduce the specificity of layout styles (#45927), however this approach did not result in the desired outcome. The specificity of layout styles was reduced, however it then resulted in the layout and margin rules having the same level of specificity (010), which meant that if the layout styles were output after the margin styles, the layout styles still won out.

So, the argument in this PR is that it would be better to be explicit about having block-level margin rules that intentionally have a higher specificity than layout rules, however lower specificity than layout rules set at the individual block level. The result is:

  • .is-layout-flow * + * (010) — base layout styles
  • .is-layout-flow > .wp-block-group (020) — layout aware margin styles output

How?

  • Add a marginSelector property to the layout definitions in theme.json.
  • In both the PHP and JS global styles output, check if block gap is supported by the theme and if margin is supported by the current block — if so, then output layout aware margin rules as above, using the marginSelector to join the layout classname with the block's classname.
  • Update tests to match.

Testing Instructions

  1. In the site editor, set some margins for blocks that support it (e.g. Cover or Heading blocks)
  2. Add blocks within group blocks and ensure margins are being output correctly
  3. Save and view the site frontend — margin rules should win out over base layout rules
  4. Back in the site editor (or post editor) set a block spacing value on an individual container block (e.g. Group) with a Cover block inside it — the block spacing value at the individual container block should override the margin rules for the Cover block from global styles
  5. Ensure all these styles are working correctly in the post editor
  6. (Regression testing) Double-check that the changes here do not unintentionally spill any gap or margin rules into themes that should not have theme (e.g. if block gap is set to null in theme.json or if running a Classic theme)

A question — do we also need to output these extra rules for the flex layout? I don't think so, since it uses gap rather than vertical margins, but it might be worth double checking.

Testing Instructions for Keyboard

Screenshots or screencast

Before (note that the Cover block's margin rules do not appear to apply) After (note that the Cover block's margin rules do apply
image image

@andrewserong andrewserong added [Type] Bug An existing feature does not function as intended Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Feature] Layout Layout block support, its UI controls, and style output. labels Jan 25, 2023
@andrewserong andrewserong self-assigned this Jan 25, 2023
@andrewserong
Copy link
Contributor Author

For visibility, since I know a few folks have taken an interest in fixing this issue, just thought I'd ping a few people: @tellthemachines @aaronrobertshaw @t-hamano

This appears to be working pretty well for me so far, but I've only just finished hacking it together so I might have very well missed edge cases, etc. I'll do any tidying up that might be needed and aim to switch this over to ready for review by the end of the week (I'm AFK tomorrow).

@github-actions
Copy link

github-actions bot commented Jan 25, 2023

Size Change: +20 kB (+2%)

Total Size: 1.33 MB

Filename Size Change
build/block-editor/index.min.js 194 kB +2.32 kB (+1%)
build/block-editor/style-rtl.css 14.4 kB +97 B (+1%)
build/block-editor/style.css 14.4 kB +99 B (+1%)
build/block-library/blocks/button/editor-rtl.css 587 B +102 B (+21%) 🚨
build/block-library/blocks/button/editor.css 587 B +102 B (+21%) 🚨
build/block-library/blocks/button/style-rtl.css 628 B +96 B (+18%) ⚠️
build/block-library/blocks/button/style.css 627 B +95 B (+18%) ⚠️
build/block-library/blocks/file/style-rtl.css 265 B +12 B (+5%) 🔍
build/block-library/blocks/file/style.css 265 B +11 B (+4%)
build/block-library/blocks/image/editor-rtl.css 830 B +1 B (0%)
build/block-library/blocks/image/editor.css 829 B +1 B (0%)
build/block-library/blocks/image/style-rtl.css 652 B +25 B (+4%)
build/block-library/blocks/image/style.css 652 B +22 B (+3%)
build/block-library/blocks/latest-comments/style-rtl.css 357 B +59 B (+20%) 🚨
build/block-library/blocks/latest-comments/style.css 357 B +59 B (+20%) 🚨
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B -2 B (-3%)
build/block-library/blocks/post-excerpt/editor.css 71 B -2 B (-3%)
build/block-library/blocks/query/editor-rtl.css 463 B +5 B (+1%)
build/block-library/blocks/query/editor.css 463 B +6 B (+1%)
build/block-library/blocks/quote/style-rtl.css 222 B +9 B (+4%)
build/block-library/blocks/quote/style.css 222 B +9 B (+4%)
build/block-library/classic-rtl.css 179 B +17 B (+10%) ⚠️
build/block-library/classic.css 179 B +17 B (+10%) ⚠️
build/block-library/editor-rtl.css 11.6 kB +121 B (+1%)
build/block-library/editor.css 11.6 kB +121 B (+1%)
build/block-library/index.min.js 200 kB +481 B (0%)
build/block-library/style-rtl.css 12.7 kB +168 B (+1%)
build/block-library/style.css 12.7 kB +167 B (+1%)
build/blocks/index.min.js 51 kB +611 B (+1%)
build/components/index.min.js 207 kB +3.78 kB (+2%)
build/components/style-rtl.css 11.7 kB +9 B (0%)
build/components/style.css 11.7 kB +11 B (0%)
build/compose/index.min.js 12.4 kB +25 B (0%)
build/core-data/index.min.js 16.2 kB +321 B (+2%)
build/customize-widgets/index.min.js 12.2 kB +372 B (+3%)
build/data/index.min.js 8.57 kB +507 B (+6%) 🔍
build/date/index.min.js 40.4 kB +8.38 kB (+26%) 🚨
build/edit-post/index.min.js 34.8 kB +346 B (+1%)
build/edit-post/style-rtl.css 7.53 kB +68 B (+1%)
build/edit-post/style.css 7.52 kB +68 B (+1%)
build/edit-site/index.min.js 65.2 kB +833 B (+1%)
build/edit-site/style-rtl.css 9.96 kB +312 B (+3%)
build/edit-site/style.css 9.95 kB +307 B (+3%)
build/edit-widgets/index.min.js 17.3 kB +399 B (+2%)
build/edit-widgets/style-rtl.css 4.55 kB +60 B (+1%)
build/edit-widgets/style.css 4.55 kB +59 B (+1%)
build/editor/index.min.js 45.7 kB +288 B (+1%)
build/editor/style-rtl.css 3.54 kB -38 B (-1%)
build/editor/style.css 3.53 kB -40 B (-1%)
build/element/index.min.js 4.95 kB +11 B (0%)
build/experiments/index.min.js 0 B -905 B (removed) 🏆
build/format-library/index.min.js 7.27 kB +34 B (0%)
build/format-library/style-rtl.css 557 B -41 B (-7%)
build/format-library/style.css 556 B -41 B (-7%)
build/keycodes/index.min.js 1.94 kB +64 B (+3%)
build/list-reusable-blocks/index.min.js 2.14 kB +3 B (0%)
build/rich-text/index.min.js 10.8 kB +8 B (0%)
build/style-engine/index.min.js 1.53 kB +3 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.78 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 483 B
build/block-directory/index.min.js 7.2 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.11 kB
build/block-editor/content.css 4.1 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 91 B
build/block-library/blocks/avatar/style.css 91 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/cover/style-rtl.css 1.57 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 984 B
build/block-library/blocks/gallery/editor.css 988 B
build/block-library/blocks/gallery/style-rtl.css 1.55 kB
build/block-library/blocks/gallery/style.css 1.55 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 716 B
build/block-library/blocks/navigation-link/editor.css 715 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB
build/block-library/blocks/navigation/editor.css 2.14 kB
build/block-library/blocks/navigation/style-rtl.css 2.22 kB
build/block-library/blocks/navigation/style.css 2.2 kB
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB
build/block-library/blocks/navigation/view.min.js 447 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 376 B
build/block-library/blocks/page-list/editor.css 376 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/style-rtl.css 134 B
build/block-library/blocks/post-excerpt/style.css 134 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-featured-image/style-rtl.css 318 B
build/block-library/blocks/post-featured-image/style.css 318 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 409 B
build/block-library/blocks/search/style.css 406 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 490 B
build/block-library/blocks/site-logo/editor.css 490 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 433 B
build/block-library/blocks/table/editor.css 433 B
build/block-library/blocks/table/style-rtl.css 651 B
build/block-library/blocks/table/style.css 650 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 404 B
build/block-library/blocks/template-part/editor.css 404 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 179 B
build/block-library/blocks/video/style.css 179 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/theme-rtl.css 698 B
build/block-library/theme.css 703 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/customize-widgets/style-rtl.css 1.41 kB
build/customize-widgets/style.css 1.41 kB
build/data-controls/index.min.js 663 B
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.71 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/escape-html/index.min.js 548 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.79 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.99 kB
build/notices/index.min.js 977 B
build/plugins/index.min.js 1.95 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.35 kB
build/primitives/index.min.js 960 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 940 B
build/react-i18n/index.min.js 702 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.75 kB
build/reusable-blocks/index.min.js 2.26 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/server-side-render/index.min.js 2.09 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 650 B
build/url/index.min.js 3.69 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 1.09 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.31 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

@t-hamano
Copy link
Contributor

@andrewserong

Thank you for your great work! I will try this PR within a couple of days, but this PR will also fundamentally solve #47059 👍

Copy link
Contributor

@tellthemachines tellthemachines left a comment

Choose a reason for hiding this comment

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

This is working as expected with both block and classic themes ✅

Mostly questions below, and a further bonus question 😅 : what should happen if Group block has a gap value set in Global Styles? Currently it's overriding the Global Styles-set margin of a child Heading block:

Screenshot 2023-01-27 at 12 05 56 pm

if ( ! block_has_support( $block_type, array( '__experimentalLayout' ), false ) ) {
if (
! block_has_support( $block_type, array( '__experimentalLayout' ), false ) &&
! block_has_support( $block_type, array( 'spacing', 'margin' ), false )
Copy link
Contributor

Choose a reason for hiding this comment

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

Trying to wrap my head around what this condition is doing - if layout is not supported, when does it matter whether margin is supported or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see the confusion here, I should add a comment to clarify.

This check is about what the current block supports rather than what the theme supports, so to support layout aware margins for blocks without layout support (e.g. heading, paragraph, image) we need to allow it to pass at this point. The check is primarily an early return so that for blocks that we know don't need any handling, we don't need to do any further lookups to theme settings, etc. Previously, that was just blocks that didn't support layout, but we now need the check to be layout + margin.

Further down in the function, we check $has_block_gap_support (that is, the theme has block gap support) before outputting the layout aware margin rules.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it, thanks for clarifying!

lib/theme.json Outdated
@@ -246,7 +246,8 @@
"margin-block-end": "0"
}
}
]
],
"marginSelector": " > "
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the benefit of declaring the selector here is having a single source of truth between editor and front end code. If this becomes unnecessary though (say we find a better solution with cascade layers) how easily can we remove it?

Copy link
Contributor Author

@andrewserong andrewserong Jan 27, 2023

Choose a reason for hiding this comment

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

Yeah, the benefit was to try to keep the selector in one place. It should be easy enough to remove from theme.json since it's an undocumented part of the layout definitions object, which isn't intended to be overridden by themes. I think we'd just need to land the changes to the PHP / JS code that uses a different approach first, and then as a final step, remove this property in a follow-up.

That said, if it seems like something we'd likely want to change in the shorter-term, I suppose we could hard-code it for now. But in general I kind of like the idea of trying to keep the definitions in one place where possible, for clarity... but that may or may not be all that valuable 🤔

@andrewserong
Copy link
Contributor Author

Thanks for taking this for a spin @tellthemachines!

Mostly questions below, and a further bonus question 😅 : what should happen if Group block has a gap value set in Global Styles? Currently it's overriding the Global Styles-set margin of a child Heading block:

Oh, that's a great question. I think I might need to ping a designer for ideal feedback on this one, as it's a bit more of a UX / user expectations concern and I could see the decision going either way.

@jasmussen / @WordPress/gutenberg-design — if anyone has input here on the expected behaviour here, we'd love some feedback. To recap:

  • This PR proposes to fix an issue with margin set at the block level in global styles by outputting layout-aware margin styles. That is, if a margin is set at the block level in global styles, additional layout rules are output so that those margins can override global gap values.
  • The question is: if the Heading block has a margin set in global styles, and the Group block sets a block spacing value in global styles — which rule should win out? Should the Group block's spacing value override the margin set for the Heading, or should the Heading's margin style still win out over the Group block's block spacing value? Currently the Group block's spacing value wins out.

@andrewserong andrewserong marked this pull request as ready for review January 27, 2023 05:38
@andrewserong
Copy link
Contributor Author

Update: I've pushed a small change (72d0afe) to ensure that children of the root .wp-site-blocks class are also handled, as the root layout rules don't use the normal layout classnames (yet, at least). This means that the logic here should also apply to any blocks set at the root level in the site editor (i.e. not wrapped in a Group block or other container).

I've switched this over to ready for review now — I think it's mostly working aside from figuring out which should win between block-level block spacing in global styles and block-level margin in global styles. I'll see if I have any fresh ideas after the weekend and continue on with this PR on Monday 🤔 — very happy for feedback on whether folks think it's a blocker, or if there's a clever further tweak we can make to the output rules.

@github-actions
Copy link

github-actions bot commented Jan 27, 2023

Flaky tests detected in 1fa9c3b.
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.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4249382021
📝 Reported issues:

@jasmussen
Copy link
Contributor

The question is: if the Heading block has a margin set in global styles, and the Group block sets a block spacing value in global styles — which rule should win out? Should the Group block's spacing value override the margin set for the Heading, or should the Heading's margin style still win out over the Group block's block spacing value? Currently the Group block's spacing value wins out.

Very tricky to parse the nuance here, thanks for trying to summarize, but forgive me if I'm still missing a beat.

My initial instinct was that the ancestor wins, and child loses, mostly on CSS principle. But for this to work the rules of the ancestor should be intentionally added by a user.

I.e.:

  • I have global margin rules that affect the Heading block
  • I wrap the Heading block in a group, and it looks identical
  • I change margin rules on the heading block, and now they override/propogate

Is that a correct use case and would it work this way? Pros/cons to this approach?

@t-hamano
Copy link
Contributor

What I have noticed is that when margin is set at the block level, the top margin of the first block in the container and the bottom margin of the last block in the container take precedence.

My feeling is that these two margin styles should not apply.

block

For example, how about applying only the margin-top to the second and subsequent blocks in a container, as shown below?

/* From */
.is-layout-constrained > .wp-block-heading {
	margin-top: 50px;
	margin-bottom: 50px;
}

/* To */
.is-layout-constrained > * + .wp-block-heading {
	margin-top: 50px;
}

@andrewserong
Copy link
Contributor Author

Thanks for the feedback, folks!

Is that a correct use case and would it work this way? Pros/cons to this approach?

@jasmussen I think you're getting it there — the trick is that by wrapping the heading block in a group block, the group block's block spacing value (if set in global styles) will unfortunately override the heading's global styles margin value. I'm not sure if we have (yet) a good way of figuring out how to apply that, so I'm still trying to think about how we might fix it 🤔

Also, apologies, it is a difficult issue to describe, thank you for taking the time to look at this!

For example, how about applying only the margin-top to the second and subsequent blocks in a container, as shown below?

@t-hamano thanks for the feedback, there — I was a little on the fence about whether to only apply margin-top. If the theme has defined both margin-top and margin-bottom wouldn't they expect both rules to be applied? For margin-top, they could set it to only be the top margin in global styles if they wanted to, so I was wondering if it might be unexpected from the user perspective if only margin-top is applied, or if they could only see the margin applied if the block was not the first block in the list... 🤔

@jasmussen
Copy link
Contributor

the group block's block spacing value (if set in global styles) will unfortunately override the heading's global styles margin value.

Oh it does this by default and even without any margin/spacing customization? Yes tricky indeed.

@tellthemachines
Copy link
Contributor

the group block's block spacing value (if set in global styles) will unfortunately override the heading's global styles margin value.

Oh it does this by default and even without any margin/spacing customization? Yes tricky indeed.

Not entirely by default; a value has to be set for the Group block spacing in Global Styles. So it's one Global Styles customisation overriding another.

I'm ok with landing this as-is, because the benefit of having margins working for all blocks inside layout containers is already huge, and we can fine-tune some of the detail later. @andrewserong is there anything else you feel needs improving here? Otherwise I'm happy to give it a final check.

@andrewserong
Copy link
Contributor Author

I'm ok with landing this as-is, because the benefit of having margins working for all blocks inside layout containers is already huge, and we can fine-tune some of the detail later.

I agree, thanks @tellthemachines — from my perspective, the change in this PR is probably desirable in that it isn't making too many assumptions about how the layout rules should be applied, it's mostly dealing with the priority issue. Since it's potentially contentious as to whether or not the styling rules here are the right way to go (@t-hamano has some very valid feedback about potentially different rules), I'd be keen to make sure that there's a bit more visibility on the approach here, so I'll add a few more reviewers / pings in case there are other folks who might have an opinion on it. CC: @WordPress/gutenberg-core

@carolinan
Copy link
Contributor

Is this intended to only work in block themes?

@andrewserong
Copy link
Contributor Author

Is this intended to only work in block themes?

Yes, since it's only for sites that opt in to blockGap and set margin rules at the block level in global styles.

@aaronrobertshaw
Copy link
Contributor

Thanks for all the hard work on solving the layout vs margin styles issue @andrewserong 🙇

I've taken this PR for a quick spin but I'm seeing differences between the post editor and the frontend.

Steps to replicate:

  1. Set a margin on the Cover block via Global Styles
  2. Set a block gap on the Group block via Global Styles
  3. In the Post Editor, add a Group block with an inner Cover block followed by a paragraph
  4. Save the post and notice that the editor and frontend don’t match
  5. Back in the editor switch between the different Group block variations, saving and checking the frontend for each. The frontend is different to the editor each time.

This is what I'm seeing:

Screen.Recording.2023-02-01.at.10.41.23.am.mp4

@carolinan
Copy link
Contributor

carolinan commented Feb 1, 2023

Please know that in 6.2, classic themes are already able to opt-in to appearance tools, including block gap.
It is already merged.
It was punted in 6.1 and requested to be commited earlier in 6.2 to allow time to test it.

I have already suggested that we may need to revert it and update the theme support without including block gap, but if we need to do that, an early decision is better.
https://core.trac.wordpress.org/ticket/57460

@andrewserong
Copy link
Contributor Author

Thanks for digging in @aaronrobertshaw and @t-hamano, much appreciated!

I'm seeing differences between the post editor and the frontend.

I'll have a play around as to why it's looking different, I wonder if the margin collapse of the subtle difference in styling in the block editor has anything to do with it... this is potentially related to:

I think this behavior gives an unintended impression to many users, how do you feel about it?

Ah, our good friend margin collapse! 😅
Yeah, that looks very unexpected from a user perspective, and makes for a good argument for trying to target everything inside the layout container without breaking out from it. I'll have more of a play around with the rules over the next couple of days. Since this PR is a bug fix, hopefully we'll still have enough time to experiment a little to settle on a good balance between honouring the settings in global styles, and providing a consistent enough output in the editor and on the site front end 🤞

@andrewserong
Copy link
Contributor Author

Alrighty, I haven't tested it much, and it'll still need filtering for margin-top if we want to restrict it to just that property, but I've pushed an update (c3b19ed) that uses the > * + selector that @t-hamano suggested, so we can have a play with that. I'll continue on with this tomorrow!

@andrewserong andrewserong force-pushed the add/layout-aware-margin-styles-for-block-level-global-styles branch from c3b19ed to 3604c0f Compare February 3, 2023 06:06
@andrewserong
Copy link
Contributor Author

Quick update: I haven't forgotten about this one, and I'll continue chipping away at it next week. I'm still noticing some odd differences between the site editor and the site frontend that I suspect could be partly to do with how the global styles get processed and output, rather than only being to do with the rule we're generating. Mostly I'm trying to diagnose that a cover block as first child of a group block, with top margins set in global styles, results in the cover block's margin winning in the site editor, but not on the site frontend.

Site editor Site frontend
image image

Inspecting the generated rules, the selector generated is body .is-layout-constrained > * which matches the site frontend, but the actual rule has the body prefix replaced by .editor-styles-wrapper . And at the same time, the normal margin rules output also has .editor-styles-wrapper prefixed to it, so these two rules wind up with the same specificity (I think?) in the site editor, whereas they have different specificity on the site frontend due to the lack of the .editor-styles-wrapper prefix on the site frontend. Here's a screenshot of the rules in the site editor:

image

So, it looks like the output in the site editor will need to be tweaked slightly, I think... I'm not too sure which direction it needs to be tweaked just yet, but I'll continue to play around with this next week. Also, for anyone reading this, don't worry if my comments here don't make any sense! As it's the end of my week, I mostly wanted to jot down my thoughts while they were fresh in my mind, so I know where to pick up again next week 🙂

@jasmussen
Copy link
Contributor

I'm not entirely sure if the following is useful to the conversation. But I wanted to nevertheless surface this codepen. Essentially what it does is use margin-inline instead of margin to center and position the main column, which allows us to use margins, including negative margins, on a per-block basis inside. Relevant?

@andrewserong
Copy link
Contributor Author

Relevant?

Not quite since we're not really looking at the block-level margin output in that kind of way (thank you for sharing, though, always great to see some practical examples in working code!). But it has spurred a thought that we could potentially expand the margin styles output here to also include rules for the first and last items, to parallel the block spacing rules. I'll have a play with that tomorrow to see if that helps the reliability of the output. 🤔

@andrewserong
Copy link
Contributor Author

andrewserong commented Feb 7, 2023

Update: I've had a go at another approach that adds some extra complexity, but appears to help introduce better parity between the site editor and the site frontend. I'm not sure if I'm sold on the approach, but I think the exploration was worth it, at least! I'll recap the ideas explored in b536418:

  • Add marginStyles array as a parallel to spacingStyles that includes rules for the first, last, and in-between blocks of the layout type.
  • As with spacingStyles if the rule in the array is a real value, output it directly. If it is set to null then look-up the provided value and output that instead (in this case, look up the corresponding margin value, if set in global styles)
  • The result is that the layout aware margin rules affect margin rules that are within the layout container, but don't extend beyond the top or bottom of the container — there's still the chance that folks will think that the margin rules aren't working, but it seems to get things to play more nicely with the concepts of the layout rules, and hopefully gets us closer to the ideal that @t-hamano mentioned earlier (Layout: Add layout aware margin styles output for blocks in global styles #47399 (comment))

The styles that get output now look like the following (assuming a Group block set to margin top of 25px and margin bottom of 50px):

.is-layout-flow > .wp-block-group { // First block sets top margin to 0, pass in real value for bottom margin.
    margin-block-start: 0;
    margin-bottom: 50px;
}
.is-layout-flow > * + .wp-block-group { // In-between blocks get to output real values for both top and bottom.
    margin-top: 25px;
    margin-bottom: 50px;
}
.is-layout-flow > *:last-child.wp-block-group { // Last block sets bottom margin to 0, pass in real value for top margin.
    margin-top: 25px;
    margin-block-end: 0;
}
.wp-site-blocks > * + .wp-block-group { // Root blocks rules (might also need the above logic)
    margin-top:25px;
    margin-bottom:50px;
}

From playing with this locally, it looks like we can now get close to parity between the site editor and site frontend:

image

Notes / caveats:

  • It looks like theme.css rules are being applied in the site editor and not the site frontend for TT3 theme, so in the screenshot above, I've switched off the padding rules for .wp-block-group.has-background as the inconsistency of those rules is beyond the scope of this issue/PR
  • If this looks viable, I'll need to replicate the logic for root blocks (children of .wp-site-blocks) to implement something similar, most likely 🤔

Very happy for any feedback on this approach, and whether or not this approach is overly complicating things. I'm cautiously optimistic that it's something that gets it working, but what I'm not sure about is whether it's worth the extra complexity. If so, I'll look into seeing if we can simplify the code a bit / consolidate things where possible.

@t-hamano
Copy link
Contributor

t-hamano commented Feb 7, 2023

Thank you for your great initiative, @andrewserong! 🎉

I used the following data and confirmed that it is working exactly as expected:

theme.json
{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"settings": {
		"appearanceTools": true,
		"layout": {
			"contentSize": "840px",
			"wideSize": "1100px"
		}
	},
	"styles": {
		"blocks": {
			"core/paragraph": {
				"spacing": {
					"margin": {
						"top": "1.8em"
					}
				}
			},
			"core/heading": {
				"spacing": {
					"margin": {
						"top": "30px",
						"bottom": "29px"
					}
				}
			}
		},
		"elements": {
			"h2": {
				"spacing": {
					"margin": {
						"top": "40px",
						"bottom": "39px"
					}
				}
			}
		}
	}
}
Simgle page markup
<!-- wp:paragraph -->
<p>Root Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Root Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Root Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Root Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Root Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Root Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Root Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Group &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Group &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Group &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>Group &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Group &gt; Group &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Group &gt; Group &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Group &gt; Group &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:cover {"customOverlayColor":"#d9d4d4","isDark":false} -->
<div class="wp-block-cover is-light"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#d9d4d4"></span><div class="wp-block-cover__inner-container"><!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Group &gt; Cover &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Cover &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Group &gt; Cover &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Cover &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Group &gt; Cover &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Group &gt; Cover &gt; Paragraph</p>
<!-- /wp:paragraph --></div></div>
<!-- /wp:cover --></div>
<!-- /wp:group --></div>
<!-- /wp:group -->

<!-- wp:group {"layout":{"type":"flex","flexWrap":"nowrap"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>Row &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Row &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Row &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Row &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Row &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Row &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Row &gt; Paragraph</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

<!-- wp:group {"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>Stack &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Stack &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Stack &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Stack &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Stack &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Stack &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Stack &gt; Paragraph</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

<!-- wp:cover {"customOverlayColor":"#d9d4d4","isDark":false} -->
<div class="wp-block-cover is-light"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim" style="background-color:#d9d4d4"></span><div class="wp-block-cover__inner-container"><!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Cover &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Cover &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Cover &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:paragraph -->
<p>Cover &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Cover &gt; Group &gt; Heading H1</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Cover &gt; Group &gt; Heading H2</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Cover &gt; Group &gt; Heading H3</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cover &gt; Group &gt; Paragraph</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div></div>
<!-- /wp:cover -->
Screenshot

screenshot

These margin rules don't apply to blocks within a cover block, but I think they are not covered by this PR and are expected behavior for now.

One thing I noticed is that the element-level margins are not applied:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"styles": {
		"elements": {
			"h2": {
				"spacing": {
					"margin": {
						"top": "40px",
						"bottom": "39px"
					}
				}
			}
		}
	}
}

What do you think about element-level margins?

Copy link
Contributor

@tellthemachines tellthemachines left a comment

Choose a reason for hiding this comment

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

Thanks for persisting with this! It's a tough problem to get right.

Block margins inside blocks with layout are now working well with default gap values ✅ but there's still a difference between editor and front end when Group has a block spacing value set in global styles:

Editor:

Screenshot 2023-02-08 at 2 53 20 pm

Front end:

Screenshot 2023-02-08 at 2 53 50 pm

This seems to be due to the order in which core block styles are output, because rule specificity is the same in both cases.

Did we reach a decision on which style should take precedence in this case? (I feel it should be the child block's style as that would be more consistent with the behaviour we're trying for in this PR.) In any case, I wonder if it would be possible to fiddle with specificity a bit further so we're not dependent on order of output?

One thing I don't love is the amount of extra CSS this change adds, especially because it gets added to all blocks that set margins, regardless of if they will ever be inside a layout-enabled block or not. For instance, I'm seeing these styles output for the Comments Title block, that can only ever exist inside a Comments block, which doesn't have layout.

There's sufficient repetition in styles that it shouldn't be too much of a performance hit when gzipped but it's still not optimal. I'm afraid don't have any better ideas at the moment 😅 but it may be worth thinking on this a bit further.

@andrewserong
Copy link
Contributor Author

andrewserong commented Feb 8, 2023

Thanks for reviewing and testing @t-hamano and @tellthemachines!

There's sufficient repetition in styles that it shouldn't be too much of a performance hit when gzipped but it's still not optimal. I'm afraid don't have any better ideas at the moment 😅 but it may be worth thinking on this a bit further.

The excessive CSS rules are my main concern here, too, but I haven't been able to think of a stable alternative. Very happy to pursue any ideas that folks have, though!

Since it's proving to be a tricky issue to fix, my main objective right now is to follow the question, "What code changes (however inefficient and verbose) get us to a working state?". The hope is that if we can get it technically working, the path toward optimising the output might then become a littler clearer 🤞

With that in mind and based on the helpful feedback here, I'll next explore the following:

  • Look into replicating the logic for root blocks (children of .wp-site-blocks)
  • See if it's possible to include elements styling in the supported rules
  • Look into updating rules specificity to attempt to address the situation where Group has a block spacing value set in global styles (at the very least, create parity between the site editor and site frontend)
  • See where it's possible to consolidate logic and / or rules

@tellthemachines
Copy link
Contributor

Since it's proving to be a tricky issue to fix, my main objective right now is to follow the question, "What code changes (however inefficient and verbose) get us to a working state?". The hope is that if we can get it technically working, the path toward optimising the output might then become a littler clearer 🤞

Sounds sensible! If nothing else, this work is allowing us to clarify what the desired state of things actually is.

@andrewserong
Copy link
Contributor Author

Just dusting this one off a little to continue playing with consolidating some of the PHP logic. I imagine we might wind up going with something like #47858 in the end, but thought it still worthwhile to see where the ideas in this PR might lead. I'll continue on with this tomorrow.

@andrewserong
Copy link
Contributor Author

I'll close out this PR as #47858 in now approved and will be a cleaner and simpler fix for #43404.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Layout Layout block support, its UI controls, and style output. Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] Bug An existing feature does not function as intended
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

6 participants