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

Theme JSON: use block global style for block gap where no gap value exists in layout.php #39870

Closed

Conversation

ramonjd
Copy link
Member

@ramonjd ramonjd commented Mar 30, 2022

What?

Use block global style value (not the root) for block gap where no gap value exists.

Resolves #39789

Why?

In #37360 we removed blockGap from the block and elements arrays in $theme_json.

The side-effect was that block gap values in global styles for blocks such as the Group block were neither saved in the editor or appear in global styles the frontend.

Because we were removing block gap global styles from the theme json tree it meant that we could never compile the styles and output them to the frontend.

As a temporary measure we've removed the block gap control UI from dimensions panel in #39845.

This PR reinstates it.

How?

  • Only skips top-level style properties when compiling the styles. The block/element-level block gap values are not unset from the theme json tree.
  • In layout.php, if there is no block-level value for blockGap, but a global styles value available for blockGap, use the latter.
  • Reinstate the block gap control UI removed in Revert "Global styles: remove block gap control" #39845

See:

Testing Instruction

In the Site Editor, edit the global block gap value of a block that supports it, e.g., Group.

Check the editor and frontend to ensure the changes are visible.

Ensure that no top level styles are overwritten, that is, any global block gap styles (--wp--style--block-gap) set at the root level in the body tag should persist.

s
2022-03-30 14 15 30

// Some styles such as blockGap are only meant to be available at the top level (ROOT_BLOCK_SELECTOR),
// hence we only output styles at the top level.
if ( 'top' === _wp_array_get( self::VALID_STYLES, array( $value_path[0], $value_path[1] ), null ) && static::ROOT_BLOCK_SELECTOR !== $selector ) {
continue;
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm suspect of this. It seems fragile, only in the sense that I'm not aware of any side-effects.

Needs lots of testing.

@ramonjd ramonjd requested a review from andrewserong March 30, 2022 03:46
@ramonjd ramonjd added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Mar 30, 2022
@github-actions
Copy link

github-actions bot commented Mar 30, 2022

Size Change: +44 B (0%)

Total Size: 1.24 MB

Filename Size Change
build/block-editor/index.min.js 150 kB +6 B (0%)
build/block-library/index.min.js 180 kB +8 B (0%)
build/components/style-rtl.css 15 kB +8 B (0%)
build/components/style.css 15.1 kB +7 B (0%)
build/edit-navigation/style-rtl.css 4.05 kB +2 B (0%)
build/edit-navigation/style.css 4.06 kB +2 B (0%)
build/edit-post/style-rtl.css 7.09 kB +5 B (0%)
build/edit-post/style.css 7.09 kB +6 B (0%)
build/edit-site/index.min.js 47.6 kB -5 B (0%)
build/edit-site/style-rtl.css 7.97 kB +1 B (0%)
build/edit-widgets/style-rtl.css 4.41 kB +2 B (0%)
build/edit-widgets/style.css 4.41 kB +2 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.51 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/style-rtl.css 14.9 kB
build/block-editor/style.css 14.9 kB
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 65 B
build/block-library/blocks/archives/style.css 65 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 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 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 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 445 B
build/block-library/blocks/button/editor.css 445 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 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 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 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 127 B
build/block-library/blocks/comment-template/style.css 127 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 95 B
build/block-library/blocks/comments/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.53 kB
build/block-library/blocks/cover/style.css 1.53 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 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 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/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 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 961 B
build/block-library/blocks/gallery/editor.css 964 B
build/block-library/blocks/gallery/style-rtl.css 1.51 kB
build/block-library/blocks/gallery/style.css 1.51 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 333 B
build/block-library/blocks/group/editor.css 333 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/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 529 B
build/block-library/blocks/image/style.css 535 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 463 B
build/block-library/blocks/latest-posts/style.css 462 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 493 B
build/block-library/blocks/media-text/style.css 490 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 708 B
build/block-library/blocks/navigation-link/editor.css 706 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-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.95 kB
build/block-library/blocks/navigation/style.css 1.94 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 395 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 363 B
build/block-library/blocks/page-list/editor.css 363 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 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 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 69 B
build/block-library/blocks/post-comments-form/editor.css 69 B
build/block-library/blocks/post-comments-form/style-rtl.css 495 B
build/block-library/blocks/post-comments-form/style.css 495 B
build/block-library/blocks/post-comments/editor-rtl.css 77 B
build/block-library/blocks/post-comments/editor.css 77 B
build/block-library/blocks/post-comments/style-rtl.css 628 B
build/block-library/blocks/post-comments/style.css 628 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/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 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 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 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 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 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 369 B
build/block-library/blocks/query/editor.css 369 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 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 202 B
build/block-library/blocks/rss/editor.css 204 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 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 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 233 B
build/block-library/blocks/separator/style.css 233 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 759 B
build/block-library/blocks/site-logo/editor.css 759 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 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 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 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.37 kB
build/block-library/blocks/social-links/style.css 1.36 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 504 B
build/block-library/blocks/table/editor.css 504 B
build/block-library/blocks/table/style-rtl.css 625 B
build/block-library/blocks/table/style.css 625 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 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 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 993 B
build/block-library/common.css 990 B
build/block-library/editor-rtl.css 10.3 kB
build/block-library/editor.css 10.3 kB
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/style-rtl.css 11.5 kB
build/block-library/style.css 11.6 kB
build/block-library/theme-rtl.css 689 B
build/block-library/theme.css 694 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 47 kB
build/components/index.min.js 227 kB
build/compose/index.min.js 11.7 kB
build/core-data/index.min.js 14.6 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.39 kB
build/customize-widgets/style.css 1.39 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 7.98 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.69 kB
build/edit-navigation/index.min.js 16 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 30.4 kB
build/edit-site/style.css 7.95 kB
build/edit-widgets/index.min.js 16.4 kB
build/editor/index.min.js 38.4 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.3 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 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.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.1 kB
build/nux/style-rtl.css 751 B
build/nux/style.css 749 B
build/plugins/index.min.js 1.98 kB
build/preferences-persistence/index.min.js 2.23 kB
build/preferences/index.min.js 1.32 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 628 B
build/react-i18n/index.min.js 704 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.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.2 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.99 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.21 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@ramonjd
Copy link
Member Author

ramonjd commented Mar 30, 2022

I know the tests are failing. This PR is just to test out an idea from #39789

Copy link
Contributor

@andrewserong andrewserong 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 awesome, thanks for picking this one up @ramonjd 🙇 — I haven't test it yet, but just added a quick drive-by comment about where we do the checking for the block-level value from global styles.

Looks like a good direction to go in to me, and happy to give it a more detailed test / look on Monday if no-one beats me to it!

lib/block-supports/layout.php Outdated Show resolved Hide resolved
@ramonjd ramonjd force-pushed the try/global-styles-skip-block-gap-style-generation branch from 7f7d330 to f0344ff Compare March 31, 2022 01:14
@ramonjd ramonjd changed the title [TRY] Add support for gap set at the block level in theme.json and global styles Theme JSON: use block global style for block gap where no gap value exists in layout.php Mar 31, 2022
@ramonjd ramonjd requested a review from youknowriad March 31, 2022 02:42
@ramonjd ramonjd self-assigned this Mar 31, 2022
@ramonjd ramonjd added CSS Styling Related to editor and front end styles, CSS-specific issues. [Type] Bug An existing feature does not function as intended labels Mar 31, 2022
@ramonjd ramonjd marked this pull request as ready for review March 31, 2022 02:42
// If there is no block-level value for blockGap,
// but a global styles value available for blockGap,
// use the latter.
if ( empty( $gap_value ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed? isn't the fallback supposed to happen using the CSS variable?

Copy link
Contributor

Choose a reason for hiding this comment

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

(And we can only set the CSS variable at the global level theme.json)

Copy link
Member Author

Choose a reason for hiding this comment

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

Why is this needed?

Good question.

Logically it's not.

I only put it there so we could skip over trying to fetch the global value via gutenberg_get_global_styles if a gap value set in the block's local styles attribute is found, which would take precedence anyway.

isn't the fallback supposed to happen using the CSS variable?

It will either way, unless I'm missing something, which could be the case 😇

My thinking went along of these lines: if the block's local styles attribute does not contain a gap value, we'll try the block's global styles.

Either could still be null by the time we call gutenberg_get_layout_style() in which case the fallback would be --wp--style--block-gap, which is set at the root.

Does that sound right?

Copy link
Contributor

Choose a reason for hiding this comment

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

It does feel like duplication to me, since if the first one is null, the fallback will be the CSS variable (which corresponds to the root value).

Or in other words, if we do the fallback in php, why do we have the CSS variable in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

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

It does feel like duplication to me, since if the first one is null, the fallback will be the CSS variable (which corresponds to the root value).

Thanks for clarifying.

Just so I understand your concerns, are you seeing somewhere where the root block gap value, as opposed to the block-level global style value, is returned from

$spacing_global_styles = gutenberg_get_global_styles( array( 'blocks', $block['blockName'], 'spacing' ) );

on this line?

If so, yes, that would be a mistake.

The intention of this PR is to get gap working for block-level global styles by:

  1. filtering out block-level global styles for blockGap, but NOT the root, in the style sheet. See this line
  2. using the block-level global styles value, which still exists in the theme json tree, as a fallback ONLY IF the block attributes do not contain a style.spacing.blockGap value. If the former doesn't exist, we'll use the root value.

The effect of point 1 is that a user sets the value of, say, the Group block's gap in global styles, .wp-block-group { --wp--style--block-gap: '{someCustomValue}px} won't be rendered:

<style id='global-styles-inline-css'>
    body {
            /* this will still be here! */
	    --wp--style--block-gap: 1.5rem;
    }
    /* block-level global styles rules will not be printed */
</style>

The consequence of point 2 – at least what I'm attempting - is that if a user has set the value of Group block's gap in global styles it will be used when an individual block's attributes do not contain a style.spacing.blockGap value.

So the priority should still be:

  • try to use block attributes first
  • then the block's global styles second
  • finally the root value

If things aren't working that way in this PR it means I've done something wrong! 😬

Copy link
Member Author

Choose a reason for hiding this comment

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

You raise good points, thanks for clarifying.

This basically changes how the "style engine" of layout works, instead of being styleObject => CSS, it's now ( styleObject, theme.json ) => CSS. It changes the mental model and will have an impact on the style engine work.

Yeah, I see what you mean. We might run into trouble if we mix block support style attributes with global styles.

we're planning to add "theme.json" like support to each block (containers)

I wasn't aware of Style Partials (theme.json) so I agree that a change like the one in this PR might come back to bite us. 👍

I was having a discussion with @tellthemachines about something similar over at Try using variable for root padding value #39926

I was wondering about an alternative: a const VALID_TOP_LEVEL_STYLES (or whatever) in WP_Theme_JSON_Gutenberg that explicitly defines unique, root-level-only CSS vars.

body {
    --wp--root--style--block-gap: 2px;
    --wp--root--style--padding: 10px;
     /* etc ... */
}

I haven't really thought this through, but I was venturing towards checking VALID_TOP_LEVEL_STYLES when we assemble the styles in compute_style_properties and appending --wp--root-style-- for ROOT_BLOCK_SELECTOR styles.

Or there might be a tricky way to assemble them in sanitize() via $schema['styles'], $schema['styles']['elements'] and $schema['styles']['blocks'].

Uniquely identifying global CSS vars has a benefit, aside from explicitly stating their purpose, in that their values can be used for top-level layout calculation.

For example, in #39926, full-width blocks can use a root padding CSS var set a negative margins so that they stretch to the "full-width" of the screen.

Ultimately, we need to know how to treat blockGap when it is a root or a block/element style value and output something different accordingly.

I can chat about it with @andrewserong and see what we can cook up.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great questions.

This basically changes how the "style engine" of layout works, instead of being styleObject => CSS, it's now ( styleObject, theme.json ) => CSS. It changes the mental model and will have an impact on the style engine work.

Totally, I think it reveals some pragmatic challenges surrounding how we output styles, particularly for the layout support, which as @ramonjd mentions further down, is a little different to the other block supports.

In the case of this PR (and the current implementation of the layout support), everything happens at the individual block level when it's rendered, so out of necessity, to factor in global styles, we've kinda got to "look up" to the parents in order to deal with those values (or use CSS variables to stand-in for it).

In an ideal circumstance, with the style engine, how differently might we be doing things? The model for the style engine is a lot clearer for supports like padding, margin, typography, etc, where we'd like to consolidate the approach at the individual block level and global styles, and using a block's classname is an appropriate hook for it. In some of the explorations (like #39374) it looks like we'll be able to move more to global styles, but the unique block gap values was still a bit of mystery to me as to how best to handle it, and neatly declare values that get passed down / or cascade down correctly.

With block gap, because the value is used directly in different circumstances (rendering flow vs flex gap), it does create this additional challenge. I think because the use case is so different to each of the other block supports, I'm wondering if the approach in this PR would be an acceptable way to unblock getting the global styles support in, and if we could treat it as an implementation detail we could potentially swap out if and when partials in #39281 is explored.

From my perspective, it could be worthwhile proceeding with this change, so long as:

  • We're happy that folks will set blockGap values at the block level within theme.json and via the global styles interface in the site editor.
  • So long as we're happy with the shape of the data as it's stored, then theoretically, we could change the implementation after the fact, once we have a clearer idea of how we'd like to handle outputting the layout styles in the style engine.

From some of the explorations we've looked at recently, given that a fair bit of the logic winds up being moved to the Theme JSON class anyway, I don't think that the current change here would preclude further work, but very happy to be proved wrong, as I definitely don't want to nudge us into a decision that's difficult to reverse!

Copy link
Contributor

Choose a reason for hiding this comment

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

With block gap, because the value is used directly in different circumstances (rendering flow vs flex gap), it does create this additional challenge.

One alternative could be to keep the current logic (selectors specific styles but output something like):

.selector.is-layout-flex {
   gap: something;
}

.selector.is-layout-default > * {
   margin-top: something;
}

To be honest, I didn't think much about this, it's just a random idea for now, but it's an alternative that allows us to avoid that dependency to parent global style.

From some of the explorations we've looked at recently, given that a fair bit of the logic winds up being moved to the Theme JSON class anyway, I don't think that the current change here would preclude further work, but very happy to be proved wrong

I don't know 🤷 to be honest, personally I don't have a full confidence here but I trust your judgement.

Copy link
Contributor

Choose a reason for hiding this comment

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

One alternative could be to keep the current logic (selectors specific styles but output something like):

I really like that approach — I'd like it if we can output something like that in the longer term. I might be overthinking it, but I think that approach slightly opens up the can-of-worms surrounding rendering out semantic classnames, which we're in more of the proposal / exploratory phase of (since we'd need to adjust the logic for how the theme JSON class outputs styles, and then the layout support to inject the classnames).

I don't know 🤷 to be honest, personally I don't have a full confidence here but I trust your judgement.

Thank you, much appreciated! Since I was one of the folks to propose the idea of looking up global styles, I think I'd feel more comfortable with getting a couple more opinions if you're not totally sold on the idea, to confidence check before proceeding. I think my main interest is to see how viable we think a short-term fix is (so that we can fix this bug in WP 6.0) and then aim to have the class-based approach like in your code snippet in time for WP 6.1.

Copy link
Contributor

@youknowriad youknowriad Apr 5, 2022

Choose a reason for hiding this comment

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

cc @jorgefilipecosta @oandregal @mcsf if you have any opinions here.

@ramonjd
Copy link
Member Author

ramonjd commented Apr 4, 2022

I've been toying around with alternatives, hoping to cover the requirements of root padding CSS vars as well, but I can't yet find something that satisfies all conditions, namely:

  1. Define a consistent gap across blocks and layouts (flex, flow...) at the root level (one of the reasons behind Avoid using CSS variables for block gap styles #37360)
  2. Reenable block theme.json/global style block gap support (we've disabled it in the UI, but it still doesn't function via theme.json)
  3. Prioritize block theme.json/global style block gap values over theme.json/global style values

Stepping back, if the approach in this PR doesn't end up being the way to go, should we rethink how blockGap is serving us?

Ignoring how hard it would be to do, given that blockGap is closely coupled with our layout implementation, perhaps "spacing" is the wrong group for it, and it should be under "layout"?

  1. blockGap doesn't work in practice like any of the other spacing properties (margin and padding).
  2. The layout panel operates at the block-level (it doesn't appear in global styles). A gap or spacingGap or whatever control would be part of the layout panel, and its value would overwrite the root value and that's it. Basically how it works right now.
  3. blockGap having been taken over by the layout implementation, it could free us up to reintroduce gap block support for non-layout blocks, e.g., navigation, social icons, etc

I'm not sure, just thinking aloud right now 🔊

@andrewserong
Copy link
Contributor

Stepping back, if the approach in this PR doesn't end up being the way to go, should we rethink how blockGap is serving us?

I quite like the approach in this PR, but yes, it probably is worth giving some thought to how blockGap is working for us. One idea I had, which might not be at all viable, would be to re-use blockGap for blocks that don't opt-in to layout support, by implementing the gap value directly, but only if the block does not use the layout support. So something like:

  • The block opts-in to both layout and blockGap — the blockGap gets treated as part of the layout support as it does now and in this PR
  • The block opts-in to blockGap but not layout — the blockGap gets treated as the gap CSS property in much the same way as the padding and margin block supports use it

Not sure how viable that'd be, but just an idea, so we don't wind up with two gap features that are very similar 🤔

Ignoring how hard it would be to do, given that blockGap is closely coupled with our layout implementation, perhaps "spacing" is the wrong group for it, and it should be under "layout"?

I actually quite like "spacing" as the grouping for it, because controlling the gap between things is so closely related to padding and margin, where other controls like orientation, justification, etc, aren't unit-based, so more naturally fit into layout from a UI perspective. So, keeping the structure of where we put the value close to where we display the input field, feels natural to me, even if it does mean that our logic is a little split in terms of what winds up outputting the value.

@ramonjd
Copy link
Member Author

ramonjd commented Apr 4, 2022

would be to re-use blockGap for blocks that don't opt-in to layout support, by implementing the gap value directly, but only if the block does not use the layout support

Great stuff. I like this idea, at least as a soft alternative to keep the spirit of this PR alive. 🥇

@ramonjd ramonjd force-pushed the try/global-styles-skip-block-gap-style-generation branch from db592a2 to 58aa996 Compare April 5, 2022 04:27
@ramonjd
Copy link
Member Author

ramonjd commented Apr 5, 2022

The block opts-in to blockGap but not layout — the blockGap gets treated as the gap CSS property in much the same way as the padding and margin block supports use it

I was thinking about this today. To make the gap CSS property useful, the block would have to employ flex anyway.

It would be nice to separate the two still (layout gap and regular gap).

styleObject => CSS, it's now ( styleObject, theme.json ) => CSS. It changes the mental model and will have an impact on the style engine work.

I think it's gap that starkly highlights the edge case because of the way it works at the root level.

I can't yet come up with any other use case for why we'd want to look up global styles at the block supports level, which means Gutenberg's inheritance model is working fairly well I guess 😄

As @andrewserong mentions above, the other block supports play much more nicely.

So in my mind, either we accept that block gap is a special case and carry on, or we split/change the way block gap works (no idea about that one 🤣 ) or we run with this PR, and look up the Gutenberg style inheritance tree to determine the fallback. The latter would fix the bug until something better comes along.

To be honest I'm not sure either.

Given the the inheritance model of global styles > block global styles > block styles, and somewhere in between elements and, soonish, style "partials" I wonder how long we can get away with the Style Engine only knowing about a block's style object to the exclusion of all other styles that may effect that particular block.

Maybe things will become clearer once we work out how the Style Engine will gather and output block styles/classnames: we'll be able to see inheritance/cascade on the frontend. The answer might lie in the way we structure the CSS as opposed to PHP logic.

🤷

@andrewserong
Copy link
Contributor

To make the gap CSS property useful, the block would have to employ flex anyway.

Or grid! In that case, we're really saying that the block that's opted-in has provided its own display styles, I suppose.

or we run with this PR, and look up the Gutenberg style inheritance tree to determine the fallback. The latter would fix the bug until something better comes along.

I think I'm leaning in this direction, personally. Given that in alternate ways of doing it (like rendering out the class name from the theme JSON class) we're still pulling the value from the same place in the data structure, it seems like the proposed fix here isn't one that would be too difficult to revert if we needed to, since it doesn't alter any saved data.

Given the the inheritance model of global styles > block global styles > block styles, and somewhere in between elements and, soonish, style "partials" I wonder how long we can get away with the Style Engine only knowing about a block's style object to the exclusion of all other styles that may effect that particular block.

That's a good question 🤔, it's very much from the perspective of everything cascading down correctly, which I really like. 🤞 between being able to add more specific selectors, multiple attributes per classname, etc, and consolidating rendering a style object between global styles + at the individual block level, I think we should be able to cover most use cases. Riad's very cool suggestion for the classname-based approach above is a good example of one of the things that should be fairly straightforward if and when we settle on one of the layout-as-presets approaches.

It's highly likely we'll still encounter edge cases that don't quite fit into things, but at least from the style engine perspective — if we've simplified and consolidated rendering a fair bit, and removed a lot of the duplication and one-off code in block supports, and if folks find it easy enough to contribute to, then I think we'll have succeeded.

Maybe things will become clearer once we work out how the Style Engine will gather and output block styles/classnames: we'll be able to see inheritance/cascade on the frontend.

I think so too 🙂

@ramonjd
Copy link
Member Author

ramonjd commented Apr 5, 2022

I think I'm leaning in this direction, personally. Given that in alternate ways of doing it (like rendering out the class name from the theme JSON class) we're still pulling the value from the same place in the data structure, it seems like the proposed fix here isn't one that would be too difficult to revert if we needed to, since it doesn't alter any saved data.

Thanks for your thoughts @andrewserong 🙇

One thing that only occurred to me just now is that layout.php could be classified as a bit of an outlier too. It introduces some intricate styles that require unique logic.

layout.php is also looking at global properties already:

$block_gap             = gutenberg_get_global_settings( array( 'spacing', 'blockGap' ) );
$default_layout       = gutenberg_get_global_settings( array( 'layout' ) );

Maybe part of the paradigm should be to consider it a case of "layout implementation exceptionalism". 😄

Seeing it this way, it makes me sleep better at my desk at night when comtemplating the way we've approached things here as well.

@ndiego
Copy link
Member

ndiego commented Apr 19, 2022

@ramonjd is this still something we are trying to land in 6.0. If not, I will remove from the project board. Thanks!

@ramonjd
Copy link
Member Author

ramonjd commented Apr 19, 2022

@ramonjd is this still something we are trying to land in 6.0. If not, I will remove from the project board. Thanks!

Thanks for checking @ndiego

I'll remove it. I'm not convinced we'll come up with a satisfactory compromise in time.

@scruffian
Copy link
Contributor

This work seems to be connected to the idea of block partials, which is blocked by conditional loading of the styles for each blocks. I had a go at introducing that change here: #40513

I'd appreciate some input from you on this change as I think it will help to drive forward the changes here...

@ramonjd
Copy link
Member Author

ramonjd commented May 11, 2022

Noting that there is a WIP alternative to this PR in the works:

So I might put this one on ice for a bit.

@andrewserong
Copy link
Contributor

Thanks Ramon! Yes, I'm currently hacking away at #40875 to explore Riad's suggestion from this comment (#39870 (comment)) to see if it could be a viable alternative. The PR's a little broken right now but I'll continue playing around with it 🙂

ramonjd added 3 commits May 16, 2022 15:28
…mpiling the styles.

In layout.php, if there is no block-level value for blockGap, but a global styles value available for blockGap, use the latter.
In layout.php, move check for global style into gutenberg_render_layout_support_flag
- Before we were unsetting blockGap for block and elements from the merged $theme_json structure in sanitize().
- After we keep them in the merged $theme_json, but skip them when printing out the global stylesheet.
@ramonjd ramonjd force-pushed the try/global-styles-skip-block-gap-style-generation branch from 3b3d96e to aac2cef Compare May 16, 2022 05:45
@ramonjd
Copy link
Member Author

ramonjd commented Jun 23, 2022

Closing in favour of #40875

@ramonjd ramonjd closed this Jun 23, 2022
@ramonjd ramonjd deleted the try/global-styles-skip-block-gap-style-generation branch June 23, 2022 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CSS Styling Related to editor and front end styles, CSS-specific issues. 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
None yet
Development

Successfully merging this pull request may close these issues.

Layout blockGap / spacing: Add support for gap set at the block level in theme.json and global styles
5 participants