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

Built-in CSS settings controllers (or standard API) #6651

Closed
rchipka opened this issue May 9, 2018 · 5 comments
Closed

Built-in CSS settings controllers (or standard API) #6651

rchipka opened this issue May 9, 2018 · 5 comments
Labels
[Type] Enhancement A suggestion for improvement.

Comments

@rchipka
Copy link

rchipka commented May 9, 2018

As developers begin to create custom blocks we're going to see a lot of repeating patterns inside the block settings.

Settings like text color/align, box-shadow, background color/image, border settings, float settings, position settings, transforms, padding, margins, etc. will all be implemented many times over, each with a different UI/UX or in a different location.

Different implementations of the exact same property configuration controller might be buggy or lack certain features/functionality, even though the underlying CSS property has a well-known set of possible values according to the web standards.

Multiple implementations will also result in multiple techniques for injecting the styles, making style overrides an unpredictable headache for a developer.

I think it's important that Gutenberg take some level of ownership over user-defined CSS property control early on so that we don't end up with a buggy, hodgepodge mess in the future.

If a feature is missing from a CSS property controller, developers would patch/update built-in Gutenberg functionality instead of rolling their own, which will benefit everyone once the feature is added.

I think we should come up with a comprehensive user-friendly built-in solution to handle simple CSS configuration options which are generally applicable to all blocks.

But not rendered as inline styles

If the user-defined style settings are injected directly onto the container via the style attribute, it would be difficult for a developer to override these styles and force them to resort to !important.

Instead a class should be added to the block's container and the styles for that post should be injected into the post content inside a <style> tag.

The contents of the <style> tag would be generated by looking at all of the custom style attribute settings for each block, grouping the matching ones, and creating a class based on each unique style attribute value.

The class name would be a hash of the CSS attribute name and value, so if someone sets a block's text color to red, the block might get a class like .color-10b06ba962bec30.

The benefit of the hash is that it allows us to uniquely represent complex CSS attribute values using identifier-safe characters, and it also discourages developers from targeting the class name directly (as it could be subject to change).

An extra class like .gb-block should be added so that we can target the element using a slightly higher specificity.

The resulting <style> tag would contain:

.gb-block.color-10b06ba962bec30 {
  color: red;
}

This way the developer can easily override styles as long as they target the element with a greater specificity (i.e. with a tag name and a class name, or with an ID).

This also means that existing styles with a high specificity can't be overridden by the Gutenberg editor, which is good.

If an existing style has a high specificity and should also be able to be overridden by the Gutenberg editor, the developer should update the CSS selector so that the specificity is lower (i.e. just target the element with a single class name) or put those styles in the footer.

If not a built-in CSS settings UI...

Then the addition of configurable CSS attributes should be standardized as a special prop on each component so that Gutenberg can take care of injecting the styles/classes in an automated, consistent, and maintainable way.

If there were a standardized prop that CSS settings should go into, then these styles would be easily accessible/editable later, should Gutenberg (or a third party) want to override them or implement an advanced CSS settings editor for all blocks.

@rchipka rchipka changed the title Built-in CSS settings panel (or standard API) Built-in CSS settings controllers (or standard API) May 9, 2018
@rchipka
Copy link
Author

rchipka commented May 23, 2018

An example of this would be #6618, which adds a standard FontSizePicker component.

@jorgefilipecosta
Copy link
Member

Hi @rchipka,
Thank you for creating this issue and submitting an idea to remove inline styles.
The usage of the hash approach was tried before in #3669.
At the time I think the approach was not used because the usage of classes for the default colors removes inline styles from most of the cases (the most used colors are expected to be the default or the ones set by the theme).
And now we allow themes to disable colors besides the ones they configured so if a theme does not want the inline styles to be set they can disable the custom colors.

@rchipka
Copy link
Author

rchipka commented May 23, 2018

@jorgefilipecosta Thanks for pointing #3669 out to me. I didn't know there was already a PR so similar to the implementation suggested in this issue.

The hash concept has many benefits and I think it should still be strongly considered. We want unique identifiers, concise inline classes, and we want to discourage targeting these classes directly.

If I understand correctly, the issue was that the CSS selectors in the default style sheet targeted the inline styles with the same specificity, causing them to be difficult to override.

With my approach, which adds a .wp-block class, we can target our defaults to .wp-block and target our inline styles to .wp-block.style-%hash%.

This will cause inline styles to always have a higher-than-default specificity and allows a theme to easily override them.

An even better approach might be to add a property name class too, so we can target .wp-block-color.wp-color-%hash%, then theme developers could easily override any custom colors by targeting .wp-block-color instead of the value-specific class name.

A theme's configuration of default colors should be handled in the exact same way for consistency.

@rchipka
Copy link
Author

rchipka commented May 23, 2018

In CSS, a developer should be discouraged from targeting a block by some styling attribute value and instead should target a block by the styling property name.

If a theme developer is concerned with restricting the style property values of a block, then it should be handled on the configuration/controller side of things (and not in the CSS).

These restrictions could also be easily defined for any CSS property (like a theme's block color restrictions) if we implement the main concern of this issue, which is creating a standard interface for all things CSS.

@earnjam earnjam added the [Type] Enhancement A suggestion for improvement. label Oct 30, 2018
@mtias
Copy link
Member

mtias commented Nov 17, 2019

This is definitely an important area as customization tools and theme support expand for block style attributes, but let's fold it together with #9534 as it has a bit of a broader view.

@mtias mtias closed this as completed Nov 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

4 participants