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

Block nesting and horizontal alignment of InnerBlocks #14234

Closed
getdave opened this issue Mar 5, 2019 · 10 comments
Closed

Block nesting and horizontal alignment of InnerBlocks #14234

getdave opened this issue Mar 5, 2019 · 10 comments
Assignees
Labels
[Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P Needs Design Feedback Needs general design feedback.

Comments

@getdave
Copy link
Contributor

getdave commented Mar 5, 2019

The proposed Container Block is getting closer to landing in Core! However it is missing a key feature - the ability to horizontally align its child Blocks.

Problem

As it stands you can alter the alignment of a Container Block to be wide or full. However once you do so there is no way to control the alignment of the InnerBlocks (child Blocks added to the Container).

This makes it impossible to achieve layouts such as a full width "band" (100% width stretching to the edge of the viewport) with content aligned centrally to the site/content width.

Here's an example of the layout which is currently not possible:

band

Given how prevelant this type of "banded" layout is on the web today we need to find a solution which affords the ability to align the child Blocks within an InnerBlocks component.

Note that the InnerBlocks component is a "pass through" component which does not currently display any UI controls.

Solution

One solution is to add controls to any given Block that makes use of the InnerBlocks component to give it the ability to control the alignment of the wraping <div> rendered by InnerBlocks.

I created a demo of what such an enhancement could look like (I used the Container Block as the basis for this) - for our purposes focus your attention on the controls which allow you determine the alignment of the inner content:

demo-alignment

Please note: the icons used (they are placeholders) and where the tools are located (sidebar or Block toolbar) are a implementation details. We are primarily interested in the high level approach.

This is (I believe) a good solution, but it does mean that every Block would have to add controls to control the alignment of the InnerBlocks. One alternative is that InnerBlocks itself renders it's own toolbar, but this doesn't feel quite right given that it's always been a "pass through" component.

Alternative Solution

@youknowriad has proposed an alternative solution which involves adding an API to allow any Block that uses InnerBlocks to have the ability to determine which alignment controls are available to the Blocks which are within its InnerBlocks.

This might look something like the following:

supports: {
   allowedInnerBlockAlignments: [ 'wide', 'full', 'left', 'right' ]
}

or

supports: {
   allowedInnerBlockAlignments: [ 'wide', 'full'] // doesn't allow "left" or "right"
}

By default all child Blocks of InnerBlocks would have their alignment set to "centered" (default - no value). However each child Block would be able to overide this and toggle its own alignment to be any one of the whitelisted values (from allowedInnerBlockAlignments).

One potential problem here is that this would require all Blocks to have a BlockAlignmentToolbar added to them when used in the context of InnerBlocks.

Feedback Welcome

I feel the ability to align the Blocks added to a Container is critical to allow the new Block to be truely useful. However, we need to ensure we're approaching this in the right manner.

I'd hugely appreciate any input on

  1. Which solution would work best and why?
  2. Any additional downsides to either solution?
  3. Any alternative solutions?
@getdave getdave added [Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P Future labels Mar 5, 2019
@getdave getdave self-assigned this Mar 5, 2019
@youknowriad
Copy link
Contributor

It's also good to think of how this API relates to the canvas of the editor as it is today, the canvas could be considered as an "invisible" container block.

@youknowriad youknowriad added Needs Design Feedback Needs general design feedback. and removed Future labels Mar 5, 2019
@jasmussen
Copy link
Contributor

Good ticket, and +1 to what Riad said. His solution seems to make sense at a cursory reading too.

The thing to think about here is: what is the role of the container block? What should it do? Or more importantly, what should it not do?

The key thing to keep in mind here is ensuring that the 5 buttons we have — left, center, right, wide, fullwide — always behave the same (or at least appears to behave the same). Insert a small image and press the Center button, for example, that image is now centered. How would this compare to how such buttons would do in your GIF mockup?

At the same time, if you mean to center ALL the content inside of a container block, then absolutely we're back to where we started (regarding color background discussions), that the container were meant to solve. So in that vein, the use case of being able to provide an alignment for inner blocks definitely does make sense.

This brings me back to what Riad suggested — wide is honestly an aspect of contents inside the editing canvas. What would it look like in a full editor where we had content outside that editing canvas, such as a "header" or a "footer"? In such a world, "full wide" is more or less the default, and anything other than that is actually a layout moreso than an alignent. This is a future I'd personally like to see happen. I suppose that is a high level plus one to Riad's suggestion.

@getdave getdave mentioned this issue Mar 5, 2019
15 tasks
@getdave
Copy link
Contributor Author

getdave commented Mar 5, 2019

Thanks @jasmussen. Appreciate your input and insight

what is the role of the container block

  • Provide a container "context" on which to hang css based changes - makes UI more extensible for CSS changes.
  • Provide a way to wrap a group Blocks to apply central point of layout/styling (eg: alignment and/or backgrounds)
  • Semantics - eg: could have an option to add a <seciton> element in the future

I'm open to more suggestions though...

The key thing to keep in mind here is ensuring that the 5 buttons...always behave the same

Agreed. Learn the UI once and once only.

Insert a small image and press the Center button, for example, that image is now centered. How would this compare to how such buttons would do in your GIF mockup?

No difference. The child blocks are left entirely alone. A class is applied to the <InnerBlocks /> component itself which aligns it within the parent Container as required by the setting selected. Therefore the existing interface for all other Blocks is preserved (unlike the other option where we need to add new controls to a whole swathe of existing Blocks...).

if you mean to center ALL the content inside of a container block

I mean to align the content. "Center" is perhaps a misleading term. By default the Container Block is the site width. However if yuo set it to align: full then it's 100% of the viewport width. You may need this to achieve a full width background, but you might then want your content (ie: the InnerBlocks) to be aligned to the rest of the site content (ie: contents outside of the Container Block). Again referring to the visual design of Digital Ocean I've referenced will help to frame this.

Is the above clear? It's an important point.

What would it look like in a full editor where we had content outside that editing canvas, such as a "header" or a "footer"?

I'd love to see a someone who is a more competent designer explore this.

In such a world, "full wide" is more or less the default

It it though? How many websites do you see where the content is allowed to abutt the far sides of the viewport on large screens? Very few. The reason is because we typically set a max-width on the contents of the site so that it doesn't become unwiedly.

So with a header you'd still need to be able to align the contents of the header to the middle of the site else you'd end up with a logo off to the far left side and a menu off to the far right hand side leaving a huge gap of whitespace in the middle.

Does that make sense?

Some great discussion here which I'd like to try and get more people involved with. I will be raising in #core-editor chat on Wednesday.

Thank you again.

@jasmussen
Copy link
Contributor

Great thoughts.

It it though? How many websites do you see where the content is allowed to abutt the far sides of the viewport on large screens? Very few. The reason is because we typically set a max-width on the contents of the site so that it doesn't become unwiedly.

To clarify I a bit here, I'm thinking way beyond the block editor being just for content. I'm imagining the block editor for your entire site, a "full editor" where you see and can edit inline, both your header, navigation menus, sidebars, footers, and indeed any other additional content areas your website might have. This is a world wherein the WordPress theme is less of a provider of a ton of markup, and more a provider of JSON based page templates and some CSS on top of that.

All of that is still early days and speculative, of course. But if such a future would come to pass, you could imagine a section block being the container of your post contents — i.e being one step up from where you are today. You could even imagine one being the container for your entire website.

In other words, same as a single div in an empty codepen spans the full width of the viewport, so would a container be unbounded by default, and "full wide" be something left for content inside that to decide upon.

@kjellr
Copy link
Contributor

kjellr commented Mar 14, 2019

This makes it impossible to achieve layouts such as a full width "band" (100% width stretching to the edge of the viewport) with content aligned centrally to the site/content width.

Here's an example of the layout which is currently not possible:

Given how prevelant this type of "banded" layout is on the web today we need to find a solution which affords the ability to align the child Blocks within an InnerBlocks component.

I was just chatting with @getdave about this issue, and wanted to throw out an alternate way of looking at this problem.

Once the Section block has launched, it's theoretically possible to achieve this via the following structure:

Artboard

Please ignore the extreme ugliness of this, but here's the general effect, using just what's available today in #13964:

Screen Shot 2019-03-14 at 10 21 28 AM

This obviously isn't quite right for a number of reasons, but it does mimic the basic structure of the example above. While it'd be fairly unreasonable for us to require users to learn advanced block nesting in order to achieve a seemingly-basic result like this, I do think this could be an opportunity for us to take the Cover block approach to this: The cover block is really just a Section block, pre-configured into a commonly used pattern.

Along those lines, we could create some pre-packaged nested block templates for users to insert and easily achieve the pattern used in that DigitalOcean screenshot. Going this route would also allow us to intelligently assign reasonable margins + inner block behavior to optimize the appearance for this context.

@mapk
Copy link
Contributor

mapk commented Mar 15, 2019

Just adding my thoughts here.

  1. I believe inner blocks should have alignment controls, but those alignment controls should be in the toolbar of the inner block itself. Not the sidebar.
  2. Using the API to determine which controls are surfaced sounds good to me.
  3. I would expect the alignment of an inner block to work within the Section block similarly to how it works outside the Section block, but just constrained by the Section block's width as noted in this comment.
  4. I have no problem sticking to 3 alignment options like we currently have for image blocks right now: 1. Content width, 2. Align-wide, and 3. Full-width.

@jasmussen
Copy link
Contributor

In expansion on #14234 (comment), that layout should be possible with plain editor styles and CSS even today, right? I.e. even if this block ships without alignment support, you could still achieve that layout using editor styles.

Something along the lines of:

.wp-block-section[data-align="wide"] {
max-width: none;
}

.wp-block-section[data-align="wide"] .wp-block {
max-width: 610px;
}

I know that may not be as elegant as having explicit buttons for it.

But one of the things we have to be mindful of here, is to not keep good PRs from being merged in the name of perfection. It might make sense to merge the Section block even in its most barebones state, before we hold it up with too much additional complexity. Already the Columns alignment PR is being postponed a bit simply because the selection of parent/child blocks is still fiddly.

Maybe some of the complexity will be easier to answer once we have a basic V1 out of the door?

@mapk
Copy link
Contributor

mapk commented Mar 15, 2019

But one of the things we have to be mindful of here, is to not keep good PRs from being merged in the name of perfection. It might make sense to merge the Section block even in its most barebones state, before we hold it up with too much additional complexity.

I think this is a good point made when the experience doesn't feel broken. Like if the MVP is just missing a few features, cool, but not being able to adjust alignment of inner blocks doesn't feel right, and produces an outcome I wasn't expecting. I'm trying to understand more, so please bear with me. What problem are we solving with the Section block? Or what's our hypothesis of how we think people will want to use it most? (I may have missed these conversations, so if there's a link, I'm happy to be pointed there.)

My answers, which could very well be wrong, are 1) To provide a block that groups content together visually. The "visual" aspect of this seems most apparent through the use of a background color. When I think of this, I immediately think of the full-width block patterns on the web that show a full-width background color with the content retaining a narrower width in the middle (much like the DigitalOcean example above). This reflection is also my hypothesis as to how most people will want to use this Section block. Right now this doesn't work.

I definitely don't want to hold up a block for reasons that it isn't trying to solve. So please correct me if I'm wrong. The other thought here is to completely remove the inner block's alignment toolbars until this is figured out in another PR. But I would only go this route if my hypothesis isn't one of the main ways in which we imagine people using this block.

@getdave
Copy link
Contributor Author

getdave commented Mar 20, 2019

I agree with @mapk. As such I've got a working prototype of this on my fork of the Section Block PR. This will be merged into the core branch if/when it is deemed to be working correctly.

I think this issue can remain open until this feature lands.

@getdave
Copy link
Contributor Author

getdave commented Apr 2, 2019

Closing as Section now shipped with this resolved #13964

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Nested / Inner Blocks Anything related to the experience of nested/inner blocks inside a larger container, like Group or P Needs Design Feedback Needs general design feedback.
Projects
None yet
Development

No branches or pull requests

5 participants