WordPress / gutenberg

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

Additional Block CSS: Selector impossible if attribute is not on block-level but on element-level (as in BEM) #49415

Open porg opened 1 year ago

porg commented 1 year ago

User Goal

As a block theme tweaker (advanced user, designer with CSS knowhow, but no developer):

  1. You add a helper class like .has-outline-dashed on a block instance like a Button block.
  2. You add Additional Block CSS, which shall apply not all all instances of that block but only to block instances which have that helper class added via their Additional CSS Class(es).

TL;DR — My User Experience

If the attribute you want to override corresponds not to the block-level (as in BEM) of your block, but on an element level ...

  1. In Additional Block CSS due to automatic prefixing it is impossible for "advanced users" (designers/tweakers) to formulate a proper CSS selector here.
  2. Then the only way for advanced users is via Global Additional CSS, which is not in the "modular spirit" (modular CSS selectors yes, but all in one long text blob (enqueued all time!), instead of separate Additional CSS per each block (enqueued only on demand).
  3. Professional theme.json developers/modders possibly can achieve that by writing a proper block style with inline custom CSS as JSON values.

Followup

My full testing

1) If I wanted to overwrite the default block style, it works easy:

Global Styles → Blocks → Button → Additional block CSS

border-style: dashed;

2) If I wanted to overwrite a particular block style "Outline", working with the same method fails.

Global Styles → Blocks → Button → Style Variation "Outline"

3) Select a button block instance → block settings → Advanced → Additional CSS Class(es)

a) The only way I managed to select and override it was:

Global Styles → Additional CSS

.has-border-style-dashed .wp-block-button__link {
  border-style: dashed;
}

b) Cleaner but failed attempt: Global Styles → Blocks → Button → Additional block CSS

b1) Additional block CSS:

.has-border-style-dashed {
  border-style: dashed;
}

Outcome in <style id='wp-block-library-inline-css'>

.wp-block-button .wp-block-button__link.has-border-style-dashed {
  border-style: dashed;
}

b2) So I try this now:

.wp-block-button.has-border-style-dashed .wp-block-button__link {
  border-style: dashed;
}

Outcome in wp-block-library-inline-css:

.wp-block-button .wp-block-button__link.wp-block-button.has-border-style-dashed .wp-block-button__link {
    border-style: dashed;
}

b3) Hence I tried to formulate a selector in the spirit of "has a parent with class .has-border-style-dashed":

.has-border-style-dashed:has(.wp-block-button__link) {
  border-style: dashed;
}

Outcome in wp-block-library-inline-css:

  .wp-block-button .wp-block-button__link.has-border-style-dashed:has(.wp-block-button__link) {
      border-style: dashed;
  }
mrfoxtalbot commented 1 year ago

Thank you for the report @porg. I am going to add a couple of screenshots with a simple example of what you describe to make sure I understand:

You add a per-block style: Screen Shot on 2023-03-31 at 17:28:55

But you have some blocks of that type that should be styled different: Screen Shot on 2023-03-31 at 17:27:59

... hence, your only option is to add a global style. Screen Shot on 2023-03-31 at 17:28:30

Were you referring to this?

I also see how trying to target different parts of the block can be very challenging in the case of complex blocks. There are a couple of tips in this article: https://wordpress.org/documentation/article/styles-overview/#applying-custom-css but I see how it is very limiting at the moment.

Is it possible that "Additional Block CSS" gets "a bit smarter" with what it prefixes

Do you have any thoughts on how we could iterate on the "Per block CSS" interface to incorporate more flexibility?

porg commented 1 year ago

Were you referring to this?

Yes, I was referring to what is depicted on your screenshots.

Identified base problem

Do you have any thoughts on how we could iterate on the "Per block CSS" interface to incorporate more flexibility?

Please improve the documentation of this section

https://wordpress.org/documentation/article/styles-overview/#applying-custom-css

I have some ideas how to improve the Additional Block CSS UI.

Though I know the underlying architecture of theme.json and theStyle Engine only on the level of a designer / amateur frontend-dev, but not more. So some ideas may need adaptation or discarding.

Existing solutions

Pure attribute names get wrapped into the appropriate selector. That works fine already. And shall be guaranteed to continue to work, also if we the rest gets added functionality.

Idea

Approach 1 (short term): Single textarea with available selectors visible as click links above the text area.

Approach 2 (long term): From the manifest the UI automatically creates different text areas

I prefer approach 2:

mrfoxtalbot commented 1 year ago

Thank you for the detailed outline. I see pros and cons on both solutions 🤔

Once again I need to resort to @annezazu's expertise 🙏

annezazu commented 1 year ago

👋🏼 Thanks for tagging me in! To take a step back, CSS is intended to be a gap filler with the long term aim for as much as possible to be handled by the site editor itself. I'm sharing that to ensure the wider context is known for how and why custom CSS was added. Ideally, in the future, you won't need to rely on this to create the customizations you want. Of note, there are these follow up items:

Add inline code completion and linting to input box similar to customizer. Provide list of blocks that have had custom CSS applied at the block level.

Professional theme.json developers/modders possibly can achieve that by writing a proper block style with inline custom CSS as JSON values.

Generally speaking, this is what's currently possible. In the future though, there's work to be done to both expand styling options through things like https://github.com/WordPress/gutenberg/issues/40966 and thoughts around having a way to save a custom CSS class as a block variation: https://github.com/WordPress/gutenberg/issues/7551 I might comment on that latter issue personally.

@glendaviesnz I want to get your thoughts here, particularly around why there isn't a custom CSS field for block variations. That felt a bit surprising but I imagine there might be some technical limitations here.

porg commented 1 year ago

@annezazu thanks for providing the bigger picture and long term goals.

  1. My approach 1 to make the BEM selector accessible would be aided by #47945 if it would also complete the block__element classes.
    • Though as said, this is just "more of the same" (like Additional CSS in the Customizer of classic themes) compared to approach 2.
  2. My approach 2 to Reflect the Modular CSS nature also in the UI likely gets more possible with #40966 which can serve as a manifest of Elements (as in BEM) too and as such you could then in the UI particularly style certain Elements of a Block without dealing CSS selectors.
  3. As you seem to have knowhow in that subject domain: Could you please amend the documentation with the status quo on Custom CSS particularly to answer these aspects I inquired ?
annezazu commented 1 year ago

As you seem to have knowhow in that subject domain: Could you please amend the documentation with the status quo on Custom CSS particularly to answer https://github.com/WordPress/gutenberg/issues/49415#issuecomment-1495893626:~:text=Please%20improve%20the%20documentation%20of%20this%20section ?

Ironically, I did an initial sweep of that doc right before 6.2 to help out that team: https://github.com/WordPress/Documentation-Issue-Tracker/issues/675#issuecomment-1486026994 and then @mrfoxtalbot and co helped flesh it out after the fact. Here's an issue to address this: https://github.com/WordPress/Documentation-Issue-Tracker/issues/747 If I can, I'll loop back personally.

glendaviesnz commented 1 year ago

@glendaviesnz I want to get your thoughts here, particularly around why there isn't a custom CSS field for block variations. That felt a bit surprising but I imagine there might be some technical limitations here.

I didn't have much involvement in the block-level CSS sorry, I mostly handled the global level, @carolinan may have more of the background on this.

carolinan commented 1 year ago

The per-block custom CSS field is not intended to target these additional selectors. It is intended to be as simple as possible for end users, not developers.

  1. Use the global CSS field when you are not targeting a block. I read in the issue why you don't want to, but that is its purpose.
  2. Use the interface in the Styles sidebar to update the style variation, not custom CSS.
carolinan commented 1 year ago

About the documentation, the article you linked to is for users, not developers, so I do strongly disagree that it should cover topics like what post-processing is used.

porg commented 1 year ago

So I summarize:

  1. Styling in block themes is primarily done in the Editor UI. Convenient!
  2. Custom CSS is intended as a workaround to achieve some things the Editor UI does not yet support. But beware that this custom CSS is limited to declare attribute: values; only and not targeting particular elements of a block with CSS selectors (the prefixing/suffixing is a blackbox, which one must not know and which will remain undocumented).
  3. Selecting particular elements and styling them should be in block specific CSS files which use wp_enqueue_block_style().

So I will use mostly 1, skip 2 due its very limited nature, and fall back to 3 in the few cases where really needed.

carolinan commented 1 year ago

A user should not be required to know what a prefix is. They should trust that the CSS is added to the block they selected in the menu: and it is.

porg commented 1 year ago

Exactly that expectation was the start of my journey!

mrfoxtalbot commented 1 year ago

I have the impression that we are discussing two things in paralell here:

Regarding the first item, I opened a separate thread here https://github.com/WordPress/gutenberg/issues/49531 If we do not want to make the end-user documentation excessively complicated, we should at the very least include a link to the relevant developer article where this is covered. I discuss the need to cross reference developer and end-user documentation with @juanmaguitar a while back and this is a perfect example.

About the second item, I do not see a clear path to fix this without going a very complex rabbit hole. I would recommend polishing the current interface and gather feedback from users to understand how useful per-block CSS really is.

annezazu commented 1 year ago

Wanted to cross reference this issue too as it relates to this conversation around "adding a custom CSS field to block style variations":

https://github.com/WordPress/gutenberg/issues/49602

carolinan commented 1 year ago

These are two separate issues:

Put "border-style: dashed;" into a "custom block CSS" and instead of overriding the visible border's style (which was solid) I got nothing, and when using "border: 2px dashed red;" I got another border around the existing visible border. Why: Because the block author had applied the border not on the block level but on the element level (some deeper nested element). Only from this arose the need for an element-level CSS selector.

I am not able to reproduce this, the second issue. Can you provide the full details, including which block you are using and wether or not you were trying to override a style variation here?

carolinan commented 1 year ago

If I understand correctly from discussions in related issues, the plan now is to add a CSS input field to the style variation UI. https://github.com/WordPress/gutenberg/issues/49602