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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃枍Global Style System #19611

Open
ItsJonQ opened this issue Jan 13, 2020 · 41 comments
Open

馃枍Global Style System #19611

ItsJonQ opened this issue Jan 13, 2020 · 41 comments

Comments

@ItsJonQ
Copy link
Contributor

@ItsJonQ ItsJonQ commented Jan 13, 2020

馃憢 Hello everyone!

First off, Happy New Year at all! I hope you all had the happiest of holidays.

I'd like to expand upon the original "Block Style System" issue @mtias started at #9534.

I originally proposed a concept last year in November. Even before then, the thread has evolved a lot, with a lot of exciting ideas and feedback.

This Github issue is also very much related to #19255. Serving as the technical complementary piece to the Global Styles / FSE design work that is happening!

Recap

The idea is to provide a unified system for Gutenberg blocks (core + 3rd party) and themes to work well with each other. They also have to understand and respect user overrides. These defined styles can be applied globally throughout the user's site (e.g. Declaring font scale, or colors, or how all Buttons look).

At the moment, Gutenberg only supports style customization at the per-block level. So updating a Button in one post, will not retroactively update Buttons on other pages.

Terminology

"Builders" - People who create things to help create content. Examples: Block creators, themers, plugin authors.
"Users" - People who create content.
"Backend" - Gutenberg's Editor. What the User uses to create content.
"Frontend" - Rendered site. What the User sees.


Demo

Screen Capture on 2020-01-13 at 16-33-31

I think a good way to start this one would be an interactive demo!
The demo can be found here:

馃憠https://9w53w.csb.app/

CodeSandbox (for code/preview):
https://codesandbox.io/s/github/itsjonq/wp-gs

Github Repo for source code:
https://github.com/itsjonq/wp-gs

In the demo, click on "Toggle Inspector" to see the style configs (outlined below)

To simulate the "loading" of a theme, go to:
https://codesandbox.io/s/github/itsjonq/wp-gs

Uncomment the following line:

//import "./load-theme";

And click the refresh icon in the browser preview (right)


Note: The code I have is mostly prototype code. Code to discover and realize the various moving pieces, and how they all fit together. I wrote it outside the context of Gutenberg to make iterations/builds faster. It also enabled me to publish it onto CodeSandbox for live code/preview purposes.


The Parts

01-parts

For my proposal, global styles is a system of setting and rendering a (giant) config. These mechanisms can be represented by 5 parts (above).

  1. Default theme styles
  2. Theme styles (e.g. Twenty Twenty)
  3. User styles
  4. Merged styles
  5. CSS Variable rendering

1. Default Theme Styles

These determine the default properties how the sites/blocks will render. These are the bare-bone essentials for rendering site's front-end. They are not opinionless, but very close to being so.

They also help establish structure when it comes to adding/updating values. For example, colors and fontSizes will always exist.

The current structure follows the semantics outlined by Theme UI spec, which is a (mostly React) based theming convention that's gaining in popularity. Of course, we don't have to use this schema :).

What qualifies as default styles?

Some core colours and typography would be a great start.

Gutenberg's core blocks have style opinions. They kind of have to. For certain blocks to be functional, they need some styling in order to work correctly on the front-end. These would qualify for default styles as well.

2. Theme styles

In the future, once Global Styles x Gutenberg is in place, one way a Gutenberg supported theme may want to customize blocks would be to include a theme.json file. The key/value pairs follow the same schema.

The .json file works similarly to the current add_theme_support() php function, but I feel like it's easier to declare.

These will add to/override the values from default styles.

3. User styles

The ability for the user to customize these values would be presented in the Global Styles editor/tool interface. The concept is very similar to the customizer.

The experience of this can be seen in my demo.

Global Styles x Blocks

In addition to updating colors or typography, (in the future) this interface can update (style based) attributes for blocks. Using a registration system (like how core/custom Gutenberg blocks are registered), block style attributes can appear in this global editing experience.

Hierarchy

User styles overrides theme styles.
Theme styles overrides defaults.

Leading us to...

4. "Merged" styles

This is the consolidation of User > Theme > Default styles. These are consolidated and enhanced to prepare the values to be rendered.

Enhanced with "plugins"

03-transforms

A mechanism I built into the system allows for Builders to modify/enhance values from the style config. For example, in the above screenshot, the original single text value has become an array of various color shades. This is applied to any color value under the colors key.

With my prototype, this is how a plugin may look like:
https://github.com/ItsJonQ/wp-gs/blob/master/src/global-styles/plugins/color-scheme-plugin.js

By interpolating/enhancing values, we can improve and simplify the values to be rendered with CSS

5. CSS Variable rendering

Finally, the defined and enhanced styles are rendered via CSS variables. The last stage of the system flattens and transforms the data into CSS variables.


Global Styles x Blocks

For blocks to start using global styles, their CSS will need to be refactored to use the CSS variables outputted by system.

Example:

.wp-block-button {
	box-sizing: border-box;
	border: 1px solid var(--wp-gs-color-primary-dark20);
	display: inline-flex;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
		"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
		"Helvetica Neue", sans-serif;
	line-height: 1.2;
	font-weight: bold;
	text-decoration: none;
	cursor: pointer;

	background-color: var(--wp-gs-button-backgroundColor);
	border-radius: var(--wp-gs-button-borderRadius);
	border-width: var(--wp-gs-button-borderSize);
	box-shadow: var(--wp-gs-button-dropShadow);
	color: var(--wp-gs-button-textColor);
	padding: var(--wp-gs-button-padding);
}

Global Styles x Themes

With this system, the overhead of styling blocks outputted from Gutenberg has been tremendously reduced. By leveraging a theme.json file, the Themer has a lot of controls over the visuals of the WordPress x Gutenberg. Better yet, they will be able to confidently adjust the visuals of custom blocks as well (assuming they're using global styles).


Rendering on the Front End

Similar to how Gutenberg blocks are saved/rendered, we can save and store the outputted HTML from Global Styles. This HTML contains the generated variables, which can be injected into the head via PHP, meaning there's not variable/style consolidation required on load. It's already been done.

Any change made to global styles will trigger a save, following the mechanism that Gutenberg has for its blocks.

This style generation mechanism needs to be triggered regardless if Gutenberg is loaded or not. For example:

A user installs and opens WordPress for the very first time. They download and activate a custom theme (with global styles support). They view their site, without having written a page/post yet. The site should render correctly.


Customizing rendering of "sections"

Since UI on the front-end will be rendered with CSS Variables, we will be able to customize how blocks render in "sections" in a robust manner.

For example, your site is white with black text, but your sidebar is black with white text.

Certain blocks that get added to your sidebar need to adjust their colors to be readable. From a technical standpoint, this can now be done by inline styling a CSS variable, example:

<div class="wp-sidebar-block" style="--wp-gs-colors-text: white;">
  ...
</div>

For those who made it to the end of this very long post, thank you!

馃檹 馃檹 馃檹 馃檹

There are a lot of moving parts for this idea. We're still very early days. I'm sure there are a lot of nuances and edge cases that I haven't thought of yet. Which is why I'd love to hear from everyone!

Thoughts and feedback are 馃挴 welcome.

Thank you so much for your time!

@tellthemachines

This comment has been minimized.

Copy link
Contributor

@tellthemachines tellthemachines commented Jan 14, 2020

Thanks for posting this! Very excited for the possibilities 馃槏

These defined styles can be applied globally throughout the user's site (e.g. Declaring font scale, or colors, or how all Buttons look).

At the moment, Gutenberg only supports style customization at the per-block level. So updating a Button in one post, will not retroactively update Buttons on other pages.

To clarify, will users be able to update the color on all the buttons, or the font-size on all the paragraphs, through the editor UI? And if so, will they still be able to make adjustments on a per-block basis?

Similar to how Gutenberg blocks are saved/rendered, we can save and store the outputted HTML from Global Styles. This HTML contains the generated variables, which can be injected into the head via PHP, meaning there's not variable/style consolidation required on load. It's already been done.

Would there be a good alternative to using CSS variables on the front end? The concern here is that any website using WP would stop working on IE. Even if WP as a project decides to stop supporting IE (which is likely at some point in the future), if users can no longer build IE-compatible websites with it that could be a huge problem for any government or other official institution that uses WP.

@SchneiderSam

This comment has been minimized.

Copy link

@SchneiderSam SchneiderSam commented Jan 14, 2020

So cool and can't wait for this feature!

@nerrad

This comment has been minimized.

Copy link
Contributor

@nerrad nerrad commented Jan 14, 2020

Would there be a good alternative to using CSS variables on the front end? The concern here is that any website using WP would stop working on IE. Even if WP as a project decides to stop supporting IE (which is likely at some point in the future), if users can no longer build IE-compatible websites with it that could be a huge problem for any government or other official institution that uses WP.

This is an important point and unfortunate reality. It'd be nice if we could get some hard data on exactly how much of an impact this would have though.

With that said, I wonder if something like https://www.npmjs.com/package/postcss-css-variables would be something that could be used in the build process to assist with the final css. Maybe there could be a plugin for WP that would do on the fly processing of the css output to transpile (using that package) to a IE friendly output that could then be used by those sites needing it?

@youknowriad youknowriad removed the [Type] RFC label Jan 15, 2020
@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 15, 2020

@tellthemachines + @nerrad Thanks for your feedback! I agree, the concern with CSS Variables and the lack of (older) browser support is very real.

Maybe there could be a plugin for WP that would do on the fly processing of the css output to transpile (using that package) to a IE friendly output that could then be used by those sites needing it?

That would be interesting! Something server-side to reduce the need for a JS-based polyfill fill client side.

I'm really hoping we can use CSS Variables for the styling mechanism for this project. Either using a technique like what @nerrad suggested, and pony/polyfill, or something else.


With that said, I don't think CSS variables the piece that makes/breaks global styles.

I think the most critical piece, would be creating the system that allows Themes, Blocks, and user Customizations (globals + one-offs) to play nicely with each other. A system that reduces complexity and overhead for Block Developers and Themers. This will then provide a more cohesive experience for users. Perhaps a user who customizes things often or tries using different custom blocks from different block authors.

Focusing on that user experience is, I think, ultimately a big part of the Gutenberg experience :). I'm reminded of that by a comment @nerrad wrote (link below), where he eloquently emphasized the importance of user experience within WordPress.

#16384 (comment)

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 15, 2020

馃憢Hallooo all!

I have an update. I've been working with @karmatosed to figure out the flows for how global styles will work in the context of Full Site editing, as well as with themes and blocks.

I've created a prototype that demonstrates the flow + hierarchy of how global styles will work with blocks and themes

I recorded a screencast that goes over prototype + concepts:

馃摴 Video
https://www.loom.com/share/73f721797f524dfeb2c3a222e9e24561

馃檶 Demo
https://yvz8y.csb.app/#/v2/post


Too Long, Didn't Watch

No worries! I'll try to summarize <3

The style hierarchy can be represented by this pyramid:

Screen Shot 2020-01-15 at 4 38 43 PM

Core: Base styles that come with Gutenberg/global styling system
Theme: Custom styles defined by a theme
Global: Custom styles applied by the user, intended for the entire site
Document: Custom styles applied by the user, intended for certain pages/template parts (FSE)
Block: Custom styles applied by the user, for individual blocks

In the above pyramid, we can see that the Core styles (black text), has persisted it's way up, as no styles were defined on any other layer. Resulting in something that looks like this:

Screen Shot 2020-01-15 at 4 43 43 PM

If we switch the theme to Blue, the blue theme's custom styles (in this case, blue text), will override core's styles. It will persist upwards as no other custom styles are applied

Screen Shot 2020-01-15 at 4 38 48 PM

Resulting in a site that looks like this:

Screen Shot 2020-01-15 at 4 44 53 PM

If we apply a global style, it will override the theme's:

Screen Shot 2020-01-15 at 4 39 01 PM

If we apply a document style, it will override global's (if applicable):

Screen Shot 2020-01-15 at 4 39 12 PM

Lastly, if we customize a specific block, it will override the other layers:

Screen Shot 2020-01-15 at 4 39 21 PM

Resulting in:
Screen Shot 2020-01-15 at 4 39 33 PM


We will also have the ability to "reset" or remove custom settings. In this example, let's say the user removes their global styles setting. However, the document style remains, which renders like so:

Screen Shot 2020-01-15 at 4 39 51 PM


Theme Switching

Global + Document styles are coupled with the theme. You can think of them as user theme configs. If the user switches to another theme, it will apply that themes' global + document styles.

Let's say the user has customized their existing theme ("blue") a bunch.
Let's say the user installs a brand new theme ("red"). A theme they just downloaded.

Once they switch, the global + document styles will be reset.

The reason is because they've never customized anything on the "red" theme yet.

Switching back to "blue", will restore their previous global/document styles.

Screen Capture on 2020-01-15 at 16-51-17


TLDR (Too Long, Didn't read)

  • There's a style hierarchy - Core, Theme, Global, Document, Block
  • Global, Document, Block styles are customized by the user
  • Global + Document styles are associated with a theme
  • This allows for theme switching with minimized side effects

Thank you so much for your time! Thoughts + feedback welcome 馃檶

@aristath

This comment has been minimized.

Copy link

@aristath aristath commented Jan 16, 2020

Excellent breakdown, thanks @ItsJonQ!
Isn't Theme & Global pretty much the same thing though?
I mean thinking of what the future of themes might look like, most themes will probably switch from using the customizer to the global-styles system. Settings that now exist in the customizer will be migrated to this system... They can be thought of as the same thing. We can call them "theme" if the theme uses the customizer and "global" if the theme is using the global-styles system, but it's one or the other, no theme will have the same settings both in the customizer & the global-styles editor because there's no reason to do so, there's no benefit in having both.

Regarding the css-vars: I wouldn't worry about IE support... Parsing the content and replacing css-vars with their values won't be difficult to do in PHP.
IMO we can work with css-vars and a simple filter that does search-and-replace server-side on the PHP side of things can work perfectly fine.

@nosolosw

This comment has been minimized.

Copy link
Member

@nosolosw nosolosw commented Jan 16, 2020

Would there be a good alternative to using CSS variables on the front end? The concern here is that any website using WP would stop working on IE.

This is solvable by creating a fallback such as:

p {
    font-size: 16px; // Fallback for IE.
    font-size: var( --font-size-paragraph );
}

It can be automated using https://www.npmjs.com/package/postcss-custom-properties Another approach would be a SASS mixin, although the CSS gets muddy (you have to write @include font-size-mixin( 16px ); which is a bit unnatural. There are options to overcome older web citizens, so CSS custom properties are fine to use.

@kraftner

This comment has been minimized.

Copy link

@kraftner kraftner commented Jan 16, 2020

I've just read through all of #9534 and this issue and I'd like to bring up a perspective that hasn't been mentioned at all yet as far as I've read.

Users Styling vs. Builders Styling

All of the above is mostly concerned with maximum flexibility and control for "Users", offering them a solid base in the form of core and theme styling but giving them the final say and a broad array of capabilities to alter the styling of a website.

This is a valid and quite surely the most common use case, but I am coming from a totally different (not to say opposite) direction: Sites where there are multiple users as well as a clear separation between designers, developers and editors. In that setting users specifically should have no or at least very little control over the styling of the site. They create semantic content using the (heavily moderated) set of blocks leaving the styling in the hands of designers and developers. Think separation of concerns between content and layout/styling for the sake of consistency.

In that situation the "Style Hierarchy" mentioned above is not what one needs or wants since styling should solely be defined by the theme. Changing anything on the Global, Document and Block Levels shouldn't be possible. And even the Core Styling might be too opinionated. Instead the Theme Level should be the first, last and only one to decide how everything is styled.

Shouldn't we just embrace users being in control?

Generally yes, but maybe not here. Let's see why.

If a website is based on a corporate design, a styleguide or any other well thought through system a button looks like a button and there is no need for a user (think content editor) to ever even be able to micro-manage things like the background color of a button. Maintaining global consistency is impossible with individual user control.

(Even more so I personally think taking away some choices like the ones relating to styling actually helps users be content editors by freeing them from needing to think about styling. This actually makes them feel more in control even if they might not technically be. "Decisions, not Options")

Core styles are always opinionated.

I understand that there has to be some baseline, but even that often needs to be changed drastically if not even removed. Simple example: Currently Column and Gallery Blocks use CSS Flexbox for layout, making any Core Block CSS totally obsolete if not even hindering if having your whole site layout based on CSS Grid.

So basically here the whole concept of multi-layer overwrites is somewhere between irrelevant to harmful beyond the fact that one can disable, overwrite or take as much control over it as possible. And even if some things may be allowed to be styleable by users I'd see the pyramid shuffled such as that the theme layer is on top having the final say and only "letting through" certain styling choices by a user.

So if this whole system gives even more styling control to users than we already have right now please make sure that any setting that is being introduced as user-controllable has a way to be disabled, restricted or overwritten. This is so that it isn't as difficult to stay in control as it currently is with things like custom colors/gradients, fonts sizes, number of columns, drop caps,...

Final thoughts

To close things up I am aware that the general direction Gutenberg is moving towards is a very visual approach to content editing. WordPress has always been quite oblivious to the separation of content and layout, but currently I see the risk that this might become the final nail in the coffin so that it isn't only difficult but becomes outright impossible the further down we go the route of giving unbound styling power to users.

@pagelab

This comment has been minimized.

Copy link

@pagelab pagelab commented Jan 16, 2020

In that setting users specifically should have no or at least very little control over the styling of the site.

@kraftner This is really spot on and I just want to point out that this level of control already happens 鈥渙ut there鈥. There's currently no shortage of plugins that empower the user to micromanage it's own website layout 鈥 even to it's own detriment.

By implementing this new system in core, that practice would be finally condoned by WordPress itself, which IMO is not in the best interest of that specific kind of user that have no clue about what design systems are, and therefore, their relevance and impact. And I would even say that this kind of user represents the majority of the user base.

This is something important to tackle before moving on.

@mtias

This comment has been minimized.

Copy link
Contributor

@mtias mtias commented Jan 16, 2020

Thanks for your detailed thoughts, @kraftner, these are good points.

All of the above is mostly concerned with maximum flexibility and control for "Users", offering them a solid base in the form of core and theme styling but giving them the final say and a broad array of capabilities to alter the styling of a website.

I don't think this is necessarily the case here. The system proposes a way to structure the style capabilities of a block in a way that can be better controlled, but it doesn't say much about who will bear this control. It's entirely possible that most of this would just be exposed as theme builder tools, to admins and designers, not necessarily to end users.

Think of it more as the evolution of the "theme editor" than necessarily giving control of all the style details to users. The latter would also not be great to most users, since it would be quite overwhelming, but themes need better and easier control over blocks (particularly blocks they don't know even exist!).

Sites where there are multiple users as well as a clear separation between designers, developers and editors. In that setting users specifically should have no or at least very little control over the styling of the site.

This is perfectly reasonable, and it should go without saying that a site would have control over whether these tools are exposed, to which roles, and which capacity 鈥 the same way your regular users don't have access to the PHP theme editor.

And even the Core Styling might be too opinionated. Instead the Theme Level should be the first, last and only one to decide how everything is styled.

It should be in your control to setup things this way 鈥 don't load default block styles (outside of the structural ones, maybe) and restrict the ability to edit global and local block style options. I think what you outline is a perfectly valid use case that should be easy to accommodate and improve upon.

So if this whole system gives even more styling control to users than we already have right now please make sure that any setting that is being introduced as user-controllable has a way to be disabled, restricted or overwritten.

Definitely. Again, I see this foundation as giving more deliberate control to the theme over blocks. A side effect is that we end up with a system that could also be exposed to users if they want to have that level of control using a GUI rather than writing CSS and modifying PHP templates by hand, but this is not going to be a one-size-fits-all-use-cases, as the world of WordPress is incredibly diverse and we need tools that accommodate diverse use cases.

If there are more examples of things that you feel are relinquishing that control from you, please, report them as issues so that it could be discussed and addressed. I do agree that currently it can take effort to go through all the things you might want to disable. Part of the motivation for a more comprehensive block style system is to make this easier to control 鈥 either by opening up or closing it down.

@kraftner

This comment has been minimized.

Copy link

@kraftner kraftner commented Jan 17, 2020

I think what you outline is a perfectly valid use case that should be easy to accommodate and improve upon.

This sounds great @mtias. I just wanted to re-emphasize this, especially the point that I think that it should be a blocking requirement for each and any of these user-controllable features to only go into the plugin or at least core when it comes with an option to control (configure, restrict, disable).

The reason I came here basically is due to the fact that you have pretty much said the same thing in the Office Hours at WCEU in June when you, me and @m where talking about this particular topic. But I already then had the impression that this was seen as a "nice-to-have" thing for later, not a hard requirement or even a priority. But without such control it is currently practically impossible to use Gutenberg in a tightly controlled setup.

Concerning the examples of the loss of control I am talking about - most of them already have issues, but unfortunately for a lot of them there is little to no movement. Often I also don't understand how corresponding bugs can even happen, why turning it off apparently isn't even tried for new features during development.
So in the end it feels like a very frustrating "Whac-a-mole" situation where for every feature one can regain control of, two more that are not controllable are entering the editor. Just to emphasize what I am talking about, here is a list of issues I am currently or was previously struggling with, having no or only hacky ways of controlling them. (This is right out of my still ongoing research for my upcoming WC talk on this very topic)

  • Drop caps: #6184 / #14654 -> #6023 (This was known/reported to be problematic long before WP 5.0, why did this feature ever go in at all?)
  • Background colors for tables #16478 / #19659 (Why was that "trade-off" ok and not a blocking issue?)
  • Font sizes #13824 / 46290 (How could this slip through? Disabling stuff is one of the first things to try after adding any option, no?)
  • Gradients: #18213 (Why doesn't this feature wait for a general solution to disable, instead adding an experimental flag, no documentation, introducing just another new mechanism to disable something?)
  • Numbers of columns #10791 -> #18892 (I understand the need for a general solution, but why aren't new features on hold until then?)
  • Template locking #8112 / #7845 (These are urgent requirements to be able to lock down CPT structure to replace the old Custom Fields Plugins approach)

I know that at the end of this list I am somewhat digressing from styling issues, but I believe all of this together shows the overarching theme: Taking control of Gutenberg is still somewhere between hard and impossible.

Don't get me wrong: I do understand that Gutenberg is still under heavy development and looking at all of these issues in isolation one can of course say bugs happen, nothing is ever perfect and we can only work on one thing after the other. But the sum of all of the above makes me feel like it isn't seen as a priority by the project leadership and instead of solving this important issues with content editing first, we're already pressing ahead to the next, even more complex area of full site editing.

TL;DR: Control over users capabilities is an important and urgent need across the whole of Gutenberg, and I really think that it is high time to put some more focus on this. Please, please give us back control before implementing any more features. 馃檹

@talldan

This comment has been minimized.

Copy link
Contributor

@talldan talldan commented Jan 21, 2020

I don't want to dig into the weeds too much, but one thing jumped out to me in one of the examples from the issue description:

For blocks to start using global styles, their CSS will need to be refactored to use the CSS variables outputted by system.

and then this is part of the example:

border: 1px solid var(--wp-gs-color-primary-dark20);

Colors are always difficult when it comes to theming because it's hard to base them on a particular semantic. Essentially this is hard-coding a relationship between the theme schema and a block's style, and that might be restrictive. I might be wrong, but I think it means the number of colors and types of color that can be defined are fixed. Also the block implementor has to make a judgement about the theme's configuration and what sort of color this should be. I wondered if there might need to be a separate layer where these styles are wired up to the theme's schema.

Instead, this is maybe defined as:

border: 1px solid var(--wp-button-block-border-color);

And then a relationship is defined (by the theme?):

--wp-button-block-border-color: --wp-gs-color-primary-dark20

Not sure if I've explained that clearly. It's already sounding quite complicated, but it's something I anticipate might need to be solved.

edit: On further though not sure how what I've proposed would work with third-party blocks. Perhaps the issue is that semantics need to be defined more clearly, so we avoid naming something 'dark' or 'light'.

@karmatosed

This comment has been minimized.

Copy link
Member

@karmatosed karmatosed commented Jan 22, 2020

As I am visual, I wondered if this might help anyone to see what gets effected each time something was iterated. For example, how the layers filter down. This builds on the pyramid cascade @ItsJonQ created and is done in collaboration.

Flow_ typography

What this does is look at specific actions:

  • Globally changing a style: for example, increasing baseline font size. In this case it goes across everything as global. The dots show that is the top (respecting the hierarchy) and what is therefore affected.
  • Local/document changing a style: for example baseline font size increase just on the about page.
  • Block style changes: for example just changing baseline font size just on a quote block.

If you notice there are 2 columns which don't have any interaction there, these persist throughout before you do any interactions.

Another point to note blocks includes a few things:

  • Style variations
  • Custom styling
  • Developer (plugin) block styles

In this image, the theme is the layer next to the core default, anything that changes globally above that all way up to the block at the top.

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 22, 2020

Global Styles - The First Iteration

This morning (Toronto time), I hopped on a call with @nosolosw and @jorgefilipecosta to sync up on this new Global Styles focus.

We have each independently worked on this problem at one point in time. Given that many aspects of Global styles is brand new (in the context of Gutenberg), and the complexities involved in all of the various moving parts, we felt like it would be good to sync up - to share our experiences, thoughts, experiments, and to start planning.

The 3 Parts

gs-mechanics-flow

After discussing the various implementation details and various edge cases, we simplified the original proposed concept into 3 main parts:

  • Resolver (we called it "Merge" during the meeting)
  • Blocks
  • Controls

These 3 parts still embody the spirit of the original design, except the "Transformers", "Hooks", and "Renderer" pieces were simplified and consolidated into "Resolver" and "Blocks"

Resolver

The Resolver is responsible for checking a theme.json file and the previously saved global styles data from the database. It will then merge the dataset together and prepare something for Gutenberg to consume.

Blocks

Blocks are the Gutenberg blocks we all know and love! Updates will need to be made to the blocks' .css to start using the CSS variables that will be core to the Global Styling system.

Controls

Controls are user-interfaces that enable the user to adjust global style values. These will be presented within the Full Site Editing experiences.

Note: Controls also exists for individual block instances. They are the various control fields that are available in a block's InspectorControls. The update will only adjust how the style values are applied, i.e. adding inline style CSS variables, rather than hard coded values. (More on that later)

Flow ("Backend")

The following will detail the backend flow of the Global Style system.

Resolver

gs-resolver

When the Resolver starts, it first looks locally for a theme.json file.

1. theme.json

For this proposal, a theme.json file is an easy way for a theme to:

a. Opt-in to global styles
b. Declare theme specific style values

An example of a theme.json may look like this:

{
	"name": "Awesome Theme",
	"global": {
		"color": {
			"background": "black",
			"text": "red"
		}
	},
	"blocks": {
		"core/paragraph": {
			"color": {
				"text": "hotpink"
			}
		}
	}
}

In this example, the theme is overriding the global default color.background and color.text. It's also specifically adjusting the core Paragraph block's color.text.

2. Checking the Database

If a theme.json is found, the resolver will then check the database for previously saved global styles.

Theme Specific global styles

Global styles are to be saved in a way that's specific to a theme. This enables the ability to safely switch themes without style aesthetic conflicts.

This can be demonstrated in this demo

(Try applying some global / document styles and switching the themes).

3. Merging

The theme.json data and database data are merged and prepared to be consumed by Gutenberg.

Block

gs-block

1. Rendered

Blocks are loaded and rendered by the Gutenberg editor. Blocks use a series of CSS variables that correspond to the global styling conventions.

CSS Variables

The following is an example of the core Paragraph block using Global Styles:

p {
    color: currentColor;
}

.wp-gs p {
	color: var(--wp-gs-paragraph-color-text, var(--wp-gs-color-text));
}
.wp-gs scope

For our initial implementation, the idea is to apply a specific CSS selector (.wp-gs) to either the html or body DOM node to effectively establish a "Global Style supported environment".

This raises the CSS specificity for globally styled blocks.

In the above example, a <p> rendering without global styles (like how they do today) would inherit it's color from a parent selector.

However, within a "Global style supported environment", the .wp-gs p rule would apply.

var(...)

The convention we're going with is to prefix the global style CSS variables with --wp-gs (WordPress Global Styles). In the example above:

.wp-gs p {
	color: var(--wp-gs-paragraph-color-text, --wp-gs-color-text);
}

var() is setup to:

  1. Handle custom block specific style rendering
  2. Fallback to generic values

The convention of using block specific styles with fallbacks gives the system both finer grain control as well as stability.

2. Block x Controls

If a block instance has custom aesthetic changes, e.g. a textColor update, the updated attribute(s) will be rendered as inline styles. The difference between the current implementation and the proposed implementation, is the use of CSS Variables over hard coded values.

Current:

<p style="color: red;">...</p>

Proposed:

<p style="--wp-gs-paragraph-color-text: red;">...</p>

In many ways, the effects are the same. However, using CSS Variables allows for most of the CSS cascading effects to apply.

Controls

gs-controls-3

Controls will be present within the site edit flow from Full Site Editing.

1. Update

gs-controls-1

When an update is made, the updated attribute is sent to the resolver.

gs-controls-2

The resolver does it's thing (perhaps coordinating with the @wordpress/data store), and pushes the updated consumable data back down to Gutenberg.

gs-controls-3

Lastly, that updated data (as well as updated CSS variables) are hydrated and rendered to the FSE user interface, and any visible blocks.

Flow ("Frontend")

The solution we've come up with (currently) requires the Resolver to check/read the theme.json and database to get and create the latest combinations of style values for a given page.

This happens server side on page load.

The Resolver will then create a <style> tag to be injected into the <head> of the page on load. Example:

<head>
    ...
    <style>
        :root {
            --wp-gs-color-text: black;
            --wp-gs-color-background: white;
            --wp-gs-color-primary: blue;
            ...
            --wp-gs-paragraph-color-text: hotpink;
        }
    </style>
</head>

Lastly, the .wp-gs CSS selector needs to be injected to activate the global styles from blocks.

- <html>
+ <html class="wp-gs">

And that's it!

The First Initiative

@nosolosw, @jorgefilipecosta, and I will be working together to create the 3 parts outlined above:

The first initiative we're going to be building for allows for users to:

  1. Set global styles for default text color
  2. Enable the core Paragraph + Heading blocks to use global styles
  3. Allow a theme to customize the default text color, heading and paragraph block text colors

Gotchas

The biggest gotcha at the moment is we're unsure how to properly support IE. Our current system relies very heavily on CSS Variables, and browser native feature that is not supported in IE11.

There are polyfills available, but there are not sufficient to do the rendering consolidations that we need (at least, not out of the box).

We are very mindful of this gap. For now, we're going to proceed with a CSS Variable based solution, as we want to validate the mechanics and flow of the system. Not only do they work, but they should not break backwards compatibility, and they should help Block Builders, Themers, and Users feel empowered rather than overwhelmed (by things like verbose API or CSS fiddliness).

Feedback + Thanks!

First off, if you've made it to the read (whether you've skimmed this or not), thank you so much! I know this was an awful lot to read. 鉂わ笍

My intention is to be as transparent as possible in regards to any designs, experiments, and implementations.

Global styles involves a lot of moving parts. The more context + updates I can give, the more informed folks involved with this project can be. Which will lead to better discussions and decisions.

As always, thoughts and feedback welcome!!

Thanks again :)

@nuxodin

This comment has been minimized.

Copy link

@nuxodin nuxodin commented Jan 27, 2020

I am the autor of ie11CustomProperties. https://github.com/nuxodin/ie11CustomProperties/
Meanwhile the Polyfill is quite fast and supports a lot.
If you would like to try it I will support you with pleasure if it comes to problems.

@aristath

This comment has been minimized.

Copy link

@aristath aristath commented Jan 27, 2020

@nuxodin to be fair, I haven't tested it in months, last time I checked that specific repo it was on v1.3, I see it has come a long way since then 馃憤

@koke

This comment has been minimized.

Copy link
Contributor

@koke koke commented Jan 27, 2020

The Resolver will then create a <style> tag to be injected into the of the page on load.

That seems it will make it problematic to use global styles on native. We don't run server code to initialize the editor, and would likely need an API-based way to get that data into the apps.
I've just started thinking how this might even work there, but I wanted to flag this issue early.

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 27, 2020

@nuxodin Wow! This looks promising! Thank you so much. We'll definitely explore ie11CustomProperties once we're ready to start testing out IE11.

I've just started thinking how this might even work there, but I wanted to flag this issue early.
@koke Thank you 馃檹 !! I really appreciate you and others thinking about issues/gotchas as early as possible.

@allancole

This comment has been minimized.

Copy link

@allancole allancole commented Jan 27, 2020

If the visitor is on IE, then they're still able to use the website perfectly fine - just with a different color scheme, spacing etc.
WordPress is compatible with IE11, but "compatible with IE11" doesn't mean that IE11 should show things the way a post-dinosaurs browser renders them... As long as it's functional we're in the clear.

@aristath, I agree with this sentiment quite a lot. I imagine if IE11 is your primary browser, you鈥檙e already missing out on tons of what the modern web has to offer today. As long as that fallback version works and is accessible it should be fine but this may only be true if you鈥檙e a site visitor browsing someone else鈥檚 WordPress site.

From the perspective of a site admin using WordPress with an IE11 browser, its tough to know what the editing/customization experience would be like. We might need to add something to disable Global Styles for WordPress site admins when using IE11 browser. Otherwise, they won鈥檛 be able to see any of the customizations they make which might feel like a broken experience for them.

@tellthemachines

This comment has been minimized.

Copy link
Contributor

@tellthemachines tellthemachines commented Jan 28, 2020

It's a common industry standard to leave IE11 support to "functional" rather than "perfect visual" level.

That might be sufficient enough here too especially considering screen reader use case as well that rest of the theme and block styles work as a fallback?

I'm more happy to go with this option for the editor side. My primary concern is with outputting CSS vars on the front end, because that means that anyone creating websites with WP no longer has the option to fully support IE if they wish to. And with my previous comment (sorry if it wasn't clear enough) I meant to point out that this could be a problem for government and other official entities that might have to provide that full support.

I'm also reluctant to go the polyfill route because of the performance implications. It might be worth doing a bit of investigation into how we can achieve this without using CSS vars on the front end (even if we do use them in the editor).

@aristath

This comment has been minimized.

Copy link

@aristath aristath commented Jan 28, 2020

My primary concern is with outputting CSS vars on the front end, because that means that anyone creating websites with WP no longer has the option to fully support IE if they wish to.

It's possible to add a PHP parser that will run server-side if enabled and replace css-vars with their actual values. This will make everything show on IE exactly the same as it would show on a modern browser.
We've done it before for the agency I work for and it works perfectly fine.
All the filters required for such a task are already in place, so it's not an unsurmountable task.

@asadkn

This comment has been minimized.

Copy link

@asadkn asadkn commented Jan 28, 2020

It's possible to add a PHP parser that will run server-side if enabled and replace css-vars with their actual values. This will make everything show on IE exactly the same as it would show on a modern browser.

This is definitely the way to go. Though with one limitation I assume, as long as the CSS vars are kept in :root or a similar top-level selector. Similar to https://jhildenbiddle.github.io/css-vars-ponyfill/

@allancole

This comment has been minimized.

Copy link

@allancole allancole commented Jan 28, 2020

It's possible to add a PHP parser that will run server-side if enabled and replace css-vars with their actual values. This will make everything show on IE exactly the same as it would show on a modern browser. I've done it before for the agency I work for and it works perfectly fine.

This PHP idea sounds really interesting especially if it doesn鈥檛 struggle with the same limitations that the fallback does. I鈥檇 love to see a PR or code snippet of this working in action鈥攕ounds pretty promising :-)

@aristath

This comment has been minimized.

Copy link

@aristath aristath commented Jan 28, 2020

Sure, I can work on the PHP implementation for this...
We'd basically need 2 things:

  1. Get the values of CSS vars.
  2. Add fallback styles for IE11.

For the 1st one I left a comment on #19883 (review) about adding a filter. We can use that filter to get the css-vars and their values.

The 2nd one depends on where the actual css that uses those css-vars gets printed. Will it be inline in blocks? If so, then we can use the render_block filter to take care of injecting the backwards-compatibility CSS.
If not, then is there a PR or an idea of how/where these will be printed? Or will themes just enqueue stylesheets using wp_enqueue_style?
If wp_enqueue_style is used, it's still doable but will require parsing the contents of the enqueued files, look for the css-vars, and if these vars are used in the file then calc the styles that need added and print them. TBH I'd like to avoid this last option because it might add some overhead if the theme adds large files.

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 29, 2020

Global Styles Roadmap

roadmap-phases

Thank you, everyone, for your thoughts/feedback so far!

There have been some discussions regarding certain aspects of the system (e.g. CSS rendering), which is valid. There doesn't seem to be much resistance or concern for the overall system and how pieces fit together, which is a good sign. It seems like we're on the right track!

This week, I've focused on exploring and planning. Thinking through technical details, implementation details, constraints, requirements, and use cases. Global styles is a substantial project, with many moving parts. It's a project that can have a profound impact on user experience and the ecosystem.

Because of this, I think it's really important to provide a clear (high level) vision - making it easier for anyone involved to understand and follow.

I've put together an high-level overview for how the system works, as well as a rough roadmap to sequence the phases of work.

馃摴 Video Screencast/Walkthrough
https://www.loom.com/share/9e63b821916a4f70821a52ced069b92b

In the video, I walk through the Rendering flow of the system and go over the phases.

Render Flow

render-flow

The diagram (above) illustrates the render flow of Global Styles. It visualizes the style hierarchy of the system. I've nicknamed this the "Synthetic Cascade".

It starts on the left (with Gutenberg and Blocks). The styles for the block may be modified when it passes through the theme layer, global layer, scope layer, and lastly localized changes within the Gutenberg editor. Finally, all of these accumulated changes render to the frontend of the user's site.

"Scoped"

The term "scoped" refers to a "document" or "template" part from the FSE experience. Essentially, a "Container" block that contains blocks.

3rd Party Block

3rd Party blocks are any non-core blocks. The system needs to provide them with a way to register their own custom styles, and have those styles customizable via a Global Style editing interface.

3rd Party Globals

3rd Party Globals refer to non-core styles that are not associated with a block. For example, adding custom global styles for overall site animation speed. Or perhaps overall site Typography font pairing (header/body).

Phases

roadmap-phases

I've broken down the work into 6 distinct phases (above). Note: Vibrancy emphasizes the focus we'd need for that area. For example, in the first phase, Red, the Core/Block area is very vibrant.

馃敶 Red

red

The first phase! The goal is to create the foundational system within core and rig up a couple of core blocks to the global styling system. We also need to provide a simple interface for updating these values. Lastly, we need to create an initial client-side (Gutenberg) and server-side (Site) style rendering system.

To start, we're going to be targeting the core/paragraph and core/heading blocks.

Consider this the MVP!

馃煚 Orange

orange

Second Phase! This phase focuses on introducing theme support into the system. How theme options and a theme.json file will interplay with core defaults. Lastly, how theme defined values are rendered and can be modified within the Global Styles editor UI.

馃煛 Yellow

yellow

Third Phase! This phase focuses on the Global Styles Editor. How block style values are presented and how they can be modified. How user-customized global styles affects theme and core values.

This is the first phase that will involve a lot of visual/interaction design.

馃煝 Green

green

Fourth phase! This phase continues the focus on the Global Styles Editor, but in relation to Document/Template parts, and how it plays into the FSE experience. The system will need to ensure that scoped changes work correctly with the style hierarchy.

馃數 Blue

blue

Fifth phase! This phase focuses heavily on the style rendering aspect. Here, we'll revisit where CSS variables are the correct solution. If not, what can we do to replicate that experience while working with the rest of the system. While working on the solution, we'll need to ensure that scoping as well as theme overrides work as expected. Lastly, this phase will start looking into 3rd party block support, and seeing how it plays with the rest of the system.

馃煟Purple

purple

Sixth phase! This phase continues the focus on rendering and ensures that it works correctly on the frontend of a user's site. It also ensures that the (potentially) new rendering mechanism works with the rest of the style hierarchy. Lastly, it integrates 3rd party block and 3rd party global support.


Where we're at?

As of right now, with the phases described (above), we've begun 馃敶 Red Phase, with our first initiative.

@jorgefilipecosta has created an initial PR that touches on all the aspects of this phase.

@karmatosed is exploring designs for the Global Styles editing interface.

@nosolosw is working on the Resolver x Client-side renderer aspect of the system.

I've been poking ahead to look at Controls.


Timeline

I can't provide an accurate timeline for the project yet. I think we'll get a better sense of things once we start building, testing, and merging. Until then, hopefully, the breakdown of the phases will help.


As always, thoughts and feedback welcome! If you've made it to the end, thank you so much for your time! 鉂わ笍

@jorgefilipecosta

This comment has been minimized.

Copy link
Member

@jorgefilipecosta jorgefilipecosta commented Jan 29, 2020

Sure, I can work on the PHP implementation for this...
We'd basically need 2 things:

  1. Get the values of CSS vars.
  2. Add fallback styles for IE11.

For the 1st one I left a comment on #19883 (review) about adding a filter. We can use that filter to get the css-vars and their values.

The 2nd one depends on where the actual css that uses those css-vars gets printed. Will it be inline in blocks? If so, then we can use the render_block filter to take care of injecting the backwards-compatibility CSS.
If not, then is there a PR or an idea of how/where these will be printed? Or will themes just enqueue stylesheets using wp_enqueue_style?
If wp_enqueue_style is used, it's still doable but will require parsing the contents of the enqueued files, look for the css-vars, and if these vars are used in the file then calc the styles that need added and print them. TBH I'd like to avoid this last option because it might add some overhead if the theme adds large files.

Hi @aristath,

Thank you for sharing your ideas and trying to address this problem.

I think we are in the presence of the second scenario, wp_enqueue_style is used. The styles that use the variables are normal block styles, and they are enqueued using wp_enqueue_style most of the times. Besides that, we have an even bigger problem core block styles containing these variables are loaded using the WordPress style concatenation system, so they are part of a giant spreadsheet.

Another point is that a simple replace of vars may not work because the idea is that in the future we will, be able to customize the global styles for things inside a specific block (e.g., inside a particular group the primary color is blue). The values the variables can have are not static; they will depend on the context.

I guess we should try to have a polyfill for CSS variables working in IE. We may even customize one for our specific needs and for example, pass a javascript object from the server with the values of the variables, etc.

@jorgefilipecosta

This comment has been minimized.

Copy link
Member

@jorgefilipecosta jorgefilipecosta commented Jan 29, 2020

The Resolver will then create a <style> tag to be injected into the of the page on load.

That seems it will make it problematic to use global styles on native. We don't run server code to initialize the editor, and would likely need an API-based way to get that data into the apps.
I've just started thinking how this might even work there, but I wanted to flag this issue early.

Hi @koke, if we use a CPT to store the global user styles, the user styles will already be exposed by an API.
That API would not include the theme default styles, just the user customizations. So we will probably need another API that provides the join of WordPress defaults with theme defaults. This problem is pretty similar to what happens with FSE. The user template block customizations are stored in a CPT, but themes provide default block templates via an HTML file, and mobile apps will need access to both CPT and the defaults. I guess the way we use to expose the theme HTML template files should also be used to expose the theme global styles. It is the same problem exposing a file set by the current theme.

@ZebulanStanphill

This comment has been minimized.

Copy link
Contributor

@ZebulanStanphill ZebulanStanphill commented Jan 29, 2020

@ItsJonQ

It starts on the right (with Gutenberg and Blocks)

I think you mean it starts on the left?

@gchtr

This comment has been minimized.

Copy link
Contributor

@gchtr gchtr commented Jan 30, 2020

What I don鈥檛 understand yet: How will color palettes and especially background colors play into this?

  • If I鈥檓 able to control the colors for different elements on a global level, can I also define a color palette that will be used as the Editor Color Palette?
  • If I have a color palette for background colors, can I control on a global level how an element looks on different backgrounds?

Take a button for example. If I choose a red color as the background for my default button, how will it look on different backgrounds, for example on orange?

Can I globally control the button background color on an orange background? Or do I still have to select the background colors for each of the buttons separately, when they appear on different backgrounds?

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 30, 2020

How will color palettes and especially background colors play into this?

@gchtr That's a great question + example! If I understand your question/use-case correctly... it sounds like we need to handle the case where:

  • All buttons are globally styled to have red backgrounds
  • But, when they appear in something with a clashing background (e.g. orange), they need to render a different color, (e.g. white, with black text).

That's where the idea of "scoping" custom global styles comes into play.

In terms of HTML/CSS, you can imagine this:

<button>...</button>
<div class="orange-section">
	<button>...</button>
</div>
button { background: red; }

.orange-section button {
	background: white;
	color: black;
}

The tricky part is. How do we replicate this model / style hierarchy in the Gutenberg Global style system?
In the context of Gutenberg, these bits would be Blocks.

So in a way... it'll be:

<Block>
<Block>
	<Block />
</Block>

Or another way of looking at it...

<Block>
<ContainerBlock>
	<Block />
</ContainerBlock>

That means, that we must be able to scope styles specific to "Container" blocks, so that any (targeted) child block would inherit these styles. The style system must support this from a UI perspective (style editing controls) and the rendering perspective.

Hopefully that makes sense!!! 馃檹


I think you mean it starts on the left?

@ZebulanStanphill Yes! Thank you so much! I've corrected it :)

@dnnsjsk

This comment has been minimized.

Copy link

@dnnsjsk dnnsjsk commented Jan 31, 2020

Hey @ItsJonQ,

This looks super exciting, however, I am also wondering how the Global Style System will work with colour palettes. I have created a mini page builder for my clients using Gutenberg, where they have full control over the layout, but no control of the colour scheme. If they need any changes to the colours available in the colour palette, I have to do it for them, but I would much rather prefer if they have the possibility to do it themselves.

The colour palette component plays a big role in my setup since the same colour might be used for Headlines and Button backgrounds, here is an example to make that a bit clearer:
PixelSnap 2020-01-31 at 13 00 59

Oxygen is already doing that in a wonderful way, allowing to change global colours AND seeing the effect of it live. I hope this behaviour will come to the Global Style System in some way too.
gif

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Jan 31, 2020

Oxygen is already doing that in a wonderful way, allowing to change global colors AND seeing the effect of it live. I hope this behavior will come to the Global Style System in some way too.

@dnnsjsk Thank you for your support and for that lovely example!

Yes, we have to support this interaction.

Ultimately, this entire effort is to improve (end) user experience. Not only should the adjustments change what you expect, but the experience must feel good while you're making those adjustments. It should feel creative, freeing, and fun. Which is in line with the goals of the Gutenberg editing experience :).

Admittedly, this experience is hard to pick out based on the wall of text I've shared in this issue 馃槄. I've mostly focused on the technical aspects and how those pieces will work together. In addition to a good end-user experience, the developer experience must be good. The workflows we establish feel easier and better for Themers and Block devs.

@karmatosed, @shaunandrews, and others are starting to explore the design/UX of this experience here:

#19255

We're still very early! I think the recent Roadmap will help the dev x design efforts work together.

@jasmussen

This comment has been minimized.

Copy link
Contributor

@jasmussen jasmussen commented Feb 5, 2020

Hello! I just wrote a long comment on #19255 (comment) which I should have probably have posted here instead? In any case the key takeaway from that comment is that as part of an effort to design a basic block pattern, I inadvertently created a wishlist of items I'd love to see the global style system able to accomplish (like font-weight, line-height, dropcap-size), mostly things I've already seen mentioned.

@carike-codes

This comment has been minimized.

Copy link

@carike-codes carike-codes commented Feb 5, 2020

Please make the sliders "a bit sticky" (smooth sliders are a terrible user experience over large ranges) and display the current value.

@ItsJonQ

This comment has been minimized.

Copy link
Contributor Author

@ItsJonQ ItsJonQ commented Feb 5, 2020

@carike-codes We have those featrures in the updated RangeControl component 馃檶
#19916

The slider behaves exactly like how a default HTML input[type="range"] would. In a situation where there are many steps, example, min: 0, max: 1000, step: 1, it'll feel "smoother", as there are 1000 values to increment over

(Hope that helps)

@Tug

This comment has been minimized.

Copy link
Contributor

@Tug Tug commented Feb 6, 2020

Note: This comment is about react-native compatibility

That API would not include the theme default styles, just the user customizations. So we will probably need another API that provides the join of WordPress defaults with theme defaults. This problem is pretty similar to what happens with FSE...

So if I understand this correctly we'll want to implement a client-side version of the resolver that will consume that API? Wouldn't that also help for FSE to be able to update the blocks styles as global styles are updated in the Controls?

If that's the case gutenberg native will want to reuse this client-side resolver.

There is still the issue of css variables which are not supported on react-native. A postcss transform won't work as we need those to be dynamic as to update with a new fetch to the API.

Taking into consideration the fact that we can only ever use inline styles in native so we'll need an extra module to fill in the style for any particular block in the editor.

Let's take an exemple of block styling where the user overwrote the text color for this block in the InspectorControls, we have this:

--wp-gs-color-text: #fff;
--wp-gs-background-color: yellow;
--wp-gs-paragraph-color-text: #000;

.wp-gs p {
	color: var(--wp-gs-color-text);
	background-color: var(--wp-gs-background-color);
}

<!-- wp:paragraph {"textColor":"red"} -->
<p style="--wp-gs-paragraph-color-text: red;">
Lorem ipsum dolor sit amet</p>
<!-- /wp:paragraph -->

On mobile we need to generate the same exact code, so save must be unchanged. However, edit must avoid using css variables:

<RichText style={ { color: "red", backgroundColor: "yellow" } } .../>

I'm not sure what are the implications in terms of writing X-platform blocks yet. Writing such a module that automatically resolve all styles for a particular block should be doable, at least if we limit ourselves to some CSS properties and if we don't have several customizable elements inside a RichText component.
Web and mobile could probably share this although it might have a performance impact in which case we'll need this only activated on mobile. @jorgefilipecosta @koke Not sure if you have any thoughts on this?

@koke

This comment has been minimized.

Copy link
Contributor

@koke koke commented Feb 7, 2020

@koke Not sure if you have any thoughts on this?

Yes, I share similar concerns, but I don't have any clear answers yet. My current instincts are that our best bet might actually be improving the CSS parser that we use on native to actually support CSS variables (and a few other things, like dark mode, media queries, and @supports). Instead of trying to convert the CSS to a StyleSheet in one step, we could have it generate a DynamicStyleSheet that would be able to adjust some variables and queries at runtime. This sounds like a big effort, so I'm still looking for alternatives that might be easier.

@Bowriverstudio

This comment has been minimized.

Copy link

@Bowriverstudio Bowriverstudio commented Feb 24, 2020

Could I use this to overwrite scss variables defined in bootstrap?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can鈥檛 perform that action at this time.