-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
🖍Global Style System #19611
Comments
Thanks for posting this! Very excited for the possibilities 😍
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?
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. |
So cool and can't wait for this feature! |
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? |
@tellthemachines + @nerrad Thanks for your feedback! I agree, the concern with CSS Variables and the lack of (older) browser support is very real.
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. |
👋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 🙌 Demo Too Long, Didn't WatchNo worries! I'll try to summarize <3 The style hierarchy can be represented by this pyramid: Core: Base styles that come with Gutenberg/global styling system 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: 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 Resulting in a site that looks like this: If we apply a global style, it will override the theme's: If we apply a document style, it will override global's (if applicable): Lastly, if we customize a specific block, it will override the other layers: 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: Theme SwitchingGlobal + 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. 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. TLDR (Too Long, Didn't read)
Thank you so much for your time! Thoughts + feedback welcome 🙌 |
Excellent breakdown, thanks @ItsJonQ! 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. |
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 |
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 StylingAll 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 thoughtsTo 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. |
@kraftner This is really spot on and I just want to point out that this level of control already happens “out 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. |
Thanks for your detailed thoughts, @kraftner, these are good points.
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!).
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.
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.
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. |
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.
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. 🙏 |
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:
and then this is part of the example:
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:
And then a relationship is defined (by the theme?):
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'. |
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. What this does is look at specific actions:
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:
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. |
Global Styles - The First IterationThis 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 PartsAfter discussing the various implementation details and various edge cases, we simplified the original proposed concept into 3 main parts:
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" ResolverThe Resolver is responsible for checking a BlocksBlocks are the Gutenberg blocks we all know and love! Updates will need to be made to the blocks' ControlsControls 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 Flow ("Backend")The following will detail the backend flow of the Global Style system. ResolverWhen the Resolver starts, it first looks locally for a 1.
|
@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: We're still very early! I think the recent Roadmap will help the dev x design efforts work together. |
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. |
Please make the sliders "a bit sticky" (smooth sliders are a terrible user experience over large ranges) and display the current value. |
@carike-codes We have those featrures in the updated The slider behaves exactly like how a default HTML (Hope that helps) |
Note: This comment is about react-native compatibility
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:
On mobile we need to generate the same exact code, so
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. |
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 |
Could I use this to overwrite scss variables defined in bootstrap? |
I just finished reading Adventures With Complex Global Systems in Block-Based Websites - Part One, and I thought it would be a good idea to share it here. It's a long, but interesting read, which might give some people here some ideas. |
We have been playing with Global Styles and have a few thoughts/ideas/questions. Current direction of Global StylesIf I understand the current direction, the idea is to hardcode global style variables into blocks so that they use them. The difficult part about this is that granular controls could end up being extremely numerous and extensive, and also hard to utilize in custom places. For example, these might be the way granular controls work (conceptually speaking, not an syntactical example):
Another idea for the direction of Global StylesAfter playing with that approach we were wondering if global styles could be more "thing-agnostic", and simplified like this:
The idea here is that blocks can choose if they want the background to be A few advantages to this approach:
|
If I have to pick between the two, I'd go with Approach B, but the version of this I've landed on for themes is a less granular version of Approach A built on top of Approach B. First, I define a bunch of colors:
(I can see the advantage of your proposed more generic --color-1 type setup for Wordpress at large, but the principal is the same.) Then, I map those onto some relatively generic high-level variables like these:
These can then be cascaded down through more specific variables as the theme requires:
Theme authors could get as granular as they want here (--h2-color, --page-title-color, --subhead-color, whatever), but they could always try to build off of the core with the cascade in mind. For example, if I was adding a block with a dark color scheme in my theme:
Switching gears, someone making a recipe plugin who has used the top-level colors like so would have a decent chance of just working fine when dropped into the theme author's Recipe plugin style example
|
Regarding IE11 support: Have you checked this solution: https://github.com/jhildenbiddle/css-vars-ponyfill ? |
I was suggested to bring clarity on where we are regarding the Block Style System. I'm trying to consolidate what we have in the two main threads: vision #9534 and specific steps #20331 which I'll update in the following days. Since this issue was created we've advanced a lot, implementation-wise: we have a working theme.json as well as a more mature understanding of its role to control the editor, we've created new design tools, an initial mechanism to connect the block & global levels of the block style system, and more than I'm missing. This issue has served its purpose, so I'm closing it. The above hints should serve as a testament of how fundamental this conversation has been to uncover the concrete steps we needed to walk. |
👋 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
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:
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
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
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
andfontSizes
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 currentadd_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"
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 thecolors
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:
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:
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!
The text was updated successfully, but these errors were encountered: