WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.47k stars 4.18k forks source link

Dimension Tools and Controls #28356

Open youknowriad opened 3 years ago

youknowriad commented 3 years ago

This is a sub part of #27331

The tools to configure the spacing of a block are among some of the most incoherent tools we offer, with controls usually scattered across different panels and standalone tools. (See #23770, #24874, #26368, #22956, #14747.)

The proposed dimensions panel emerges as the consolidation of controls relating to the space a block occupies on the page. This includes but is not exhausted by height, padding, width, possibly alignment, and so on. Much like the typography panel, these controls are not always going to be present for every block, so it’s important individual controls can be toggled on and off as required, and that blocks can expose those that are considered default options based on configuration. The focus in this exercise is to test how the different controls ought to be laid out.

Screenshot 2021-01-20 at 12 46 00

Let's try to split the work needed to achieve the proposed output in these mockups:

Height Control

Question Should the height attribute be its own block attribute or should it be part of the "style" attribute.

Width Control

I'm not talking here about the "full width"/"wide width" UI here but more about the "width" control we have right now in some blocks like "column" or "button". Basically the equivalent of the height control shown as an input.

Question Should the attribute be its own block attribute or should it be part of the "style" attribute.

Padding

We do have an existing support flag for padding, so we need to adapt it to work consistently to the other controls.

Margin

The primary focus for this is to provide a spacing option between the blocks that can work globally.

Block Alignments

What we call block alignments is the "full width"/"wide width" UI shown in the mockups and sometimes it can include "left/right"... We do have a support flag for these called "align" but it has a few issues: It's not used consistently in blocks, some blocks have their own custom "align" support. Another problem is that it uses the "align" attribute which might have a different meaning in some other blocks.

The other issue here is that this control only make sense in the "default" layout (Meaning if the container is just a normal vertical list of blocks). In different layouts like the "flex" layout (which already exists in the code base but in an implicit way using the "orientation" prop), these alignments don't make any sense.

I think here we need to be more generic and instead of talking about "block alignments" we should just talk about "position". So inside a "default" layout container, the values can be "wide"/"full"/"left"/"right"/"center"/"none" but inside a "flex horizontal" container, these values don't apply and inside an "absolute container", we might have "x and y", inside a "grid" container we might have something else (rows, columns)

So I think what's important here at the moment is to scale down the scope to the "default" layout but we keep in mind how this attribute should or shouldn't translate to other future layouts.

Based on this, here's what I think should be the plan here:

youknowriad commented 3 years ago

Started working on some of these. First thing is adding padding block support to dynamic blocks.

youknowriad commented 3 years ago

Started working on the margin block support in #30371

youknowriad commented 3 years ago

Padding server-side support flag is now merged.

aristath commented 3 years ago

Have we considered using a box-model control like the one browsers have in their dev tools? box-model

Using something like that we could have padding, margin, borders, all in one, using a familiar UI, and we can definitely toggle features on/off by making some of the values editable... A couple of years ago I built something similar for the customizer and it was pretty convenient at the time kirki-box-model Visually it was meh, but that's easy to fix... functionally it was intuitive and accessible

jasmussen commented 3 years ago

I ran into needing a margin today. This will be such an important tool to build great patterns.

priethor commented 3 years ago

As @jasmussen says, margin support seems to be one recurring tool required by many theme blocks to build rich patterns.

carolinan commented 3 years ago

I saw that a PR for adding support for margins to the site title block was merged. If this is now implemented, shouldn't margin controls be enabled by default for all blocks?

jasmussen commented 3 years ago

If this is now implemented, shouldn't margin controls be enabled by default for all blocks?

I'm conflicted here. On the one hand, I deeply want this feature for better patterns. On the other hand, the current margin controls are very clunky, and there isn't a #27331 inspired design for how we surface margin/spacing in a user-friendly way yet. For example while we might know by heart the difference between margin and padding, this is not necessarily obvious for the average user — so do we put margin and padding behind a segmented control? Do we take up space and have controls for both visible at the same time? Is there an alternative that better abstracts the controls? It's a difficult design, and every feature we surface adds weight, even if it's a collapsed-by-default panel.

Question: can we enable margin support for all blocks through theme.json and markup, without surfacing the UI for it yet? While not the most obvious interface for building patterns, at least it would be technically unblocked as we refine the UI for it.

aaronrobertshaw commented 3 years ago

Margin block support was added in https://github.com/WordPress/gutenberg/pull/30608.

I'm also starting to work on updating the spacing support panel into the proposed "Dimensions" panel. Once I have that in place, the plan is I'll add height and width support to that.

aaronrobertshaw commented 3 years ago

There is a proof of concept up for the Dimensions panel in https://github.com/WordPress/gutenberg/pull/32392.

It focuses on adding a new component that can easily be reused across multiple block supports. The individual block support controls for margin and padding can be updated as the G2 component matching the design gets imported in the near future.

The linked PR uses the new component to convert the current Spacing support panel into the basis for the new Dimensions panel. I'll be adding height and width support to it soon.

mtias commented 3 years ago

@jasmussen I've been thinking a bit about how we name and express these tools, because it seems we have three related but distinct elements: a layout panel, a spacing pane, and a dimensions panel. I'm not sure it makes sense to couple spacing with dimensions (padding/margin with width/height).

aaronrobertshaw commented 3 years ago

I'd be happy to update the padding/margin support to appear again under a "Spacing" panel again. I can address that in the next day or so unless further discussion is required?

mtias commented 3 years ago

Let's see first if that is indeed what makes the most sense — @jasmussen @shaunandrews @pablohoneyhoney for thoughts.

aaronrobertshaw commented 3 years ago

There are draft PRs in place for height and width block support.

They have also been updated to remove the custom prefix from their theme.json properties as per feedback and the theme.json v2 tracking issue.

During the creation of the width block support, the need for both segmented and explicit controls for the width support was raised. To explore this further another PR was created adopting the width support for the button block.

Before these PRs progress any further, I'd expect we'll wish to decide upon whether we're merging dimensions back under spacing in both the settings and the UI.

jasmussen commented 3 years ago

34608 adds gap support to the Gallery block, and #34630 adds it to the Columns block. At the moment, the block gap control sits in a dimensions panel which doesn't feel quite right since it doesn't affect any dimensions. So I took a quick stab the three proposed Spacing, Layout and Dimensions panel, correlating them with the controls we have, to see where things might land.

Note that the mockups in this comment are meant for discussion and do not necessarily represent final work. They are subject to change to match the work on Global Styles in #34574.

Of the proposed "Spacing" and "Layout" panels, Block gap feels like it could exist in either, though Margin and Padding controls feel related to Spacing. An argument for Block gap in the Layout panel would be that it affects the child blocks, not the block itself. On the other hand, you'll likely very often want to adjust both the padding and the gap at the same time, for example to space items inside a colored group.

That leaves us with a "Spacing" panel featuring margin, padding and gap. Mockup:

Spacing

The recently merged "Row" block — a horizontal variant of Group — opened the question of being able to toggle the direction of a block. Such a toggle would almost certainly be a Layout feature, even if it could've been nice to couple it with padding and gap.

The search block has a min-width, but it can also have an explicit width. We could potentially unify under a single width control by adjusting both min-widths and widths when explicitly setting a width. Cover currently has a Minimum height control, though the same question applies: is that just a Height control that sets min-height under the hood? In either case it leaves us with at least width and height controls.

But even then, there are likely ways blocks will want to curate those panels and their default states. For example a horizontal Buttons block would likely only want to surface width controls, and surface them primarily as presets with an option to edit freely:

Width

In some cases, the widths would correspond content, wide and full width presets:

Dimensions

In others, like the Image, you'd likely want explicit values directly accessible, including a "Size" preset:

Image

While related to dimensions, of the above examples, only the Image block shows more than 2 controls at a time. If that's all we end up with, it's possible we'd want to consider adding these as part of the Layout panel instead.

Layout is contextual to the container selected. In template contexts, Layout primarily affects child blocks whether through defining content/wide widths or justifications for flex containers:

Justification

That could be an argument for keeping width/height controls specific to a particular block in a bespoke Dimensions panel after all.

☝️ These are some of the puzzle pieces we have to put together. Do they point to three panels, or two?

andrewserong commented 3 years ago

Thanks for adding the discussion and design explorations, Joen! I think it makes sense to keep block gap (or spacing) close to margin and padding because those values will often be closely linked, as you mention. There's also the possibility that the gap support might be useful for some blocks that don't opt in to the Layout support. For example, any block that has internal elements that are not separate blocks, might benefit from a gap spacing control, such as the Post Author block, or possibly the Post Tags block if we wanted to support pill / button styles for the tags further down the track?

jasmussen commented 3 years ago

I think it makes sense to keep block gap (or spacing) close to margin and padding because those values will often be closely linked, as you mention.

Agreed. I was reminded again of how we still have some work to do on the visuals of the margin and padding controls (see mockups above), but also how visually close margins and paddings are. To the untrained eye, or just to people new to building websites, the nuance between margin and padding is not obvious at all. Things like #33221 will help here, but even when curating the inspector controls, we may be able to improve things by perhaps only showing one at a time, and letting the other be something you add from the tools panel. For example, padding is hugely valuable on a group block, margin less so.

For example, any block that has internal elements that are not separate blocks, might benefit from a gap spacing control, such as the Post Author block, or possibly the Post Tags block if we wanted to support pill / button styles for the tags further down the track?

Definitely. I think post metadata in general is an area to still shine a light on — while you can get far with inline flex and gap, there are some formats for post meta that read more like prose than horizontal lists, which is a use case that might still be good to explore.

richtabor commented 3 years ago

These are some of the puzzle pieces we have to put together. Do they point to three panels, or two?

What about one (a "Layout" panel)? Perhaps we should mock-up what each of these would look like?

colorful-tones commented 3 years ago

@youknowriad @aaronrobertshaw - do you mind providing an update of where Margin support is at please?

I've dug through most of the linked and associated PRs (closed: #30371 and merged: #30608) and I'm still unclear as to the progress, or barriers.

Margin block support was added in #30608.

@aaronrobertshaw - I'm thinking that this would not necessarily be targeted at Full Site Editor integration, correct?

Question: can we enable margin support for all blocks through theme.json and markup, without surfacing the UI for it yet? While not the most obvious interface for building patterns, at least it would be technically unblocked as we refine the UI for it.

@jasmussen - I think that this is a good idea and is causing some confusion for FSE themes, especially TwentyTwentyTwo. See: Post Title Block: Custom margin applied to Headings does is not reflected in the front-end #35522

I just tried the following to see if I could get margin support in the Post Title block (on Gutenberg trunk), and it did not work for TwentyTwentyTwo:

wp-content/plugins/gutenberg/packages/block-library/src/post-title/block.json

    "supports": {
        "spacing": {
            "margin": [ "top", "bottom" ]
        },
    }

And I tried:

    "supports": {
        "spacing": {
            "margin": true
        },
    }

I then added this to TwentyTwentyTwo's theme.json for good measure:

        "spacing": {
            "customMargin": true,
            "units": [
                "%",
                "px",
                "em",
                "rem",
                "vh",
                "vw"
            ]
        },

And I can not see the margin UI anywhere: block editor sidebar or full site editor when I select the Post Title block.

I would be happy to get a PR going for margin support for targeted block, and just needing a little additional context as to the barriers or progress. Thanks!

colorful-tones commented 3 years ago

(Oops, I have no idea how I closed this Issue, and just reopened. 🤦 Glad I noticed my mistake.)

aaronrobertshaw commented 3 years ago

Hi @colorful-tones 👋

Thanks for the questions.

I've dug through most of the linked and associated PRs (closed: #30371 and merged: #30608) and I'm still unclear as to the progress, or barriers.

Margin block support was added in #30608.

@aaronrobertshaw - I'm thinking that this would not necessarily be targeted at Full Site Editor integration, correct?

Margin support is in place and currently working. It did land in the PR you linked #30608. It's also been adopted in a couple of blocks already e.g. Site Tagline and Site Title.

In case you haven't come across them yet, the following pages on block supports and theme.json are pretty handy.

Question: can we enable margin support for all blocks through theme.json and markup, without surfacing the UI for it yet? While not the most obvious interface for building patterns, at least it would be technically unblocked as we refine the UI for it.

As it stands now, block supports can be opted into without turning on the UI. The block.json file allows the block to choose which block support features it wants. The theme.json file allows the theme to decide whether to turn on the UI for that support and allow users to adjust values.

I just tried the following to see if I could get margin support in the Post Title block (on Gutenberg trunk), and it did not work for TwentyTwentyTwo:

This is working alright for me. I checked out the latest on both Gutenberg trunk and the TwentyTwentyTwo theme. I also tested with both "margin": true and "margin": [ "top", "bottom" ]

After opting into margin block support in the Post Title block.json and turning on the UI in the TwentyTwentyTwo theme.json file, the UI appeared in both the block and site editors.

Would it be possible your local environment had the json files cached? Or they weren't reflected within Docker or something?

The snippets you highlighted look correct if they were added in the right locations.

I've created gists for my Post Title block.json and TwentyTwentyTwo theme.json files. Hopefully they help in pinpointing what's amiss.

See: Post Title Block: Custom margin applied to Headings does is not reflected in the front-end #35522

Regarding pasting block markup containing the block support styles, your comments on that issue are correct. The margin support must be opted into for those styles to be generated and applied on the frontend.

After opting into the margin support via the block.json I pasted the following markup into the code view of the block editor and saved the post. The margins are reflected correctly in both the block editor and frontend.

<!-- wp:post-title {"isLink":true,"style":{"spacing":{"margin":{"top":"200px","bottom":"200px"}},"typography":{"fontSize":"clamp(3rem, 6vw, 4rem)"}}} /-->

Here are a couple of quick videos of the margin support working during my testing:

https://user-images.githubusercontent.com/60436221/137421228-18caea6e-d64d-48d3-9dd6-b77fe80a500b.mp4

https://user-images.githubusercontent.com/60436221/137421263-6a285e89-6082-424c-bfa8-238b1e6413a5.mp4

https://user-images.githubusercontent.com/60436221/137421570-183f6b8f-0676-4c60-bf97-391e12fd22de.mp4

Mamaduka commented 3 years ago

As it stands now, block supports can be opted into without turning on the UI.

I didn't know this was possible. It might be worth mentioning in "Block Supports" docs.

@colorful-tones silly question, but did you rebuild the plugin after changing block.json settings?

A few weeks ago, I forgot that you have to rebuild after changing things in block's index.php. Lost an hour debugging a non-existing issue 😅

colorful-tones commented 3 years ago

@aaronrobertshaw @Mamaduka I did not realize I had to run npm run build after. 🤦

Thanks for the helpful links and info and helped me debug further. Margin control is working as expected. 👍

kjellr commented 3 years ago

Regarding pasting block markup containing the block support styles, your comments on that issue are correct. The margin support must be opted into for those styles to be generated and applied on the frontend.

I may be remembering incorrectly, but I think this runs counter to the way other new features have behaved. For example, when we were rolling out line height controls, I was able to use lineHeight in block pattern markup and that value would be respected regardless of whether or not the theme itself opted in.

Either way, I think there's a lot of value in allowing it to be have this way — margin is an essential missing feature for block patterns, and is important to get them appearing consistently across themes.

colorful-tones commented 3 years ago

I feel like this is worth cross-posting, as I already mentioned in #35684

I really like the idea of having preset options for margin/padding, see: Add a selection of preset spacing values to supplement/replace custom padding/margin options #35306.

Similar to Font Size: Small, Medium, Large, Extra-Large. I feel like these values would be a good first step for theme authors and users. Then, a Phase II and further down the line we add ability for users to place custom Margin/Padding (per position: top, left, right, bottom) and incorporate that in to theme.json/FSE.

carolinan commented 3 years ago

Yeah I'm with Kjellr, I might be remembering incorrectly but I think that adding spacing (example) in the HTML file block markup used to work even if the block did not have support for the control.

So where are we at? How do we move forward and complete the steps that are listed for the margin?

  1. Enable the margin control flag in some experimental blocks (FSE blocks)

  2. Decide whether it should be opt-in (with potential smart defaults depending on the container) or opt-out for block authors and enable the flag for all the desired blocks.

aaronrobertshaw commented 3 years ago

I may be remembering incorrectly, but I think this runs counter to the way other new features have behaved.

Towards the end of last year and the start of 2021, there was a wave of new block support features including borders and further typography tools. It led to a decision that all new block support features should require opt-in at both the block and theme levels.

This was aimed towards managing the proliferation of panels and fields within the Inspector Controls and Global Styles sidebars while also allowing us the chance to make considered decisions around which blocks really needed a given support feature.

Unfortunately, I'm struggling to dig up an exact link to reference this decision. I believe it still stands though.

For example, when we were rolling out line height controls, I was able to use lineHeight in block pattern markup and that value would be respected regardless of whether or not the theme itself opted in.

For static blocks, you should still be able to paste in block markup containing the inline styles. That does not require the UI to be enabled by the theme.json or the block to opt into a given block supports' feature. The inline styles within the pasted markup would be treated as per any other inline style as they aren't being generated via the block supports. That markup is saved and rendered faithfully on the frontend.

I believe the issue with the Post Title block is that it is a dynamic block. The block markup only contains the comment including the block's attributes.

<!-- wp:post-title {"style":{"spacing":{"margin":{"top":"50px","right":"50px","bottom":"50px","left":"50px"}}}} /-->

It is then from those attributes that the block is dynamically rendered on the frontend. Without opting into the appropriate support via the block.json the block doesn't know how or if it should translate those style.<feature> attributes into inline styles.

Hopefully, that helps paint a better picture than my last comment 🙂

So where are we at? How do we move forward and complete the steps that are listed for the margin?

In addition to the remaining steps you've outlined, it would probably pay to investigate how the adoption of margin support plays generally with the layout support. It might be that we only wish to enable top and bottom margins in most cases.

I've seen in some PRs opting into margin support conflicts with the layout styles for top-level blocks.

MaggieCabrera commented 3 years ago

Just chiming in to say that although margin controls usually work fine on most blocks I've encountered some that give you errors such as:

<!-- wp:separator {"className":"is-style-wide","style":{"spacing":{"margin":{"bottom":"20px"}}}} -->
<hr class="wp-block-separator is-style-wide" style="margin-bottom:20px"/>
<!-- /wp:separator -->
Screenshot 2021-10-19 at 10 05 19

While showing up correctly in the frontend.

kjellr commented 3 years ago

It is then from those attributes that the block is dynamically rendered on the frontend. Without opting into the appropriate support via the block.json the block doesn't know how or if it should translate those style. attributes into inline styles.

Hopefully, that helps paint a better picture than my last comment 🙂

Yes, definitely — that's helpful. It seems like the issue described in https://github.com/WordPress/gutenberg/issues/35522 is due to this specifically being a dynamic block then. We can fix this by enabling margin controls for that block (https://github.com/WordPress/gutenberg/pull/35684), but is this something we could fix behind the scenes for all dynamic blocks?

It might be that we only wish to enable top and bottom margins in most cases.

Can we try doing this in a PR and see how it feels?

aaronrobertshaw commented 3 years ago

We can fix this by enabling margin controls for that block (#35684),

Just for clarity, at the minimum, we'd only need to opt into the block supports not enable the controls in the UI. Which is what #35684 does.

but is this something we could fix behind the scenes for all dynamic blocks?

It would be a matter of opting into margin support for each of those dynamic blocks. There are some issues still around how a block's margins play with overrides enforced on top-level blocks by the layout support or the new block gap support in some circumstances.

Until those issues are discussed and a decision has been made on what needs doing, I don't think we can just blindly opt-in all dynamic blocks.

An example of the issues around adding margin support can be found in https://github.com/WordPress/gutenberg/pull/33835. These are concerns for both static and dynamic blocks.

Can we try doing this in a PR and see how it feels?

It would certainly add to the discussion. It might be easier to do this on a block by block basis though as the need arises, given the inevitable wrinkles we'll encounter.

carolinan commented 3 years ago

I have no problem creating the small block support PR's for individual blocks, but I'd like there to be a decision about it and for 5.9 and TT2 there is not much time.

apeatling commented 2 years ago

Added this to the design tools project overview, apologies for all the assignments above. https://github.com/orgs/WordPress/projects/10/views/1

ndiego commented 2 years ago

Hi all, looking to continue this discussion. Now that things are much more solidified as we get closer to 5.9, I believe it makes sense to explore adding additional dimension controls (the editor UI) to more block types for post-5.9 releases. I have begun by creating a PR for paragraph blocks https://github.com/WordPress/gutenberg/pull/37300 and here is the related issue https://github.com/WordPress/gutenberg/issues/37299.

I will also be working on PR for the Group block to include both margin and blockGap later this week. Given that theme developers can easily opt-in/out of this functionality in theme.json, I believe this is only enhances the capabilities of the block Editor with very little, if any, downside. It also greatly reduces the need for custom CSS and/or "magic classes" to attain certain theme designs.

mtias commented 2 years ago

Thanks for looking into this followup @ndiego. Out of all the dimension tools, margin is the trickiest to expand, particularly to non-layout blocks, because it's not easy to grasp how it works or how it interacts with adjacent margins. It also makes it difficult to reason about when it comes to boundaries — like deciding where to add a margin within or outside template parts.

Towards 6.0 I'd like us to explore using the Spacer block as a replacement for most margin needs. I know this sounds backwards, but the spacer block is a lot more intuitive for end users to reason about, they can move it separate from the rest of the blocks, they can manipulate it directly, etc. On flex layouts, the spacer can better reflect organization and adapts to vertical or horizontal displays. There's also nothing preventing us from transforming a spacer block into adjacent margins server-side if we want to avoid rendering an empty element in the DOM.

If we do this correctly, I can see a world where margin is left as an advanced tool for creators, more hidden by default.

ndiego commented 2 years ago

Thanks for the thoughtful response @mtias! I completely agree that the spacer block is much more intuitive and is great when users need to add spacing between blocks. The use-case that the spacer block does not solve is removing margin, particularly in blockGap scenarios where margin-top: X is added to every block. Similarly, for paragraphs in particular, most themes and even browser defaults add margin to <p> tags. When designing a layout in the Editor there are many instances where you would want to zero out or modify this margin. I guess if there was even a way to remove all margin and then any spacing could be added with spacer blocks, that would be a happy compromise. I just strongly feel that having to include "magic classes" in a theme to counter applied margin is more of a barrier to users and antithetical to the goal of the Block Editor.

Note that I am operating from the standpoint of wanting to be able to design entirely in the Editor. If a theme's style.css file could be completely empty of custom CSS, that would be my dream state. Regardless of the correct solution to this dimensions issue, and I know that blockGap is being rethought a bit here #37360, I believe it's important to make these controls accessible in the Editor, even if hidden behind a toggle, user preference setting or configurable in theme.json. While we absolutely do not want to overwhelm/confuse newer users, we also want to enable advanced users to harness the full power of the Block Editor. I know this is a hard balance and a difficult problem to solve. I am happy to help in any way that I can!

jasmussen commented 2 years ago

I created #38068 which contains mockups for improving the Image block inspector, notably adopting the general Dimensions panel.