Gutenberg: Allow blocks to support multiple block styles

Created on 24 Mar 2019  路  29Comments  路  Source: WordPress/gutenberg

Related: https://github.com/WordPress/gutenberg/issues/7551, #11582

I'd like to propose that blocks can optionally support multiple block styles at the same time. Currently plugins/themes can add other styles, but the user has to select Style1 OR Style2 OR Style3 etc. I'd like to see the possibility that a user can select Style1 AND Style2 AND Style3 etc.

Take for example the table block. Currently it supports a basic no style default or striped rows. A plugin could add a styles for a header row and for a header column. The user should be able to choose to have a combination of header row, column and striped rows.

This wouldn't be appropriate for all blocks, so there would have to be some kind of 'supports' definition in the block registration.

(The table block may not be the most appropriate example because the table markup will need modification instead of simply adding more classes; this is something the plugin would have to sort out)

The alternative is the plugin adding a separate panel in the sidebar most likely using checkboxes to turn on/off header rows etc, but IMO this would be a worse UX than using block style variations.

Needs Dev [Feature] Style Variations [Priority] Low

Most helpful comment

@richrd: Well, as an existing example in Gutenberg the user can already select bad (low contrast/readbility) foreground and background color-combinations and Gutenberg doesn't prevent the user from doing that. Instead, it just shows a notice/warning.

All 29 comments

I support this feature request wholeheartedly. Much needed feature especially for static blocks. Right now we end-up adding tonnes of block styles to cover combination of cascading styles.
TinyMCE (styles selection control) does it already if you look for inspiration how to tackle this.

Much needed feature especially for static blocks. Right now we end-up adding tonnes of block styles to cover combination of cascading styles.

@QuietNoise can you add some more detail on your use case? I'm sure it will be valuable info for anyone who looks at implementing this.

I'm not sure my example with the table block is actually that relevant, especially now there is built in support for table headers, and fundamentally it's changing the table structure, not just the style. Although it would still be nice to have the preview UX like you get with block styles. @mapk it would good to get your thoughts as you have been working on the table block.

Use cases are any scenarios where you need to combine different styles but also allowing admins to apply each style individually.
Simple example would be to manipulate how H1 tag is styled. For example it might be in in

  • in regular font, bold font, light or black font,
  • it might be with regular letter spacing, with extra letter spacing
  • it might have shadow, border, background image,
    or any combination of the above. This gives us 4 x 2 x 3 = 24 style options to accommodate all combinations. Quite a hindrance to ask admins to scroll through that. Add one more option would make combinations go to 48 and so on.

Alternative would to add custom controls to Heading control but as far as my experience goes it would introduce the block validation nightmare for all existing posts (due to it being a static block). Not good either.

@mapk it would good to get your thoughts as you have been working on the table block.

Thanks for the ping, @ChemicalSailor. It would be great to have various styles as settings that can be toggled on/off to get the right combination. We're working on adding more base styles to blocks and keeping here: https://github.com/WordPress/gutenberg/issues/15899, https://github.com/WordPress/gutenberg/issues/8171.

It's taking time to figure out the correct amount features and which ones we should offer as individual styles. With Gutenberg, we're going to lean more toward _less options_ right now. We'll offer style variations to help supplement that. A long list of style options can quickly become overwhelming. Ultimately we _should_ be relying on the themes to provide the variety of style options.

I would definitely support allowing for multiple styles assigned to one block. The examples provided by QuiteNoise are perfect. I, for example, have a site that has an alternate body style font, so I have added that as a block style that I can apply to paragraphs. As the same time, I have a block styles that assign a max-width for paragraphs, it would be nice to assign both styles at the same time so I have max-width and alternate body style, without the need to create another block style for max with AND alternate body style.

I hope this can be progressed into reality because as @QuietNoise references, if we have blocks that could do with multiple combinations of styles it is much easier on the end-client to be able to toggle those on and off as needed rather than to have specified styles for every, exponentially building, combination.

A use case from work I'm doing today, adding styles to a "group" block:

  • Styles to constrain the width and padding of the group (4 options)
  • Styles to change the top and bottom padding of that section (2 options)
  • Styles to change the background of the group (5 options)
  • Styles to add a decorative divider (1 option, if not counting the "off" state)

This becomes unmanageable very quickly, and so I will have to continue with only using css classes in the advanced options which, unfortunately, are not very friendly for the end client.

Ultimately this doesn't need to be something that happens as default but would be greatly appreciated if there was at least the option of creating groups of styles as a developer that would form their own, distinct, groups of styles to pick from. Something like (rough example)...

wp.blocks.registerBlockStyle( 'core/group', {
    group: 'Padding styles',
    styles: { [
        name: 'large-vertical-padding',
        label: 'Maximum padding'
    ], [
        name: 'small-vertical-padding',
        label: 'Minimum padding'
    ] }
} );

Yes, adding stylistic options to a block quickly results in very large numbers of block styles for all combinations. My current workaround is to let the theme add block options that just toggle some has- CSS classes. This requires to add JavaScript/React-code that also break sometimes. Combinable block styles are much better because the theme designer can just get the job done and doesn't have to add custom UI stuff.

Additionally, it would make sense to add the ability to group block styles, like it is possible with blocks because the number of block styles for just one particular block (notably group, heading, paragraph) can grow substantially.

I agree with this solution. I added my own custom testimonial block and i need to add so many style variants as i can only pick one style. @niaccurshi suggested a very good solution, this way we can create a style group, let's say 'Border Style' and from there you can select either a dotted border or straight line. And add another style group for 'Background Style' where the user can select a pre-defined background. At the moment you need to create a style with let's say dotted border with blue background, dotted border with green background etc.

+1
ran up against this limitation today

I also have a need for this. I am adding block styles through my theme, using options I don't want to include in my other theme, and my block has two border styles and six background styles. It would be much easier to code and maintain if these could be grouped into two different block style groups, rather than adding one block style declaration with 12 block styles.

Yes, the cascading nature of CSS would be something very useful here!

This what we need, for example the button:
I have options like simple, tiny, icon etc... that are all cumulative of course.
I add those via custom class. If i could provide the editor with a UI to choose these classes! It would be a dream comes true.

+1! HTML and CSS already support multiple classes per element since the beginning of the web. The UI for block style selection has to be adjusted from being radio-button like to checkbox-button like and toggle the associated is-style- classes.

If there was someone to write a PR for this, would it potentially be accepted as a feature?

@richard: Yes! This would be great. I am not good enough with React + Gutenberg to write something like this.

+1 not so much for myself this would be a big roadblock for anyone who wishes to atomic CSS in Gutenberg.

I just setup a development environment and I'm taking a look at how this could/should be done. I assume this is where most of the changes need to happen https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/block-styles/index.js

Anyone got any pointers on what to look out for as I'm not yet familiar with the gutenberg code base?
What things might break and need fixing if a block has multiple active styles?

My 2 cts: There is a preview selection UI thing used for the block style selection. Does that UI control already supports the selection of multiple items?

@strarsis Excellent point! I bet it doesn't but I'm not sure it would even be logical that way. I think each style preview should only show what that specific style does to the block. That way they only represent what they do on their own. The combined effect of multiple block styles should be shown in the editor but IMO not in the block style preview.

I implemented support for multiple styles in #21714 . It doesn't separate styles into groups, simply just allows selecting multiple block styles. I think creating style groups could be a separate enhancement but that involves a lot more work and likely involves a breaking change for the style registration API.

EDIT: multiple block styles can be tested here: http://gutenberg.run/21714

How do we indicate styles that will not work together?
For example if there is more than one border style, or as in TwentyTwenty, more than one style for the separator block.

All selected styles have a check mark, but only one style is showing.

That's a good question. I'm not sure what the solution to that should ultimately be. Many of such conflicting styles should be self evident, such as multiple border styles, but other combinations that don't work together can be less obvious.

Still allowing many conflicting styles to be selected could be problematic. On the other hand we have no control over what sort of block styles various themes and plugins will add, so we can't reliably prevent them from conflicting. The grouping mechanism that @niaccurshi suggested would be nice but would only work within one theme/plugin, not accross all of them.

Any thoughts @mapk ?

@richrd: Well, as an existing example in Gutenberg the user can already select bad (low contrast/readbility) foreground and background color-combinations and Gutenberg doesn't prevent the user from doing that. Instead, it just shows a notice/warning.

A lot has changed since I first created this issue. I think there is still merit in this idea, I really like the way block styles give you a little preview of what the block will look like, and the simplicity of it just adding a class to the block actually gives a very easy entry point to customising a block.

However, I'm leaning towards block styles becoming more of 'block presets' feature - something that sets one _or more_ options in one go, kind of like the patterns API but in the local scope of the block (the presets could even be grouped - light, dark etc). A block style is really a combination of one or more features, so I think each feature should have an individual control (e.g a toggle) with associated styling where appropriate. There is some discussion in https://github.com/WordPress/gutenberg/issues/19659 which I think is relevant here.

Thinking out loud - perhaps there is scope to have both block styles and block presets as two different tabs of the same panel. I suspect it wouldn't make for very good UX, but thought I'd throw it out for discussion.

A rough, not very well thought out, way this might work:

  • There is an API for registering block features, similar to the current block styles API
  • The developer provides a feature name, the type of control for automatic rendering (binary, slider, colour etc), the permissible values, and a callback for implementing
  • Gutenberg can provide some ready-made callbacks, such as for adding a class to the block
  • More advanced features would be implemented by the developer using components, but the feature still has to be registered with it's permissible values.
  • There is an API for registering block presets, possibly JSON-like which specifies a name for the preset, the features it uses and their values.
  • The presets can be part of the block definition or added by a theme, or even saved by the user.

I'm sure a lot of this overlaps with patterns, reusable blocks, templates, global styles and whatever else is being cooked up at the moment. Now it's late, so I will stop whittering on and see what other peoples thoughts are!

We now have block variations which allow for differently styled blocks to be considered and added to the Inserter. I don't think this perfectly solves this issue but worth taking a look at.

https://github.com/WordPress/gutenberg/blob/master/docs/designers-developers/developers/block-api/block-registration.md#variations-optional

@mapk: Is this already supported in the latest Gutenberg plugin?
Can those variations also be registered using the WordPress PHP API?

@strarsis yes it's in the plugin. I'm not sure on the other question.

@gziolo, can you help answer this above?

Is this already supported in the latest Gutenberg plugin?

It's both in the plugin and WordPress core starting from 5.4 release.

Can those variations also be registered using the WordPress PHP API?

It's all JavaScript-based for now. There was a dev note posted on WordPress.org blog: https://make.wordpress.org/core/2020/02/27/introduce-block-variations-api/. You can define block variations as part of the registerBlockType call or use it separately with wp.blockregisterBlockVariation function.

Is there currently an easy way to define styling options for blocks that the editor can choose and allow the editor to apply multiple styles/classes to a block at once?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wpalchemist picture wpalchemist  路  3Comments

franz-josef-kaiser picture franz-josef-kaiser  路  3Comments

ellatrix picture ellatrix  路  3Comments

moorscode picture moorscode  路  3Comments

aduth picture aduth  路  3Comments