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

Try "constrained" content width as new layout type #42763

Merged
merged 29 commits into from
Aug 22, 2022

Conversation

tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Jul 28, 2022

What?

Fixes #33374.

New layout type

  • Moves the content width logic to a new layout type, called "constrained" which makes it easier to set blocks to use content width by default.

The idea is that, when creating a new block type, we should only have to add

"__experimentalLayout": {
	"default": {
		"type": "constrained"
	}
}

to its block.json and the block will apply content width to its children by default.

  • Add the global content width styles as "base styles" for "constrained" layout, so we don't output wp-container styles for them (this is necessary so the default state of the column layout can access those styles).

Changes to Group block and post editor layout

  • Changes the Group block so newly-added blocks are automatically set to "constrained" layout. Note: for back-compat reasons, we couldn't just change the default layout type, so we're adding some logic to the block Edit to set the layout attribute for all new blocks.

  • Adds deprecation/migration so older group blocks with content width can move to using the constrained layout.

  • The post editor appearance and alignment settings for top-level blocks used to depend on the "default" layout config; this is now changed to use "constrained" layout as the full/wide width options are no longer available for "default".

Changes to the sidebar Layout controls

  • The layout "full width" toggle will now switch from this new layout type to the default "flow" layout.

  • Changes the wording on the toggle to "Inner blocks respect content width" so that the default (flow) layout state is off.

  • The custom content width options now appear when content width is enabled via the toggle.

Things to consider

  • Do we also want to change the layout type for Post Content and Column blocks? That would require using the same logic in their Edit functions as we're applying to Group here.
    * Is "column" really the best name for this layout type? Suggestions most welcome!

Why?

#33374 has shown that for most container blocks in most cases, not having a content width by default is unexpected and puts the burden on the theme author to manually change the setting every time.

This changes the most used container block (Group) to have content width by default, and provides an easy way of enabling content width by default for new blocks.

Testing Instructions

Using a block theme:

  1. Create a bunch of Group blocks with various layout settings on trunk and save.
  2. Switch to this branch; check that previous blocks still work as expected.
  3. Add a new Group block to a post or page.
  4. Check that content width is set on its children by default.

Using a classic theme:

  1. Check that alignments on Group blocks and their alignment-enabled descendants (such as Image blocks) are working the same as on trunk.
  2. Add a theme.json to the classic theme.
  3. Check that newly added Group blocks have content width set by default, and their alignment-enabled descendants have full/wide alignment options.

Screenshots or screencast

@github-actions
Copy link

github-actions bot commented Jul 28, 2022

Size Change: +621 B (0%)

Total Size: 1.24 MB

Filename Size Change
build/block-editor/index.min.js 159 kB +256 B (0%)
build/block-library/index.min.js 186 kB +291 B (0%)
build/edit-post/index.min.js 30.5 kB +14 B (0%)
build/edit-site/index.min.js 57.4 kB +60 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 982 B
build/annotations/index.min.js 2.76 kB
build/api-fetch/index.min.js 2.26 kB
build/autop/index.min.js 2.14 kB
build/blob/index.min.js 475 B
build/block-directory/index.min.js 7.06 kB
build/block-directory/style-rtl.css 990 B
build/block-directory/style.css 991 B
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 15.1 kB
build/block-editor/style.css 15 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 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 110 B
build/block-library/blocks/audio/theme.css 110 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 441 B
build/block-library/blocks/button/editor.css 441 B
build/block-library/blocks/button/style-rtl.css 539 B
build/block-library/blocks/button/style.css 539 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 187 B
build/block-library/blocks/comment-template/style.css 185 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 834 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 630 B
build/block-library/blocks/cover/editor-rtl.css 615 B
build/block-library/blocks/cover/editor.css 616 B
build/block-library/blocks/cover/style-rtl.css 1.55 kB
build/block-library/blocks/cover/style.css 1.55 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 110 B
build/block-library/blocks/embed/theme.css 110 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 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/file/view.min.js 346 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 948 B
build/block-library/blocks/gallery/editor.css 950 B
build/block-library/blocks/gallery/style-rtl.css 1.53 kB
build/block-library/blocks/gallery/style.css 1.53 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 412 B
build/block-library/blocks/group/editor.css 412 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 327 B
build/block-library/blocks/html/editor.css 329 B
build/block-library/blocks/image/editor-rtl.css 876 B
build/block-library/blocks/image/editor.css 873 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/image/theme-rtl.css 110 B
build/block-library/blocks/image/theme.css 110 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 213 B
build/block-library/blocks/latest-posts/editor.css 212 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 705 B
build/block-library/blocks/navigation-link/editor.css 703 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 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation-submenu/view.min.js 423 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.98 kB
build/block-library/blocks/navigation/style.css 1.97 kB
build/block-library/blocks/navigation/view-modal.min.js 2.78 kB
build/block-library/blocks/navigation/view.min.js 443 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 174 B
build/block-library/blocks/paragraph/editor.css 174 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 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 493 B
build/block-library/blocks/post-comments-form/style.css 493 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/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 507 B
build/block-library/blocks/post-featured-image/editor.css 505 B
build/block-library/blocks/post-featured-image/style-rtl.css 166 B
build/block-library/blocks/post-featured-image/style.css 166 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 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 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 282 B
build/block-library/blocks/query-pagination/style.css 278 B
build/block-library/blocks/query/editor-rtl.css 439 B
build/block-library/blocks/query/editor.css 439 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 396 B
build/block-library/blocks/search/style.css 393 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 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 464 B
build/block-library/blocks/shortcode/editor.css 464 B
build/block-library/blocks/site-logo/editor-rtl.css 455 B
build/block-library/blocks/site-logo/editor.css 455 B
build/block-library/blocks/site-logo/style-rtl.css 192 B
build/block-library/blocks/site-logo/style.css 192 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 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.39 kB
build/block-library/blocks/social-links/style.css 1.38 kB
build/block-library/blocks/spacer/editor-rtl.css 322 B
build/block-library/blocks/spacer/editor.css 322 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 494 B
build/block-library/blocks/table/editor.css 494 B
build/block-library/blocks/table/style-rtl.css 611 B
build/block-library/blocks/table/style.css 609 B
build/block-library/blocks/table/theme-rtl.css 175 B
build/block-library/blocks/table/theme.css 175 B
build/block-library/blocks/tag-cloud/style-rtl.css 239 B
build/block-library/blocks/tag-cloud/style.css 239 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 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 561 B
build/block-library/blocks/video/editor.css 563 B
build/block-library/blocks/video/style-rtl.css 174 B
build/block-library/blocks/video/style.css 174 B
build/block-library/blocks/video/theme-rtl.css 110 B
build/block-library/blocks/video/theme.css 110 B
build/block-library/common-rtl.css 1.01 kB
build/block-library/common.css 1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11 kB
build/block-library/editor.css 11 kB
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/style-rtl.css 11.8 kB
build/block-library/style.css 11.8 kB
build/block-library/theme-rtl.css 695 B
build/block-library/theme.css 700 B
build/block-serialization-default-parser/index.min.js 1.11 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 49.5 kB
build/components/index.min.js 198 kB
build/components/style-rtl.css 11.6 kB
build/components/style.css 11.6 kB
build/compose/index.min.js 12 kB
build/core-data/index.min.js 15.4 kB
build/customize-widgets/index.min.js 11.3 kB
build/customize-widgets/style-rtl.css 1.4 kB
build/customize-widgets/style.css 1.4 kB
build/data-controls/index.min.js 653 B
build/data/index.min.js 8.03 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 507 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.69 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 4 kB
build/edit-navigation/style.css 4.01 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/style-rtl.css 6.94 kB
build/edit-post/style.css 6.94 kB
build/edit-site/style-rtl.css 8.22 kB
build/edit-site/style.css 8.2 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.35 kB
build/edit-widgets/style.css 4.35 kB
build/editor/index.min.js 41.5 kB
build/editor/style-rtl.css 3.66 kB
build/editor/style.css 3.65 kB
build/element/index.min.js 4.68 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 6.75 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.64 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.77 kB
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.78 kB
build/keycodes/index.min.js 1.81 kB
build/list-reusable-blocks/index.min.js 1.74 kB
build/list-reusable-blocks/style-rtl.css 835 B
build/list-reusable-blocks/style.css 835 B
build/media-utils/index.min.js 2.93 kB
build/notices/index.min.js 953 B
build/nux/index.min.js 2.05 kB
build/nux/style-rtl.css 732 B
build/nux/style.css 728 B
build/plugins/index.min.js 1.94 kB
build/preferences-persistence/index.min.js 2.22 kB
build/preferences/index.min.js 1.3 kB
build/primitives/index.min.js 933 B
build/priority-queue/index.min.js 612 B
build/react-i18n/index.min.js 696 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.74 kB
build/reusable-blocks/index.min.js 2.21 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.53 kB
build/token-list/index.min.js 644 B
build/url/index.min.js 3.61 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 268 B
build/widgets/index.min.js 7.19 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.06 kB

compressed-size-action

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.

Fascinating idea @tellthemachines!

To make sure I'm following along, the idea with the default layout then, is that it's a simpler flow-based container that can group blocks and provide vertical spacing and alignments, but doesn't provide content size settings? Thinking about the available layout types, I find the idea of default/flow being quite simple and leaving things like content size to other layout types quite compelling!

I left a comment on layout.php, but I'm wondering what happens to Group blocks that are out in the wild (particularly older post/page content that is updated infrequently) that currently set content / wide size or set inherit to true. If we need duplicate handling for those cases, then I could imagine things starting to get messy again, where the shape of this PR is looking quite neat so far 🤔

In terms of naming, I think back when the Stack group block variation was added, folks avoided using Column as the name, to try to avoid confusion with the Column block. That said, I quite like the idea of a Column layout type, particularly if we eventually support settings like flex-basis for max-width, or effectively the kinds of features that are used in the Column block!

@@ -43,6 +43,16 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support

$style = '';
if ( 'default' === $layout_type ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens to existing Group blocks with the default layout type, that set contentSize or wideSize?

@tellthemachines
Copy link
Contributor Author

To make sure I'm following along, the idea with the default layout then, is that it's a simpler flow-based container that can group blocks and provide vertical spacing and alignments, but doesn't provide content size settings? Thinking about the available layout types, I find the idea of default/flow being quite simple and leaving things like content size to other layout types quite compelling!

Yes, that's the idea!

I'm wondering what happens to Group blocks that are out in the wild (particularly older post/page content that is updated infrequently) that currently set content / wide size or set inherit to true.

We should be able to handle those with a deprecation, migrating blocks with inherit to the column layout type. I'm not sure what the approach should be for third party blocks using layout though. Are there even any of those? And is it ok to have a breaking change if the layout support is still experimental?

@andrewserong
Copy link
Contributor

Yes, that's the idea!

Thanks for confirming!

We should be able to handle those with a deprecation, migrating blocks with inherit to the column layout type.

Unfortunately, I don't think a deprecation will be enough in this case as it requires the blocks to be edited in the editor before the rendering fix will take effect. This could be a tricky situation where we need non-migrated markup to still be rendered correctly 🤔

I'm not sure what the approach should be for third party blocks using layout though. Are there even any of those?

I'm not sure, but the layout support doesn't appear to be intended for third party blocks at this stage, as it's pretty much undocumented?

And is it ok to have a breaking change if the layout support is still experimental?

That's a great question. From my perspective, I think breaking changes in API-terms are probably fine, but breaking styles on existing sites, or requiring block markup to be migrated in order to render correctly is probably a blocker.

It's definitely one of the harder areas for me conceptually with the Layout block support — because it's used in production on such heavily used blocks (like Group and Columns) it's very difficult to make significant changes without breaking something 😅

@andrewserong
Copy link
Contributor

Unfortunately, I don't think a deprecation will be enough in this case as it requires the blocks to be edited in the editor before the rendering fix will take effect

Hrm... unless if we infer the type based on the presence of the inherit or contentSize, wideSize attributes at the top of the gutenberg_get_layout_style function... okay, I think I'm back on board 😅

@tellthemachines
Copy link
Contributor Author

Yeah, I was thinking the styles to display content width only need the is-layout-column class, which we could attach on the server side if it doesn't exist. I'll have a play and see what we can do!

@tellthemachines
Copy link
Contributor Author

I updated with a deprecation for the Group block, as well as some server-side logic to handle cases where there are inherit or contentSize values. There remains a problem though:

  • If an existing Group block doesn't have any of those values set, it is assumed to be using the $default_block_layout.
  • Because we've changed the default for Group to the new 'column' layout, existing Group blocks with no particular layout configured will automatically start using 'column', which we don't want. We want them to continue using 'default'.
  • This will affect existing content on the front end.

So you did have a good point above @andrewserong 😅

I'm not sure how best to fix this. We could, of course, not change the default on the Group block and instead do something like I tried in #42582 to update new blocks on the fly. I still don't love that solution though 😅

@andrewserong
Copy link
Contributor

Because we've changed the default for Group to the new 'column' layout, existing Group blocks with no particular layout configured will automatically start using 'column', which we don't want. We want them to continue using 'default'.

Ah, yes, that's a good point. Thanks for digging in here! At the very least, it's really helpful to have these PRs that demonstrate a potential solution and the exact problems we encounter when attempting to implement it. It sounds like we've got a few trade-offs to weigh up here!

I'm not sure how best to fix this.

In some ways it feels like one of the challenges we face is a similar one to some other issues/PRs of wanting to be able to perform an action when a block is inserted, and only on insert. I wonder if there's any way for us to tease apart the difference between the default value (in terms of what's a default value when the block is serialised) from the value that is set when a block is inserted? That might be a bit of an API rabbithole to figure out, though 🤔

From my perspective, between the approaches, it feels like #42582 gets to the heart of the particular task at hand, but like you mention, that solution has its drawbacks too.

I wonder if there's anything we can do with block variations, or use update logic that only applies if the Group block is empty? At the very least, that might help us hone in on only making changes to blocks that aren't doing anything visually on the front end of the site?

Not sure how helpful that is as an idea, but I'm happy to do a bit of digging / hacking around this week, too!

@andrewserong
Copy link
Contributor

or use update logic that only applies if the Group block is empty?

Not sure how helpful it is, but I had a go at this in #42876 @tellthemachines — it's still a pretty hacky approach, but tries to see if we can get it kinda working without deprecations. I was mostly curious to see if restricting the logic to only apply to empty Group blocks that haven't yet defined inherit as either true or false helps us at all 🤔

@tellthemachines
Copy link
Contributor Author

Thanks for helping me think this through @andrewserong !

I wonder if there's any way for us to tease apart the difference between the default value (in terms of what's a default value when the block is serialised) from the value that is set when a block is inserted?

I don't think there is at the point that matters to us here, which is in layout.php where we're setting the value of $used_layout.

  • If the block has a non-default value for its layout type (such as inherit for the current definition of flow layout), its attributes reflect that. If the layout values on the block were never changed, we don't have any attributes at this point.
  • If there are no attributes, we grab the default layout for that block type. This is where we run into a problem: if we change the default for the Group block, any existing block without attributes will now think it's meant to have a column layout.

I think attributes are our best bet to tell apart blocks with the legacy default layout from newly-added blocks that are meant to have the column layout by default, because they are the only info we have about each specific block. Unless I'm missing something, everything else we can access here - block defaults, layout definitions - concerns the block type or the layout type, so gives us nothing on the block itself.

The thing is we can't add attributes to existing blocks unless they are being edited and can go through the deprecation, but we can add attributes to all new blocks as they are generated, which is what #42582 attempts to do. In which case, we don't need to change the block layout type, just change the edit logic to switch all new blocks to the column type as they're created.

I wonder if there's anything we can do with block variations, or use update logic that only applies if the Group block is empty? At the very least, that might help us hone in on only making changes to blocks that aren't doing anything visually on the front end of the site?

I don't think adding a new variation would help us here, because we'd still face the problem of old default vs new default. And looking at Group content is risky because an empty Group might be used for formal purposes, as in this artwork!

The more I think of it, the more I'm convinced that we need to do something like #42582. But I think what we're doing in this PR is also important, because it provides a way of configuring new block types to have content width from scratch.

However, the logic from #42582 will need to change somewhat to accommodate this PR. I think I'll try bringing it in here, thus ending up with the mega-PR I was trying to avoid 😅

@andrewserong
Copy link
Contributor

And looking at Group content is risky because an empty Group might be used for formal purposes, as in this artwork!

Hey, that's also a fantastic pattern to use as a test case to make sure we don't break anything! What a fun one 😍

And I see what you mean, from that pattern the following still renders on the frontend:

<!-- wp:group {"style":{"border":{"style":"solid"},"color":{"background":"#d3dce4"}}} -->
<div class="wp-block-group has-background" style="border-style:solid;background-color:#d3dce4"></div>
<!-- /wp:group -->

This is output on the site frontend as:

image

If we were going with an empty / has no inner blocks check, then it'd probably also need to check that there are no attributes set at all 🤔... ah, it sure is tricky! 😅

I think attributes are our best bet to tell apart blocks with the legacy default layout from newly-added blocks that are meant to have the column layout by default

So, basically, yes, I think you've hit the nail on the head here 👍

Copy link
Contributor Author

@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 now ready for review! Don't be discouraged by the big diff, most of it is snapshot updates 😄

This PR does two main things:

  • Introduces a new layout type to deal with content/wide widths and their associated styles.
  • Sets some logic in the Group block so newly-added Groups get content width by default.

These two things could be done in separate PRs, but this way we can get a complete picture of how this works as a fix for #33374.

);
}
}
} elseif ( 'column' === $layout_type ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a very weird diff but essentially, what I did here was move all the contentSize/wideSize logic into a new "column" layout type

// Set the correct layout type for blocks using legacy content width.
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) {
$used_layout['type'] = 'column';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Blocks with contentSize or inherit are migrated to "column" layout on the front end.

$wide_size = isset( $settings['layout']['wideSize'] ) ? $settings['layout']['wideSize'] : $settings['layout']['contentSize'];
$wide_size = static::is_safe_css_declaration( 'max-width', $wide_size ) ? $wide_size : 'initial';
$block_rules .= '--wp--style--global--content-size: ' . $content_size . ';';
$block_rules .= '--wp--style--global--wide-size: ' . $wide_size . ';';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

contentSize and wideSize values are added to root as custom properties. This is necessary so we can use them in the base styles declared in theme.json.

@@ -46,7 +46,7 @@ export default function useAvailableAlignments( controls = DEFAULT_CONTROLS ) {
}

// Starting here, it's the fallback for themes not supporting the layout config.
if ( layoutType.name !== 'default' ) {
if ( layoutType.name !== 'default' && layoutType.name !== 'column' ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should in theory have been able to change this to if ( layoutType.name !== 'column' ), but that caused the BlockAlignmentUI unit tests to fail, because rendering that component is dependent on a layout type (which defaults to default) and in order for tests to succeed it needs to have some alignment controls inside it 😅

packages/edit-post/src/components/visual-editor/index.js Outdated Show resolved Hide resolved
name: 'core/paragraph',
attributes: { content: 'P' },
name: 'core/button',
attributes: { text: 'Click' },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this is an interesting one. Ostensibly these tests are checking whether cut/paste actions work correctly for nested blocks. But they are also checking if the blocks are replaced more than once during paste. This last part started failing with this changeset, probably because the Group block now updates itself to use the column layout. So to preserve the original intent of the check, I've replaced the Group/Paragraph with Buttons/Button.

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.

I love what you're doing with this PR @tellthemachines! The ah-ha moment for me was looking at the logic in the UI for editing what used to be the inherit setting in the group block.

With this PR applied the logic now appears to be:

  • Toggle Inner blocks respect content width off results in default layout being applied
  • Toggle Inner blocks respect content width to true and don't enter any values for content/wide width, and the root/default values are used, and no container classname is added
  • Toggle Inner blocks respect content width to true and enter values for contentSize, and a container class is added with the desired max-width on the children:

image

Overall this seems like a really nice way to remove the confusing idea of inheriting from the default layout, kudos for digging into how to get us from the current state of things to a more ideal representation of this kind of state! 👍


For the questions:

Do we also want to change the layout type for Post Content and Column blocks? That would require using the same logic in their Edit functions as we're applying to Group here.

If we don't make changes to these blocks in this PR, will this PR introduce regressions for existing blocks out in the wild? Or to put it differently, is this PR a breaking change for all blocks that have opted in to the default layout type? 🤔

We might need to put together some test markup to take a look at the impact of the changes on those blocks.

Is "column" really the best name for this layout type? Suggestions most welcome!

I can't quite think of a good alternative, but I think it'd be great if we can think of something that helps distinguish it from the Column block as I imagine it could be confusing the two using the same name. I suppose one question for the naming of the type is: are there additional features we'd like this layout type to have, that could help clarify its intended usage? I can't quite think of anything that isn't super clunky, like "flow with content sizes" or "constrain child content sizes"... ah naming is hard 😅


This PR changes a fair bit, so it might take me a little while to review in detail. I'll add comments here over the next couple of days, with things I find during testing, if you don't mind! I've added a comment about the post title wrapper that I noticed immediately.

packages/edit-post/src/components/visual-editor/index.js Outdated Show resolved Hide resolved
@@ -15,6 +15,12 @@
"templateLock": {
"type": [ "string", "boolean" ],
"enum": [ "all", "insert", false ]
},
"layout": {
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 being set here since this attribute comes from the block support?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we set the default in the block support, it would break back compat for existing blocks. Adding it as default here, together with the effect that's causing problems (#43760) in the edit function, ensures new blocks get the correct layout while existing blocks aren't changed.

If you have any ideas on how to do this better, I'm happy to explore them!

@youknowriad
Copy link
Contributor

Changes the Group block so newly-added blocks are automatically set to "constrained" layout.

This seems like the main reason for this new layout right? and if I'm understanding right, this is the same thing as applying "inherit" by default. So why did we decide to introduce a new layout instead of just making "inherit" true by default?

@tellthemachines
Copy link
Contributor Author

So why did we decide to introduce a new layout instead of just making "inherit" true by default?

Mainly to make it easier to set it as the default layout type on new blocks, but it also had the nice side effect of allowing us to make the content width styles base styles (with content and wide width output as custom properties at root level), so we don't have to output wp-container-x classes for them anymore. Strictly speaking it wasn't necessary to do this in order to make Groups have content width automatically, but it felt like a good improvement to make.

@youknowriad
Copy link
Contributor

Strictly speaking it wasn't necessary to do this in order to make Groups have content width automatically, but it felt like a good improvement to make.

I might differ in opinion because I feel like constrained and flow are just the same thing with different configs and we're tweaking the concept of "layout" for convenience rather than actual semantics but anyway, seems a bit late to alter it even more.

Adding it as default here, together with the effect that's causing problems (#43760) in the edit function, ensures new blocks get the correct layout while existing blocks aren't changed.

I think it's just not possible, useEffect on blocks on initialization is something we should forbid IMO, it's not the first time it creates issues. One potential solution is to remove the "group" block from the inserter by default and instead use a variation with the layout set. createBlock( 'core/group' ) will still result in a "flow" layout default.

@tellthemachines
Copy link
Contributor Author

I think it's just not possible, useEffect on blocks on initialization is something we should forbid IMO, it's not the first time it creates issues.

I was afraid you might say that 😅

One potential solution is to remove the "group" block from the inserter by default and instead use a variation with the layout set. createBlock( 'core/group' ) will still result in a "flow" layout default.

That sounds like an acceptable compromise. Could we name the variation "Group" so that the creation flow doesn't change?

@youknowriad
Copy link
Contributor

That sounds like an acceptable compromise. Could we name the variation "Group" so that the creation flow doesn't change?

Yes, I think so.

@andrewserong andrewserong added the [Feature] Layout Layout block support, its UI controls, and style output. label Sep 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Group Affects the Group Block (and row, stack and grid variants) [Feature] Layout Layout block support, its UI controls, and style output. Needs Dev Note Requires a developer note for a major WordPress release cycle Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot apply wide or full widths to nested blocks with theme.json applied