WordPress / gutenberg

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

πŸ– A Block Style System #9534

Closed mtias closed 2 years ago

mtias commented 6 years ago

Previously #5360

I'd like to define some areas of work around theme styling that go beyond WordPress 5.0. During the last 37 releases we have seen how the existing pieces interact together, so we should have a clearer idea of what has been working and what needs another look. While some of these tools and functionalities are already in place or underway, their full deployment will continue into the next phases of the project.

That means not everything has to be resolved now but we should make sure that the path forwards is one that can reach a fruitful destination one step at a time.

Strategy

Action Plan

Apart from introducing the changes in #9008 and refining #8732, I'd love to open the strategy outlined above for general discussion. What do you think? Any other ideas?

pascalknecht commented 6 years ago

I have another problem with styling: The styles of Gutenberg leak outside the editor. It would be great to prevent this. What do you think about it?

joyously commented 6 years ago

Some of this sounds very similar to what I put in #9555

0aveRyan commented 6 years ago

Related to @pascalknecht leakage callout is the main body.gutenberg-editor-page selector and potential codename deprecation.

As mentioned in #4681 in my recent comment, I'd advocate this string change sooner-than-later if deprecation is the final decision.

joyously commented 6 years ago

Joen closed my issue about the same stuff, so I'm putting my thoughts here. Reading the Gutenberg Handbook, it seems that theme integration is all backward. Here is an alternative version of how it could work:

  1. Opt-in features wide alignment - This feature should consist of adding a class to a block, and using built-in styles to represent the visual effect in the editor. The theme should not have to code a add_theme_support() call. If the theme provides a style for that class, it does. If it does not, it isn't styled. That's just how thealignleft and alignright classes work today with all themes. Block Color Palettes - This feature should not be generating dynamic class names. The editor should have some number of class names by default, that the theme styles (or not). By using different class names, the user is encouraged to have posts with many different classes. It should be the other way around. The classes supplied should be named for the "type" of style, not the specifics of the style. An example would be 'highlight' or 'stand-alone' or 'fine-print', where the theme can choose to style those with colors or sizes or margins, etc. The idea is to be consistent, so that changing themes does not involve fixing all the old posts with orphaned class names. If these were inline styles, that would be different, but also not really a good choice. Again, there is really no need for the theme to need to use add_theme_support(). This is a good place to consider using CSS Custom Properties. Block Font Sizes - This feature is similar to the color palette. There should be default class names and corresponding indicator on the font size interface component, but the user should not be encouraged to use class names tied to a theme (that would then be unstyled when the theme is switched). The theme can style the default classes without add_theme_support(). Also, absolute font sizes should not be used in examples. Disabling custom colors - Saying that a theme supports disabling custom colors is quite convoluted. I'm not sure I understand the intent here. Having anything in the editor dependent on the theme is a bad idea, because the user can change themes every day, but that should not affect how they edit their content. This whole concept should be removed. (See above).

  2. Editor styles It says "You can use this to change colors, fonts, and any other visual aspect of the editor." But this is a departure from years of standards that the theme should not style the admin. The theme should style the content in the editor, but not the editor itself. Add the stylesheet - if this is still referring to styling the editor, it should under Plugins. Otherwise, the process of styling the content already exists as add_editor_style(), which should continue to work. It would be up to the theme to ensure that the stylesheet referenced will work with the new editor. Basic colors - Is this name(body.gutenberg-editor-page) going to change? Is it referring to the whole page or just the content? This is another area that would be good for using CSS Custom Properties. Changing the width - Why isn't Gutenberg using the global content_width? Themes already define it.

  3. Default block styles - This is backward! If the theme is keeping up with current development, why would it want to add_theme_support( 'wp-block-styles' )? It's the themes that are not keeping up that need this by default. This way, the user can use the new editor without changing themes. This should be opt-out if there are truly styles that the blocks need to work. If the styles are not required for functionality, then why have them at all?

joyously commented 6 years ago

I think it's important to keep a clean distinction between WP themes and WP plugins. WP themes should not be making blocks or styling admin areas or providing much beyond a stylesheet. The things that are called add_theme_support() are "theming" from an editor viewpoint, but should really happen in plugins. It is important that the user is not tied to a theme, as in colors specifically loaded on certain pages. The styling should be generic classes that any theme can choose to style or not (since the user can put the style in Additional CSS). That brings up the question of how a user can get his Additional CSS rules into the editor easily.

ZebulanStanphill commented 6 years ago

I think alignment options in general should be context-dependent. There should be no main on/off switch in the theme. Instead, it should be up to the InnerBlocks or post template. Actually, the post template is kind of like one big InnerBlocks, is it not? Wide/full alignments do not make sense in a column, and even left/right float alignments do not always make sense in some contexts.

I agree that having nonessential default block styles is rather weird. Those should be in a Twenty Eighteen theme or something. Styles considered essential should be the only styles, and you should still be able to opt-out or at least fully override (as in no need for higher specificity) those styles. There should definitely be no opt-in nonessential styles.

chrisvanpatten commented 6 years ago

I just want to highlight that different types of themes have different needs. A highly custom purpose-built theme for an enterprise site has very different needs from a commercial theme distributed in the theme directory. The idea of portability from theme-to-theme is totally unnecessary (and possibly even detrimental) for enterprises, but of critical importance to individual users. I'm not sure how to reconcile those two cases, but it's important to note.

I also think it's clear that, in some ways, Gutenberg is really exposing the limitations of add_theme_support. That's more of a Core problem than a Gutenberg problem, but it definitely is worth considering as we think through the ways you might interact with theme settings.

joyously commented 6 years ago

different types of themes have different needs.

I think you are mistaking themes and plugins. The theme's job is to present the content for the current page request. Period. Entering content into the editor, and having a library of custom blocks to use is all the job of core and plugins.

Gutenberg is really exposing the limitations of add_theme_support.

I disagree with this. Gutenberg is using it for plugin support, when it is intended for themes. It is just a global variable to hold some values. Nothing else is really needed.

joyously commented 5 years ago

Aren't the Gberg styles for front end just a function call in PHP? Does it make sense for this to be a theme decision? Does it make more sense for this to be a per post decision by the user? Would it make sense for Gberg to facilitate this instead of push it off on the theme? (and the editor running in non-WP context might not have a theme to do it?)

timelsass commented 5 years ago

@mtias :

Block Style Variations.

I was wondering about that. These are very cool, and provide a much better way to express different designs. This is how I imagined block variations should be handled to give users more options for how they are displayed. I think it's awesome that this available!

Theme Support. There are a few aspects of customization that have been added as add_theme_support() calls (colors, fonts, wide alignments). There's also a discussion point about consolidating these declarations at #8732. However, theme support is problematic on a few fronts. It's unaware of context, which means supporting something like "wide" alignments doesn't take into account that "wide" might be contextual to the block nesting level you are operating at. Consider a case where a theme has two templates, a single column one and one with a sidebar. Whether adding content to the main column should have access to "wide" alignments depends on which template is being used. More importantly, with the addition of blocks like Columns or Section, it becomes evident that these alignments only make sense, as so far specified, when used at the root of the block list. As soon as blocks are added within multiple layers of nesting, the wide alignments cannot reflect the presentational intention anymore.

"I guess maybe we can just not have any option for a sidebar for Twenty Nineteen"

@joyously :

Block Color Palettes - This feature should not be generating dynamic class names. The editor should have some number of class names by default, that the theme styles (or not). By using different class names, the user is encouraged to have posts with many different classes. It should be the other way around. The classes supplied should be named for the "type" of style, not the specifics of the style. An example would be 'highlight' or 'stand-alone' or 'fine-print', where the theme can choose to style those with colors or sizes or margins, etc. The idea is to be consistent, so that changing themes does not involve fixing all the old posts with orphaned class names. If these were inline styles, that would be different, but also not really a good choice. Again, there is really no need for the theme to need to use add_theme_support(). This is a good place to consider using CSS Custom Properties.

Yeah - part of me likes the fact it did because I have work on a group of themes which have a color palette system in use that creates color classes, so implementing support for gutenberg wasn't much extra effort. But trust me when I say - you're 100% spot on - themeswitches become an issue on many different levels. It would still become an issue for themes with a unified classname approach too, but helps ease some of the symptoms. Naming them for what they are definitely helps. The approach I ended up going with in the end was a combination of things, but basically colors assigned by number for their order of presence in the palette - with classes generated based on css property, ie color-1-border-color, color-2-color, etc. This allowed us to have more flexibility than just the location name as there were more and more cases where we needed certain colors in different ways or places. We were also dealing with some other technical debt too though. Doing it this way - in order for themes to inherit colors in the sense you're speaking of - the color's presence on the frontend were what determined the order in the palette - so we said color-1 is going to contain primary color which gets used in context x,y,z etc, and the last color was always reserved as the "neutral" color which was normally used for the primary background colors. This prevented us from having worthless CSS selectors left over in the content, and helped improve the presentation after themeswitch. Granted this approach wouldn't really work out here since not everyone would want to use colors in the same manners, so I think that's probably why they left it open to the theme developer to decide.

Disabling custom colors - Saying that a theme supports disabling custom colors is quite convoluted. I'm not sure I understand the intent here. Having anything in the editor dependent on the theme is a bad idea, because the user can change themes every day, but that should not affect how they edit their content. This whole concept should be removed.

I disagree with this. The user can change their theme everyday, and that changes their customizer experience as this is where themes provide an editing interface for the layout and colors, so why is this any different? I actually would prefer just getting rid of pages in the dashboard and having users manage them right in the customizer with the editor controls available per page/post and customizer controls available globally. I mean it already supports everything else the pages section does, and more. We've spent a long time with WordPress, we're used to it. A typical user finds the separation disjointed though.

In the customizer I have a palette system where users can pick the colors that change everything on their site, including the content. They can also change which color from the palette different things use easily. I was happy to see colors make it to gutenberg. Now I can load the palette from the customizer, and the user can finally change the colors on a case by case basis of their site content. I didn't add functionality in the customizer for extending the amount of colors in my color palette yet, so disabling the feature for allowing the user to pick a custom color was really handy. The other problem picking a custom color introduced is the same problem I have had in my own editor - now I have an instance of an element which contains an inline style. This makes it harder for me to track the color usage, provide palette suggestions, and allow for all elements to change colors globally because the user has now basically created a static color instance that will always remain as is. Overall it's extremely handy from a DIY non webdesigner/developer to pick any color from a rainbow anytime they want to change something, but it's also one of - if not the - biggest issues I see repeatedly in terms of final product consistency for users. They pick inconsistent colors (without meaning to), and they don't realize that's actually what is happening, so they perceive things as being broken. I'm actually ecstatic that the feature to disable custom color option is available for themes, because it let me put at least some work on the back burner till I can have some time to integrate the feature properly for my needs. If it hadn't been - I would've just looked into removing it myself as the interim solution, but at least now I don't really have to do much. :smile:

You also had mentioned:

Add the stylesheet - if this is still referring to styling the editor, it should under Plugins. Otherwise, the process of styling the content already exists as add_editor_style(), which should continue to work. It would be up to the theme to ensure that the stylesheet referenced will work with the new editor.

I agree and disagree with this. I have worked on an editor which has many similar concepts as what Gutenberg does except it is for use inside of TinyMCE. We have many users who create their own content, and even their own themes based upon using that editor. All of our themes call add_editor_style, but in order to make things visually similar with Gutenberg in the themes, I had to make quite a bit of alterations. If Gutenberg is pushed as the new default editor - and I hadn't done that - I'd have thousands of people upset because it's not what they expected to happen. The best part about the classic editor was the fact all styles were isolated to be honest. No conflicts, and you could get WYSIWYG with little to no effort.

One example being for TinyMCE I had to write a plugin to handle importing some inline CSS which was generated from the customizer. Then I had to figure out how I could do that in gutenberg as well. I think it's important to note that while we are around this stuff pretty much everyday - a typical user is thinking "I just logged into my website and I need to go update my page with my calendar so no one else tries to make an appointment with me tomorrow." The last thing someone wants to do is figure out why their WYSIWYG editor is no longer really WYSIWYG, they just expect things to work. I think it's a smart move to leave this as opt in for themes, because we all know there's tons of abandoned themes and people who just don't care to update before something actually happens out there. In reality as well - I have to continue supporting the classic editor and the new editor - at least for a while. This can be a lot of effort if you manage a lot of themes and plugins - and objectively you can choose not to support gutenberg in certain projects or EOL based on usage statistics, revenue, etc.

Yeah, it's not ideal, but having some sort of switch for a few release cycles seems like the best approach to minimize the impact the editor can have. There's new bugs and issues found everyday for it - it's new, it's different, and it's conceptually doing a lot of things that were "blurred" between plugin vs theme territories.

add_theme_support isn't perhaps the best way to semantically name and provide a switch, but it's more or less only developers who are actually impacted, right? You said it best yourself, it's just a fancy wrapper around a global to hold some settings. A plugin developer who relies heavily on TinyMCE by providing features to that editor wouldn't have much of a need to declare theme support for it because his plugin was designed for use with the classic editor. Likewise, a gutenberg based plugin doesn't have much need to declare gutenberg support because it is obviously supporting it. It's a switch FOR themes to add support for their editor styles into the new editor. Of course there's some plugin territory too in which plugin developers will have to support both versions during this transition, but it's clear that despite any push back - gutenberg is going to be the new wp editor - so that's expected for developers when they are developing an extension to a parent application. At least it's opensource - so people who aren't happy with things can actually contribute to help make a difference and change things.

Part of the theme guidelines or at least the trt plugin states that themes can add some additional functionality through metaboxes. Metaboxes are something that are more or less sorta becoming deprecated - and developers are encouraged to change their format to fit the new editor's implementation. One theme I had I needed to extend the functionality of the "Page Attributes" metabox. There weren't hooks there for what I needed, so I had to copy the core version and deregister it to add the things I wanted to add for my theme's users. The settings were purely only related to my theme's display, and yes it could've been added to a plugin in theory, but there's arguments for both sides there. In Gutenberg, the core version of the "Page Attributes" metabox doesn't exist anymore, so users of that theme would see two Page Attributes sections in the Document panel. To fix that I created a js plugin to extend core's page attributes in the document panel since the stuff I needed to change is more accessible now with react in use - but the same rules still apply - it's only meant for use in that theme.

Modularity between themes and plugins is great, but so is providing a better and more cohesive user experience. Sometimes themes have use cases to provide functionality, and I believe the recent WP releases are reflecting a trend in that they are understanding it can be a mistake to say themes ONLY handle the styles and display of data. For instance starter-content support for themes now encourage themes to provide posts, pages, widgets, media, preset theme mods and options. For some premium themes I work on - we actually do some stuff to allow importing the starter-content on non-freshsite installs, and use that functionality so users can add new layouts, theme designs, blocks, customizer settings, and features easily.

More and more things are trending towards themes having more substance than just styling impact, and Gutenberg furthers this. I don't think themes should be told NOT to provide any blocks that they support for Gutenberg. In fact - I think themes should ALL add blocks. Having blocks that a theme developer made specifically to ensure the end-user, who doesn't even know what CSS stands for, is able to have beautiful content which more closely reflects the designer's original vision is a no-brainer. It makes the user experience of the theme much richer, makes content building easier (reduce support requests for developers), and saves users from having to try out 500 random block plugins which all have different and disjointed user experiences at creating blocks, finding them in the UI, the styles for them, and their outputs. It makes WordPress friendlier and easier, but still provides those with development knowledge the ability to continue creating themes and plugins to continue it's success. The WordPress repo has tons of themes, and a lot of them are pretty bad, content never really "just works", people have frustration trying to make their websites look like screenshots or demos, and the end results are usually never the way most theme designers expected when they view the results of their user's websites.

Despite that - I do agree with you though and probably to a more extreme. Themes should ONLY style content. Unfortunately, there's not a single one in the WordPress repo that does this, and this is exactly why the lines are blurred, continual discussions on what territories are covered by what, and general confusion. WordPress left structural decisions up to themes, and this has caused disparity between all themes. I would even say that if all themes could ONLY have a stylesheet so the same HTML structure is being output - designers could easily spend their time transforming that identical set of elements to look like virtually any theme in the repo, and behave in the same ways from a presentation layer (barring some extreme examples of course). I would even suspect that the quality of themes would rise, because spending the time to ensure everything in presentationally perfect on a static structure - you can focus on the details much easier. In an ideal world, I would think themes are maybe a .json file with some configuration options for initial layout arrangements, and one CSS file. Let the user move everything else around as they see fit with plugins/tools. Plugins could extend out that functionality and even output new structural elements to the frontend but more importantly everything would inherit the theme's overall design. Plugins are just as much a culprit as themes - no doubt. I mean I love "wooCommerce purple" buttons plastered on my site's awkward brown background more than the next guy, but both themes and plugins continually fail to understand or respect the boundary that should be in place to make both sides work together harmoniously. If I write a theme style that styled button elements, why is it that every plugin outputting content deems it necessary to include overly specific selectors and override the defaults I spent time creating? All those hours perfecting a theme's form elements CSS - and you put a practical use case to really test out how they look and realize every form plugin plasters 100 classes to the elements so they all come out to their vision of how YOUR forms should be displayed? If there's a boundary in place - it certainly doesn't exist in WordPress themes/plugin and has been more or less a major blocker for many great ideas over the years.

The separations of these things has caused loads of useless plugins to be made available on the repo. Plugins that just exist because a theme was rejected during review because it "did too much" so to speak. So the author removed everything he was told to, and put it in a plugin as he was instructed, and the plugin exists solely to support that theme. It doesn't really offer any unique feature or do anything unless you use that theme particularity theme. I hope you don't take this all the wrong way. I definitely don't mean to say all plugins do this, or all themes do this - there's plenty of great themes and plugins out in the repo, and ones who do respect the separation of the presentation layer appropriately, but in order for WP to grow - it has to start catering more to the average user and themes+plugins need to start becoming more harmonious. Gutenberg brings that to the table. It's making design choices, it's outputting styles, it's conflicting with theme styles, it's callin theme_support even though it's packaged as a plugin for testing purposes, it's doing all sorts of crazy stuff - but really - that's just progression.

The line will continue to be more blurred, like in the editor there's the concept of "plugins". Now you have "editor" plugins, and "WordPress" plugins. A "WordPress" plugin can register an "editor" plugin, a "WordPress" plugin can also be a collection of lots of "editor" plugins which are adding only editor functionality, and it could be blocks, styles, random stuff, etc. Whatever really. I also think themes should 100% at this point should be able to add editor plugins. For instance, I have a typography plugin I made for my theme, which reads the settings from the theme_mod users set in the customizer as the default. They have a control as well to set it to any other font, weight etc for any page/post they want which would update in the postmeta, along with a control to remove the custom font and use the global setting, and controls for overriding the global setting with a new font. My user is only seeing one page, they are only editing one page, why would I want them to set a global? They only ever see one page, even when they are customizing, so why wouldn't I want them to have access to that in a place which makes the disjointed experience come together a little more? I absolutely want that, it makes their life easier, it makes my life easier.

Would it make sense for Gberg to facilitate this instead of push it off on the theme? (and the editor running in non-WP context might not have a theme to do it?)

I think because Gutenberg was released as a feature plugin for testing there's some confusion as to what it does or doesn't do. I'm not entirely clear about these last questions - but I think you're referring to Gutenberg as it is implemented inside of WordPress, or as it stands as a feature plugin. And yes, the editor can run standalone, in which case WordPress as an application is not a dependency of it. It doesn't matter in a non-WP context about having various theme_support options, or core filters/hooks as WordPress functions don't exist in the non-WP context. It's just an editor at that point.

(since the user can put the style in Additional CSS). That brings up the question of how a user can get his Additional CSS rules into the editor easily.

I'm glad that you opened up to the idea of at least some theme's settings being acceptable inside of the editor :smiley:. As I said blurred lines, right? Assuming they've done the editor-styles stuff in the theme, they can add the theme's custom_css styles to the editor's initialization process with something like this:

add_filter( 'block_editor_settings', function( $settings ) {
        $css = wp_get_custom_css();
        if ( ! empty( $css ) ) {
            $settings['styles'][] = [ 'css' => $css ];
        }
        return $settings;
} ); 

That will make sure that they are passed in to be processed by the editor-styles CSS transform to avoid some of the specificity collision that can happen with the frontend styles. I don't think an end user needs control over this, but if you meant user as in the theme developer - they should handle the implementation of what styles should be added to the editor in the theme. I'd also argue that a theme developer should have the ability to add controls for something like this if they so wish make an interface for it available to their end users.

joyously commented 5 years ago

Ack! I'm a bit overwhelmed by the thrashing back and forth in your lengthy response. You make several of my points for me, but then conclude the opposite. And on some things, you totally missed my point. It's kinda crazy. I don't want to not respond, but feel that it's a bit much for this limited method of communication.

Disabling custom colors - Saying that a theme supports disabling custom colors is quite convoluted.

This is one you missed the point. If I tell you that I support you turning off the lights, how is it that I am actually supporting it? Wouldn't it make more sense for the lights to default to off and I support turning them on by actually doing it? So with the disabling custom colors, wouldn't it make more sense to not have custom colors unless another component supports it by saying so? Whether that is a theme or plugin is not in question. The default could be off, and then support is enabled with a function call. Having it as a function call to say it's okay to disable would imply that all components would need to agree to disable before they are disabled.

I think themes should ALL add blocks. Having blocks that a theme developer made specifically to ensure the end-user, who doesn't even know what CSS stands for, is able to have beautiful content which more closely reflects the designer's original vision is a no-brainer.

I sort of agree that users that don't know HTML or CSS should be able to make nice pages as well as those that do, but I disagree that the blocks should come from the theme. It should be a plugin. The user should be able to change his mind about the look of the site on a whim, and not be tied to the theme that provided the blocks. The content should be independent of its presentation.

Themes should ONLY style content. Unfortunately, there's not a single one in the WordPress repo that does this,

Yes, only styles, but presenting the content, which means outputting the structural HTML for the page. No, you are incorrect that those themes do not exist.

but in order for WP to grow - it has to start catering more to the average user and themes+plugins need to start becoming more harmonious.

Going for the average keeps you muddling through. Reaching for the extremes (accessibility and advanced users) causes growth and new solutions. Themes and plugins don't become more harmonious by doing each other's jobs.

I believe the recent WP releases are reflecting a trend in that they are understanding it can be a mistake to say themes ONLY handle the styles and display of data. For instance starter-content support

I disagree. Starter content should not be in the theme, but the people that threw it together at the last minute didn't really think it through. And the user doesn't really get a choice of accepting it or not, or of even knowing it is different than default.

Would it make sense for Gberg to facilitate this instead of push it off on the theme? (and the editor running in non-WP context might not have a theme to do it?)

This was about Gberg styles being output on the front end, and how the user should choose per page if those are wanted or not. Instead it is a theme decision, and those trying to run Gberg in a non-WP context won't have the option, because it's handled external to the editor.

I'm glad that you opened up to the idea of at least some theme's settings being acceptable inside of the editor

I'm not. You misread my statement. I was asking about the user adding styles in Additional CSS, and wondering how to get their styles into the editor. There have been forum questions about this already. I think the theme styles should be visible in the editor. That's why we have add_editor_style(). But it's only about giving a semblance of what the front end will be like. I don't think the theme should do more than style HTML elements and maybe a few standard classes. The theme's job is consistency across pages, so I don't like any dabbling with per post styling by the theme. Or anything that makes it difficult for the user to make his site look good again after he switches themes.

timelsass commented 5 years ago

Ack! I'm a bit overwhelmed by the thrashing back and forth in your lengthy response. You make several of my points for me, but then conclude the opposite. And on some things, you totally missed my point. It's kinda crazy.

I know - I'm a confusing person :smiley: I just wanted to share feedback as well on those topics along with my thoughts and experiences so far. I know you're very passionate about these topics, and very active here, themereviews, etc - so thank you for taking the time to read and reply!

I don't want to not respond, but feel that it's a bit much for this limited method of communication. It's the only way that I am familiar with communicating on here unfortunately, and I don't mind typing :laughing: Sorry to have overwhelmed you!

This is one you missed the point. If I tell you that I support you turning off the lights, how is it that I am actually supporting it? Wouldn't it make more sense for the lights to default to off and I support turning them on by actually doing it? So with the disabling custom colors, wouldn't it make more sense to not have custom colors unless another component supports it by saying so? Whether that is a theme or plugin is not in question. The default could be off, and then support is enabled with a function call. Having it as a function call to say it's okay to disable would imply that all components would need to agree to disable before they are disabled.

I could definitely get behind it being off by default. I thought you were meaning that the option shouldn't even exist. It does add a lot of implications to work around with the inline style overriding and the custom palettes stuff I had mentioned along with why I decided to disable it in some of my themes. So +1 for it off!

Going for the average keeps you muddling through. Reaching for the extremes (accessibility and advanced users) causes growth and new solutions. Themes and plugins don't become more harmonious by doing each other's jobs.

100% - but still - the majority of WordPress users are not designer/developers/advanced. Yes, reaching for extremes is definitely the way to go, and I believe Gutenberg will help open up entirely new experiences for how users interact with their content. Even still - if the average person isn't the one to cater to and we should put more emphasis on the minority - the advanced users (accessibility is something else all together which should definitely be addressed) - what is the need for a WYSIWYG editor then? It's been acknowledged that yes, the editor brings in a lot of new functionality, but with the plethora of new options and controls for the enriched experience, does add extra steps to the advanced user's flow for content creation.

I disagree. Starter content should not be in the theme, but the people that threw it together at the last minute didn't really think it through. And the user doesn't really get a choice of accepting it or not, or of even knowing it is different than default.

Yeah, it definitely was a rushed concept, and I wish it would be expanded upon more. The biggest learning curve for new users has always been the themes though. I still believe the omission of site content is the barrier - not giving new users a way to easily interact with stuff right away, so they can manipulate it with their own content is why site builder plugins are popular, and why entities like squarespace and wix are successful. They are filling the void for new and/or inexperienced users that WordPress hasn't. Truthfully if you think about a page builder plugin - they provide templating, layouts, drag and drop, content, etc - they easily surpass the theme/plugin boundary, yet are still acceptable in the plugin repo. Users don't even really need to use any theme in particular because some of those plugins allow virtually everything to be overridden, and there's clear stats on usage that indicate people definitely use them. It's because it made their experience using WordPress easier to handle.

This was about Gberg styles being output on the front end, and how the user should choose per page if those are wanted or not. Instead it is a theme decision, and those trying to run Gberg in a non-WP context won't have the option, because it's handled external to the editor.

I mean right now, this repo is setup as a WordPress plugin, so it does do some things that are implementation specific to the application, WordPress. I would think others implementing Gutenberg in different applications would create similar methods if they wanted to allow themes/modules/plugins etc to handle the style output however they see fit. I think it does make sense to have themes be able to choose whether or not they want to output the style for WordPress. They are the ones providing the frontend styles and look/feel as you said - so they should choose how the styles are utilized. I don't see much use for a user to select whether or not to output styles - as that could be sorta confusing.

My understanding was the editor isn't technically the one doing that - just the application. The editor is a js app, so while yes - the frontend in WordPress is making a php call for styles etc - that's just WordPress' implementation. A ruby app could easily be generating the ouput, or any language really. Whether those applications have themes or not, would probably be the determining factor for them including options or ways for the styles generated from gutenberg to be enabled/disabled/filtered/etc before output.

I'm not. You misread my statement. I was asking about the user adding styles in Additional CSS, and wondering how to get their styles into the editor. There have been forum questions about this already. I think the theme styles should be visible in the editor. That's why we have add_editor_style(). But it's only about giving a semblance of what the front end will be like. I don't think the theme should do more than style HTML elements and maybe a few standard classes.

I mean additional css - even though it's a feature from core, is a a theme_mod and specific per theme - so just another setting. Honestly, I would've loved to have add_editor_style() automatically support the additional css though. I always had to implement a tinymce plugin to handle it before, and now I have to do that code snippet I provided for gutenberg. It would've saved me some time, but overall I'm glad WordPress does have methods available for themes to be able to handle this sort of stuff if they wish -even if they could be easier to implement.

The theme's job is consistency across pages, so I don't like any dabbling with per post styling by the theme. Or anything that makes it difficult for the user to make his site look good again after he switches themes.

Yes, but I'm still of the opinion that Gutenberg really is opening up the possibilities of how plugins and themes could really utilize it. I'd hate to see themes rejected from wp.org repo because they decided to integrate gutenberg features in their theme. Granted - a little extra effort could be done to make those features reusable in a plugin sometimes, but there's several use cases like I mentioned previously where I think a theme could add useful features/functionality in the editor that are theme specific to improve the user experience and help with the disjointed process between the customizer and page/post editing experience. I'm looking forward to seeing what comes out of the Phase 2 portion though - hopefully that phase will help iron out some of the blurred lines for theme/plugin territory.

I do see, and agree with you, where theme switching is an issue. It's very hard to provide a a fluid theme switch process when themes are able to define whatever they please -- like custom color palette names fonts, etc. I mentioned things about the color palette and theme's implementing them here: https://github.com/WordPress/gutenberg/issues/6941#issuecomment-416006522. I'd be interested in hearing more about your thoughts on what you think would be the right approach to fix the custom colors and the color classes. I know you mentioned names based on location/usage, but I have seen lots of issues with that before too. You're absolutely right in saying that fontsizes are a similar issue as the colors. Having a solution to both of those is something that I really think should be resolved before pushing out a major version increment.

Thanks again for taking the time to respond back @joyously, I'm glad you clarified some of that for me - I hope I was able to do the same for my own thoughts/feelings/opinions for you :smile:

CalumChilds commented 5 years ago

My editor-style.css file for my custom theme contains the same rules as my main style.css file but it contains !important at the end of each line. Why?

strarsis commented 5 years ago

Currently I put the selectors for Gutenberg into main styles, but maybe something like jacket could separate them again for a separate editor styles file. Ideal but probably not always possible would be selector-parity between frontend and backend (Gutenberg editor).

ItsJonQ commented 4 years ago

Block Style System

image

It's inspiring to see the collection of high quality blocks that have been built with the current Gutenberg system. Various plugins/libraries that really showcase the dynamic potential of Gutenberg and the next generation of WordPress content creation (🀘). However, things become fragment and tricky when you mix these block plugins together - especially if you want them all to look and feel the same.

That's because they're lacking commonality between them, beyond the foundations of the Gutenberg block system. The front-end rendering of these blocks can benefit from a standardization of HTML and CSS, specifically, how the CSS can be customized by blocks, themes, globals, and user overrides.

I've been giving this problem a lot of thought, and I have a proposal for how we can potentially tackle this issue.


Note: These are the following terms I'm going to be using throughout this post:

"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.


The System

image

The system that I'm imagining will have 3 main pieces. These pieces work together to compliment the existing Gutenberg editing experience and provide Builders with a systematic way to create the front-end UI for blocks.

This system should be available as part of core. But perhaps, providing a way to disable style rendering if Builders/Users choose to have a blank slate.

The pieces build upon each other with Config being the foundation.

Config -> Framework -> Customizer

Where the pieces live can be visualized by this breakdown:

image

Note: In the above diagram, "Code" refers to something PHP / database related. For example, Config requires information from the database to set its initial variable data. Customizer needs some access to update variable values.

Config

image

The Config system provides a way for variables to be defined and overridden, which affects the UI rendered by blocks. It is the foundation for this block style system. Styling and customizing UI within this system should be done via the config system, rather than relying on CSS classes directly.

CSS Variables

Given the use-cases, It think the technological candidate for this would be CSS Variables.

Note: The caveat is, it won't be support with IE11. For the purposes of this proposal, we're going to assume that's okay.

CSS Variables solves many of the config x styling issues. It provides a layer of abstraction between the raw CSS code, allowing us to define grouped configs (e.g. --globalUiBackgroundColor). These configs can be defaulted and overridden by leveraging CSS var() fallbacks. Most importantly, these configs are context aware. If needed they can be customized at an individual block level, without worry of polluting the entire stylesheet with side-effects.

Globals and Defaults

The config system should have a collection of default values that power the UI Framework used to build blocks. Gutenberg kind of has this today. The defaults are mostly there, but are arbitrarily defined for each default editor block. They don't have a consistent look and feel. There also needs to be variables to power global things like colours and typography.

Generating values

Colours and typography are 2 use-cases that can benefit from generating values. Builders and Users should be able to specify a single colour value. That value will automatically generate the light/dark variations that will be used in interfaces like Buttons (hover, active, focus states). If desired, these generated values can be overridden.

Setting Variables

image

Using JavaScript, we can create a function that will make setting variables much easier. This (and perhaps the PHP equivalent) will be the recommended way of setting variables, rather than writing CSS variables directly

Do This

config.set('color.main', 'red');

Not this

// custom.css
:root[my-site] {
  --blockStyleSystemColorMain: 'red';
}

Hierarchy

The hierarchy for the Config system should be:

Default < Block < Theme < User

(< representing overrides)

Framework

image

The Framework consists of a collection of elements and patterns used to construct the front-end UI of blocks. It's constructed with regular HTML and CSS (with a hint of JavaScript), with variables powered by the Config system. The experience of building with it should feel similar to that of Bootstrap CSS.

image

The Framework will have documentation with usage + accessibility best practices to ensure successful adoption for Builders.

Ideally, we'd probably a more controlled abstraction that does not involve direct HTML implementation (e.g. WebComponents), but the technology isn't there yet (in my opinion). Given our use-case and technology requirements, I think using regular HTML/CSS/JS would be the best fit.

Look and Feel

The Framework elements need to have a default look at feel. Elements from frameworks like Bootstrap and Bulma, look like they're designed for apps rather than sites. The look and feel of this Block Style System Framework should attempt to accommodate the general aesthetics of most interfaces built by WordPress users.

Interactivity

For common interaction patterns like menus and dropdowns, we'll need some JavaScript to be loaded (on the front-end) that automatically work with the HTML from the Framework. This JavaScript should be as tiny as possible, and should work reliably with other JS from other blocks and plugins. If desired, the user should also be able to opt-out of loading the Framework's JS.

Beyond Blocks

This Framework shouldn't be limited to blocks. If desired, Builders should be able to construct non-block UI using the same code. Regardless of whether the UI is rendered with blocks or without blocks, the interfaces will benefit from the overall Config system.

Customizer

image

The Customizer is a UI that exists within Gutenberg that allows for Users to adjust variables from the Config system. The experience is similar to that of the current Customizer. (Apologies, I couldn't think of a better name). These edits can be seen in real time via special Blocks designed to showcase the elements from the Framework, as well as global-based UI from the Config system.

An example of this interface can be seen on components.ai.

image


Theming

With all of this in place, theming can be simplified. It can return to its roots of being the thing responsible for adjusting aesthetics vs. being the entire site.

image

Construction and functionality can be handled by Blocks, Templates, and Plugins. If a theme does require to have some custom front-end UI, Builders can use the Framework (perhaps to fill in some missing gaps).

The customization of the (Framework) UI elements that appear in blocks can be visualized with this config flow:

image

{} = Config </> = Framework C = Customizer


Implementation

Once we have the Config system running, as well as a base set of Framework elements, we can refactor the existing core Gutenberg Blocks. Refactoring the HTML/CSS, and connecting the system. Probably starting slow, to ensure the potential regressions aren't disruptive.


Demo

Setting (global) colours as a User Click to view

The above GIF demonstrates the ability to set global colour config. In this case, for a single button. For this example, I replaced the (Block) Button's background values with CSS variables from the Config system. I added a Toggle to determine whether to apply these changes to JUST that Button (locally) or to all Buttons (globally).

Updating the values is interesting. The changes from Gutenberg's Inspector Controls update the variables through the Config system, not through inline styles (or class names).

Setting Variables Click to view

The above GIF demonstrates how variables within the Config system can be set and updated. In this case, changing the global Button's background color.

This setting mechanism is handled by JavaScript, rather than direct CSS. The reason for this is it allows for:

TLDR of how it works. It creates and manipulates the document.styleSheet object directly. A common alternative would be to "inline" style variables too :root (e.g. html). This works, but may have undesired specificity affects, since its CSS context is closer the rendered HTML elements. Also, the <html /> element would be uncomfortably massive in the DOM.

image


Naming

image

While scribbling diagrams, prototyping, and testing, I realized that it would be helpful to have a name (or code name) for this Block System System. Naming is hard. After mulling over a bit, I went with the name "Bravas".

That namespace can be seen above in the Demo GIFs.

Edit: We don't have to go with that name! That's just the one I went with :)


Thoughts/Feedback

I approached this problem to directly tackle the gaps I see in creating Gutenberg blocks as well as front-end WP interfaces. An important note is that the ideas above are designed to work with the technologies that we have today. In other words... not rendering the front-end of WordPress themes using React.

I would absolutely love thoughts + feedback for these ideas! Nothing is set in stone .

Thank you so much for your time :)


Links / References


P.S. The artwork in this post do not make anything official. It's part of how I think through ideas. Also, I think they're fun :).

karmatosed commented 4 years ago

@ItsJonQ I love this thinking. I have been part of a few failed attempts at theme generation and right now the problem really is working around WordPress.

This can’t come soon enough. It’s just a bigger problem today than we even imagine and get empathic tastes of. There is a reason people in the theme world are cautious. We don’t need a new theme generator, or a new way to do the β€˜WP way’, we need a grassroots rethinking and this feels that. One that’s not clearing the deck in an aggressive way, one that remembers the mistakes of the past.

I am very excited to see this grow.

joyously commented 4 years ago

I'm all for idea of using CSS variables. In fact, my theme does this already. But I think you are trying to solve the wrong problem. It isn't a problem that the "blocks don't look like they go together", because that is only with some themes. That result is from the editor and block styles trying to do the work of the theme. The theme is already styling everything in the front end, and most themes style the editor. But since blocks came along, block styles and editor styles loading on the front end override and get in the way of what the theme is doing. If your idea takes hold and there is one framework, then the war is lost. All WordPress sites will look alike. What we need are fewer styles, not more or standardized styles. If the editor only styled its UI elements, the theme could do its job of unifying everything more easily.

karmatosed commented 4 years ago

Everyone is going to see their problems here, but I think it's essential to look at actual problems that exist today:

Let me qualify opinionated here because that seems to go on the surface go against some of the expected beliefs of themes do all styling. While yes, they should provide art direction, currently the sheer amount of heavy work that themes have to do to style, for example, group block, multiple alignments. That shouldn't be the case. The editor needs to have better defaults, easier styled ones, and this proposal opens that up. As a result, we need more structure, foundation styling. That shouldn't be confused with art direction, colours, typography and unique direction is what should come from the theme.

I often come back to the idea that changing a theme should be as easy as changing your clothes. If you change your sweatshirt, you don't have to remove your arms and put on new ones. How many times has content broken for you on changing a theme? I know it's a lot for me.

aristath commented 4 years ago

For the opinionated/unopinionated styles part of the above comment, blocks sometimes do too little putting the burden of styling basic things to the theme, and other times they do too much putting the burden of overriding styles to the theme. For example font-size in pixels should be a no-no in core Gutenberg styles. em would work just fine and themes wouldn't have to rewrite everything to get reasonably large sizes. Alignments etc yes they should be in the core block styles. But then again have you ever tried styling wide/full blocks on a site that has a sidebar, while at the same time try to maintain let/right-floated elements confined by the defined content-width? It's an absolute nightmare! Styles should be abstract enough to allow painless customization. Ideally any defaults would be customizable/filterable by the theme. So instead of hardcoded stylesheets, exposing something like the base font-size and allow themes to override it via a JSON or a PHP array would go a long way... And there's absolutely zero reasons to load styles for the cover block if I don't have a cover block on my page. Things need to be a bit more modular and hookable.

ItsJonQ commented 4 years ago

I'm all for idea of using CSS variables. In fact, my theme does this already.

@joyously Awesome~! I think having something CSS variables would be a game-changer for the WordPress front-end.

The theme is already styling everything in the frontend, and most themes style the editor.

The idea I proposed should make it easier for themes to adjust UI. Instead of target CSS selectors directly to override, themes can set/provide Config variables (currently done with PHP. Perhaps with this system... json?) that can more reliably adjust UI rendered within Gutenberg blocks.

If your idea takes hold and there is one framework, then the war is lost. All WordPress sites will look alike.

I don't think that's the case :). At the moment, there is some default UI that's rendered by Gutenberg's blocks, albeit very minimal. The idea for the Framework is to help with that. Being as minimal as possible when it comes to aesthetics, but having something to serve as a baseline. I think it would be lovely if the User chooses a very minimal theme, the composed UI would still look nice. Where I see the Framework helping would be with frontend HTML re-use, semantics, and accessibility (via aria) side of things. Especially if Builders use it to create blocks outside of Gutenberg for their own plugins.


Themes are too complicated; blocks add potentially more complication in styling.

@karmatosed That's the pattern that I'm seeing as well.


For the opinionated/unopinionated styles part of the above comment, blocks sometimes do too little putting the burden of styling basic things to the theme, and other times they do too much putting the burden of overriding styles to the theme.

@aristath I think this back/forth is a symptom of the large problem of... (IMO) As of today, Gutenberg's blocks don't play well with themes. The editor fundamentally changes the way content is created, rendered, and more importantly, customized. This goes against the previous theming workflow, which evolved out of necessity and integration issues (theme vs plugins vs custom CSS). At the end of the day, it's not going to stop any of use from building things :). But the experience for Builders and Users can be much smoother.

My proposal was to create something that directly addresses these issues at the core level, taking advantage of the momentum we have now with Gutenberg.

For example font-size in pixels should be a no-no in core Gutenberg styles. em would work just fine and themes wouldn't have to rewrite everything to get reasonably large sizes.

I agree. I think anything rendered by the (core) Gutenberg blocks should avoid px on the frontend. That would make it easier to have responsive font sizes/scaling. (That being said... I think px is great for backend/admin UI.)

Styles should be abstract enough to allow painless customization. Ideally any defaults would be customizable/filterable by the theme. So instead of hardcoded stylesheets, exposing something like the base font-size and allow themes to override it via a JSON or a PHP array would go a long way

That's what I'm imagining for this Block Style System :).

MichaelArestad commented 4 years ago

I don't think that's the case :). At the moment, there is some default UI that's rendered by Gutenberg's blocks, albeit very minimal. The idea for the Framework is to help with that. Being as minimal as possible when it comes to aesthetics, but having something to serve as a baseline.

I believe this alone will be incredibly valuable.

It should be trivial for a theme to opt in or out of these framework styles if they wanted to build from scratch, but right now it is quite difficult to style all of the blocks and combinations. The block styles are either too opinionated or not opinionated enough depending on your stance and familiarity with code. I lean toward the latter as I find myself wanting to build on top of a Gutenberg style framework where everything works together out of the box. Then, I can customize it to get the design matching my vision of a theme.

In short, once there is a framework in place, you could take a programmatic shortcut by using the framework styles as a basis to get you 90% of the way toward what is being envisioned with the theme design.

Caveats:

  1. It should be easy to opt-in or out.
  2. It should be easy for someone just getting started with HTML and CSS to work with.
  3. We should test it out in a pretty wide variety of use cases with a variety of developers/designers to understand what works and what could be improved.

I also wonder if there could be tiers of styling. For example, you might want just the bare minimum Gutenberg-provided block styles, but not anything too opinionated. That could be a setting. Then there could be a setting for the full set of opinionated styles.

mapk commented 4 years ago

This reminds me of Liquid, developed by Shopify and also used by NationBuilder. It provided a decent templating language that allowed themes to overwrite core styles using variables. This might be something to look into for comparison.

aristath commented 4 years ago

Using css-variables would indeed makes a lot of things waaay easier. Example:

.has-background {
  background-color: var(--background-color);
}

That's all we'd need on the css-side of things! Then elements can just define their own things. So a paragraph with a background would be

<p class="has-background" style="--background-color:#000;">...</p>

Themes can then do whatever they want with that. In a <p> element the benefits may not seem so obvious, but imagine a button:

<a class="whatever" style="--background-color:#000;--color:#fff;">...</a>

Then in my theme I'd be able to do things easy. For example, to get a solid button that on hover has a reverse color scheme:

.whatever {
  background: var(--background);
  color: var(--color);
  border: 2px solid var(--background);
}
.whatever:hover,
.whatever:focus {
  background: var(--color);
  color: var(--background);
}

It took me some creative JS & CSS to get that functionality in my theme and was more than 100 lines of weird looking code that I absolutely hate. Things could be a lot easier with proper use of css-vars...

youknowriad commented 4 years ago

While I like the proposal, I think we should focus more on the CSS Variables, config and customizing instead of going all down on the "framework".

The reasons being that:

strarsis commented 4 years ago

Gutenberg should offer enough hooks and filters that a framework or starter theme like roots.io Sage can offer a good foundation for Gutenberg-optimized themes.

The server-side render_block and client-side editor.BlockEdit filters finally allow having an extra layer in a theme to change the markup of Gutenberg blocks while the theme is active. When the theme is switched, the block markup changes immediately, without having to re-save each post (/page) and the original base markup is preserved.

ItsJonQ commented 4 years ago

Hallo! πŸ‘‹

Thanks for all of the feedback so far! I've been continuing this exploration, and I've come up with a demo that's a little bit more substantial.

Screen Shot 2019-11-20 at 5 03 44 PM

Video Link πŸ‘‰ https://cld.wthms.co/T8O5Ii

In the video (approx 1 min), it lays out the global typography of a user's site (within Gutenberg(. With some sliders and inputs, the user can (in theory) very easily fine-tune the designs of their site.

Certain values have been simplified to a single value (e.g. type scaling). If needed, I think these values can be exposed (perhaps under "Advanced", allowing for micro-adjustments), but hidden by default.

The live feedback for these changes is achieved using CSS Variables, as part of the Config variable system I proposed.


The part that I think is really neat, is that all of this can be done within Gutenberg. There could be a mode or a setting that launches this global Config editor/Customizer.

So far, all of these values exist as a simple JSON object:

const defaultConfig = {
    typography: {
        fontFamilyBase:
            'NonBreakingSpaceOverride, "Hoefler Text", Garamond, "Times New Roman", serif',
        fontFamilyHeading:
            '"Inter var", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, sans-serif',
        typeScale: 1.25,
        lineHeightBase: 1.5,
        lineHeightHeading: 1.25,
    },
    button: {
        backgroundColor: '#32373c',
        padding: '12px 24px',
        textColor: 'white',
    },
};

For themes, in theory, a large part of the art direction can be accomplished by the theme providing their own configs (which override/extend the defaults)


The very experimental and very WIP work can be found on this branch: https://github.com/WordPress/gutenberg/tree/try/block-style-system

aristath commented 4 years ago

I love the direction, but can we please get away from px at some point? Pixels made sense when all screens were between 14 and 16 inches. We now live in a world where screens range from 3 to 60 inches, pixels no longer work the way they should. A theme should be able to choose a base font-size, and then use ems. A pretty common practice nowadays is something like this:

:root {
    --font-size: 13px; /* Can be configurable */
    --typo-scale: 1.25; /* Configurable from theme-options too */
}
/* Adaptive font-sizes */
html {
  font-size: calc(var(--font-size) + 0.7vw);
}
/* Typography scale */
h4 { font-size: calc(var(--typo-scale) * 1em); }
h3 { font-size: calc(var(--typo-scale) * var(--typo-scale) * 1em); }
h2 { font-size: calc(var(--typo-scale) * var(--typo-scale) * var(--typo-scale) * 1em); }
h1 { font-size: calc(var(--typo-scale) * var(--typo-scale) * var(--typo-scale) * var(--typo-scale) * 1em); }

The above is a simple example from a theme implementing responsive/adaptive typography and a consistent typography scale. By using px and not allowing themes to use em easily, we're stuck in the past with no easy way to move forward.

joyously commented 4 years ago

Your demo looks like my theme (available for over a year). No JSON needed, and it does use CSS variables. I just don't think it should be in the editor, but it makes sense in Theme Options like Customizer. Typography

ItsJonQ commented 4 years ago

...can we please get away from px at some point?

@aristath Ah yes!! Awesome point. That's the next thing I'm gonna try

mtias commented 4 years ago

Thanks for the lengthy overview, @ItsJonQ! It'd be great to break things down into meaningful steps. I agree with @youknowriad that we should try to stay away from smaller units than the block. However, in practice, block builders are already relying on smaller pieces (rich-text, plain-text, media, etc) to specify the behaviour of the edit interface. It's not used in save, but it could, and it might ensure the attributes are mapped properly to the classes, properties, and variables without exposing them.

Color tools are a good example where adding support requires understanding a few things (the hooks, the attributes, the saved values, the classes). A lot of details will come into focus as we move ahead as well.

pattonwebz commented 4 years ago

There is so much to read in this thread that it is completely overwhelming. I spent 20 minutes here just now and I didn't even make it half way through. I scanned the lengthy proposal and on the surface it sounds like it makes some sense but it takes away a good portion of the ability for themes to easily (IE with simple CSS changes which an awful lot of people already understand) make adjustments.

While the idea of a framework seems like it simplifies things in reality it adds complexity to many peoples current workflow.

m-e-h commented 4 years ago

This thread is extremely lengthy πŸ˜ƒ

I certainly haven't read through it all but I haven't seen any mention of System UI or it's Theming spec.

It's configuration file is very similar to the what you're using @ItsJonQ https://github.com/system-ui/theme-ui/blob/master/examples/gatsby/src/theme.js

Might be worth exploring if and how this could align with some of the work being done there.

Here's how that system translates to a block editor: https://blocks-ui.com/demo

Blocks demo

ItsJonQ commented 4 years ago

I certainly haven't read through it all but I haven't seen any mention of System UI or it's Theming spec.

@m-e-h Halloo! Thank you for sharing your thoughts!

The tricky part about Style System (or similar frameworks/systems) is how they render CSS. They rely on an alternate CSS rendering method, in Styled System's cause, Styled Components or Emotion.

For frontend Gutenberg rendered content, the Gutenberg parser can't handle/transform dynamically generated styles using those methods πŸ˜… .

Here's how that system translates to a block editor: https://blocks-ui.com/demo

I was super excited when I saw Gatsby's block demo! Gatsby can do this because of their tech stack. It's all JavaScript -> Node.js, and it's all compiled before delivery. With WordPress, we don't have that cohesion.

The idea I proposed would allow us to achieve something similar within the Gutenberg/WordPress ecosystem/stack (as far as defining/customizing style goes)

m-e-h commented 4 years ago

Yeah, that all makes sense @ItsJonQ πŸ‘

I wasn't too hopeful for fully implementing that particular design system or using CSS-in-JS.

Was more thinking about how some of the ideas might serve as good inspiration or reference.

Particularly the config file you've been playing with. The Theme Spec would translate well there.

strarsis commented 4 years ago

To get things started, how should a theme author select only the typographic elements inside the editor? This doesn't seem trivial to me, see https://github.com/WordPress/gutenberg/issues/18846

ItsJonQ commented 4 years ago

Particularly the config file you've been playing with. The Theme Spec would translate well there.

@m-e-h Yes indeed! With the config system, there should be an easy way for a theme to declare variables. With Gutenberg, they have to be done with PHP functions. An additive method to this could involve something like a theme.json file. Where you have values defined as (nested) key/values (like Theme Spec).

The system can look for this file, load it, parse it, and apply it into Gutenberg x Theme :)

From my experience, declaring variables in this manner makes creating and customizing things feel really elegant and lightweight 😍. We do this a lot in the JS/Node world. A non-JS example would be Jekyll with its config system.

joyously commented 4 years ago

With the config system, there should be an easy way for a theme to declare variables.

Even better is to just use standardized names in the editor for CSS variables. And themes can set them to whatever values they want. No config needed. Very simple. Everyone can do it easily without JS.

timhibberd commented 4 years ago

@mtias - There is some great discussion and some excellent idea mock-ups in this issue so far. What are the key questions you take away from this discussion so far that will drive the strategy from your perspective?

So far these are the key strategic questions I am hearing:

  1. Gutenberg blocks are UI-opinionated - should they continue to be or should they transition to being UI-directed by the theme?
  2. We have already standardized the block editing and management. If the block U.I configuration mechanism is to be standardized what forms might that take and what are their pros / cons?

I would be curious what key questions other contributors have in mind. I love key question discussions because they get to the heart of the problems people are concerned about without being obfuscated in solution speak.

timhibberd commented 4 years ago

So here are my thoughts around my key questions...

NOTE: I have separated this from my previous key questions post to avoid muddying the waters around the value of us consolidating our Key Questions lists to assist @mtias to clarify the strategy.

Should Gutenberg blocks be UI-opinionated or UI-directed?

In my opinion GB blocks should be UI-directed. There should be a GB Core Block Test Theme / Configuration that embodies the U.I. configuration currently embedded in the UI-opinionated core blocks and the core-blocks should be converted to be UI-directed by that GB Core Block Test Theme / Configuration.

This provides a stable reference point for all concerned and facilitates auto-testing for the core elements. It also facilitates the continuation of a flexible theme marketplace that has been a key contributor to WordPress's success. I believe this conversion could be done in a fashion that would not break existing websites that are based on a legacy UI-opinionated GB block world.

Why do I think this?

We can't reasonably support co-managed blocks in the field or support will become a nightmare when a bug is reported by an end-user. Every core UI tweak will potentially break the UI for millions of sites. If core blocks are UI-directed then the theme supplier handles the 1st-line support issues as they already have been doing so for years. Unless something changes from the current UI-opinionated core-block path, the core team will be inadvertently taking on all the end-user U.I. 1st-line support burden.

I have not converted my client sites to GB for this very reason. GB has already broken the few live GB pages I have deployed numerous times because tweaks to the underlying block-UI have cascading consequences to the over-arching UI configuration.

What form should standardized blocks U.I. configuration take?

I believe that there should be a standardized configuration mechanism supported by the core and I do like the direction that @ItsJonQ has mocked-up. I also appreciate the customizer mock-up by @joyously as a reminder that the GB mechanisms needs to be directed by the theme vs. being opinionated in an isolated fashion.

Having said that, I acknowledge that there is a market imperative for WordPress to be able to stand-alone independently from the WordPress free / commercial theme marketplace in providing a "Wix-competitive" experience.

For this to work, though, the core team would need to create a 2021 theme in parallel to this blocks U.I. configuration management development process to ensure that the underlying mechanism is UI-directed and not UI-opinionated. This approach would also allow the free / commercial marketplace to develop in parallel and provide useful feedback and better development testing economies-of-scale.

Regarding the form of the configuration management mechanism...

@joyously raises a good point. The marketplace has invested in the customizer. If it is to be replaced then there should be design documentation, open to market feedback, with a reasonable explanation as to why, architecturally, it needs to be replaced and what it would be replaced with. I like the look of the @ItsJonQ mock-up in that it makes the management UI consistent with the GB block management UI...does that mean a re-write of the underlying customizer mechanism or just a re-skin!

To close I would point out that add_theme_support() is the canary in the coal mine. At present:

  1. add_theme_support('title-tag') is the theme telling the core it will NOT provide this function!!
  2. add_theme_support('align-wide') is the theme telling the core that it will NOT muck up the UI hard-coded in the blocks!!

Standardization can be dictatorial (UI-opinionated) or facilitated (UI-directed). I prefer the latter than the former since it is more flexible, facilitates auto-testing and clearly delineates the support lines.

add_theme_support() should not exist in a theme-directed world. The theme should never have to tell the core what it is doing.

kraftner commented 4 years ago

I've just added a long comment concerning the global style system, but I have another comment that fits better in the context of this issue:

Horizontal separation instead of vertical inheritance.

I'd also like to add something new I deem very important and I don't see addressed at all here right now.

There is a lot of thought going into vertical inheritance, especially in #19611, but the the fact that each layer always covers every possible block with all its states is a real issue. On a site where only a very small subset of blocks with a limited set of configurations (e.g. disabled Block Styles) are allowed/in use even the very slim shared structural core styles probably contain much CSS that isn't actually needed.

So what would be great here is a way to ensure that each level is split up so that only code for blocks that are actually in use are loaded.

In case this is too complicated or not wanted for any other reason the things I stated in my other comment concerning taking full control over the styling with the theme are even more important since the only way forward then is to just kick any styling from Gutenberg out and totally roll your own. For example in the way @justintadlock currently does in his Exhale theme.

AdFisch commented 3 years ago

Hello everyone,

I'm new to discussion and have done my very best to read and understand all open issues around the subject "theme.json". As far as I understood, this is the "vision issue". That's why I wanted to contribute some thoughts hoping they're not a duplicate (if so I'm sorry but there is sooo much to read).

Different themes - different demands

I know this has been stated before: I think there are 2 opposite approaches a theme can take (of course, these are the "excesses" and some themes lie in between):

I think the implementation of theme.json is a great way to serve both needs at the same time. However, I feel like the focus has been on the first category of themes so I wanted to mention some crucial aspects that I am missing for my themes of the second category.

Opt-in Flag

Highly customized themes are usually rarely updated. Updates usually occur if there is some kind of incompatibility, security issue or if the customer requests a new feature. However, me (and I think a lot of other developers, see j.hoffmanns comment for example cannot actively monitor changes in the available theme.json settings for each customized theme since those kind of budgets are not available.

Right now, if I don't actively disable a feature in the theme.json, it is automatically enabled. This might be nice for universal themes but might add unwanted functionality to my customized theme every time WordPress updates. That's why I suggest some kind of opt-in flag which states that only those editor features are enabled which are excplicitely activated in the theme.json:

{
    "version": X,
    "optInMode": true,
    "settings": {
            ...

Every control should be configurable

So far, theme.json only handles basic functionality like fonts, colors, formatting. For highly customized themes it would be important to be able to completely configure Gutenberg. This means, developers should be able to enable/disable every block control or manage available options (for example, how many columns can be created in the columns block, see #10791, or limit the available levels in the heading block). Right now, if I want to control the available options for the beforementioned examples, I need to completely recreate the block types. That's why I would suggest configuration possibilities like this:

{
        "version": X,
    "optInMode": true,
        "settings": {
              "textColor": [
                     Global text colors
              ],
              "core/heading": {
                     "levels": [ "h2", "h3", "h4" ],
                     "textColor": false
              },
              "core/paragraph": {
                     "textColor": true
              },
              "core/quote": {
                     "textColor": [
                            Block-specific colors
                     ]
              },
              "core/columns": {
                     "numberColumns": {
                            "min": 1,
                            "max": 3
                     }
              },
              ...

The above example would activate the text color options for all blocks and provide a default palette. The heading block then disables the color picker so users cannot choose a text color. The paragraph block has the textColor enabled, "true" means that the default palette is inherited. Note that setting "textColor" to true would be mandatory, since "optInMode" is true. The quote block then enables a text color picker with its own palette.

Right now, I feel like every theme ships with its own page builder. If Gutenberg was more configurable, theme developers could easily adapt Gutenberg to their needs, page builders finally were redundant and Gutenberg would get more credit.

Security concerns with auto-generated CSS

The upload of a theme.json file leads to the insertion of auto-generated CSS code in the frontend. From a security perspective, it is best practice to disable inline CSS/JS using CSP. I understand that it is very hard for "universal themes" to achieve a complete absence of inline code and thus, appropriate CSPs are never set. However, I have managed to do so with customized-themes (of course, for the frontend only - so no admin bar). I haven't checked if this is possible, but it would be neater if the auto-generated CSS code was output in a cached CSS file or that at least the auto-generated CSS can be easily disabled.

As I said, I'm fairly new to the discussion and hope that my suggestions above are new (and don't annoy you). I've seen parts of them in other issues so I wanted to consolidate them as well as think them further to make sure they don't get lost. Thank you all for your hard and very much appreciated work!!! I'm looking forward to your feedback.

mtias commented 2 years ago

This has run its course.

certainlyakey commented 1 year ago

@AdFisch thank you, your writeup summarises my thoughts exactly. The current state of Gutenberg doesn't make it easy for WP developers who sell a particular website development and do not sell reusable themes to customise core blocks without multiple trade-offs.