gutenberg
gutenberg copied to clipboard
Global Styles: an input for custom CSS
This issue stems from the recent FSE call for testing to create a custom 404 page. For my 404 page, I ended up adding several elements via the Customizer (accessible via Appearances > Themes > Customize), such as a site background image. I imagine that most of what I added will eventually be handled by Global Styles but as a designer, there’s always going to be something that could be tweaked a bit further.
There could be input form in the Global Styles panel for custom CSS:

This mockup includes some basic syntax validation, but it can be as little as what is being discussed here, and doesn't necessarily need the row highlight.
Note the details:
- Full height panel
- Fullscreen button to open in a modal
- Ellipsis menu that if need be can contain a link to "read more about CSS"
Issue updated Jan 20.
Initial proposal
What if there was an input form in the Global Styles panel for “additional CSS”? I’ve shown it in these comps living alongside Global Styles top-level options for Color, Typography, and Layout (as proposed in #27473, comment) but it could be more subtle.
I expect there might be some passionate arguments on both sides of this issue, and possibly also some important context around the Customizer that I'm missing 😅 Let's discuss!
Tasks
- [x] Add styles.css to theme.json schema - https://github.com/WordPress/gutenberg/pull/46255
- [x] Add custom CSS input option to global styles to site editor - https://github.com/WordPress/gutenberg/pull/46141
- [x] Verify security for full input and display flow of custom CSS strings
- [ ] https://github.com/WordPress/gutenberg/pull/47396
- [ ] Put the "Read more about CSS" link into an ellipsis menu, and allow the CSS panel to flex all the way to the bottom
- [ ] Add inline code completion and linting to input box similar to customizer
- [ ] Look at the possibility of adding a direct link to additional CSS in the site editor menu as classic themes do in the appearance menu
- [ ] See if there is a way to surface the validation warnings to the user - currently these only show in the console - #47132
- [ ] Provide list of blocks that have had custom CSS applied at the block level
- [ ] Remove duplication of custom CSS in hybrid themes
I'd second this proposal. Not all third party blocks are supported by global styles, and if they were, there would still be unsupported properties.
My use case right now is overriding the default background colour of a third-party audio player block. There's no way to do this while using a block theme.
Custom CSS definitely needs to continue to function alongside global styles. Style settings should never expose all of the possibilities in CSS as user-facing options. There is a lot of additional background on the benefits of user-edited CSS in the original core ticket and Make/Core posts from WordPress 4.7. #30496 identifies this particular feature as needing parity and outlines three potential approaches to ultimately maintaining compatibility for all current customizer features.
If #30496 moves in the direction of providing a separate implementation of customizer features in the site editor, we should consider the pros and cons of the current interface. Custom CSS is one of the most successful features in the customizer. It offers instant live preview. The preview is fully contextual - the HTML exactly matches the frontend, so the CSS previewing can also reflect the frontend. And users can inspect the preview markup while customizing.
CSS probably wants to be implemented in a very customizer-like way if it is rebuilt in the global styles context. It almost needs to exist alongside a browse mode (#23328), or otherwise lock the editor canvas during CSS editing to provide the best possible frontend parity in markup. The literal iframe of the frontend works well for a live CSS editor.
It would also be great to see further progress on some things that were planned but not yet implemented for the customizer iteration. See https://core.trac.wordpress.org/ticket/38707 for background including design mockups. If CSS gets another redesign, there's certainly room to improve it further.
For those who can't wait :
At Ionos, we have developed a tiny plugin for the very same reason.
It simply replaces the input field with a tag-like-editor (similar to the @wordpress/components
FormTokenField : https://developer.wordpress.org/block-editor/reference-guides/components/form-token-field/) to allow designers to apply a theme specific set of css classes.
Maybe this is solution to adapt for Gutenberg.
The plugin is about to be open sourced at github (https://github.com/IONOS-WordPress) within the next weeks.
The theme provides the set of css classes using a custom @wordpress/hooks
filter :
addFilter(
'gutenberg-customclassname-tag-input-extension-get-configuration',
'wp-flausen',
function (configuration, block) {
return {
...configuration,
items: [
{
label: `Funky effect`,
value: 'theme-custom-effect-funky',
description: 'Makes the block appear funky.',
},
{
label: `Thick`,
category: `Text`,
value: 'theme-custom-text-thick',
description: 'Makes the block font thick.',
},
{
label: `Thin`,
category: `Text`,
value: 'theme-custom-text-thin',
description: 'Makes the block font thin.',
},
...
and the css classes in the theme's style.css
:
...
.theme-custom-text-thick {
font-weight: bold;
}
.theme-custom-text-thin {
font-weight: lighter;
}
.theme-custom-spacing-small {
padding: 1em;
}
.theme-custom-spacing-medium {
padding: 2em;
}
.theme-custom-spacing-large {
padding: 3em;
}
...
The applied css classes can be styled by the theme depending on their "category" in the configuration :
.gutenberg-customclassname-tag-input-extension-tag-category__text {
background-color: #f0f8ff;
color: #333;
}
.gutenberg-customclassname-tag-input-extension-tag-category__spacing {
background-color: #789899;
color: #fff;
}
.gutenberg-customclassname-tag-input-extension-tag-category__foreground {
background-color: #69aade;
color: white;
}
I was trying to build a little site for myself with FSE today, and within 5 minutes I needed to make a custom CSS change, and immediately needed this. I think it's seriously problematic this wasn't made a higher priority. What are the next steps for this?
I love this idea and have already considered creating an issue for it. With customizer inevitably going away, I think this is a huge win for those who need to customize a few things via CSS.
IMO Custom CSS is essential for WP. There will always be situations that can't be addressed by global styles (plugins, theme styles held in stylesheets etc) and so I look forward to seeing a solution for this. Personally I would be happy for the customizer to be kept, and only show the Additional CSS box. It could even be rebranded as the CSS Customizer and have no panels.
Another thought: when this becomes part of Global Styles, perhaps CSS classes created here can be accurately reflected in the Editor when people use the Additional classes area on any block. That would really help as well.
Non-developers -- who are in excess of 90% of people managing WordPress websites -- absolutely need some way to enter CSS rules to tweak the appearance of their site. They will not create a child theme; it's beyond them. They shouldn't have to install a special plugin. This is core functionality that's needed in 100% of sites that aren't custom-developed by a developer, which is to say, 99%+ of sites.
I want ahead and added the "Needs Dev" label as I assume this issue is ready for a developer to work on.
@lgersman I like you modification! Looking forward to accessing the src.
Here is another implementation in order to access tailwinds classes, https://wordpress.org/plugins/website-builder/
@lgersman I like you modification! Looking forward to accessing the src.
@kauaicreative : I've actually already published the source code (2 todays after posting in this issue), but forgot to post it here 😅
react component for rendering the css classes : https://github.com/lgersman/wp-flausen/tree/develop/packages/react-tag-input
WordPress plugin providing the hook : https://github.com/lgersman/wp-flausen/tree/develop/packages/gutenberg-customclassname-tag-input-extension
example WordPress theme implementation : https://github.com/lgersman/wp-flausen/tree/develop/packages/gutenberg-customclassname-tag-input-extension-theme-example
I already extended the prototype to support CSS classes "per block type" (see https://github.com/lgersman/wp-flausen/blob/develop/packages/gutenberg-customclassname-tag-input-extension-theme-example/src/index.js).
If themes could also provide custom css classes via Global Styles (aka theme.json
) instead of a JS hook like in the prototype - a designers dream come true. But that's another story.
Both plugin and theme work properly.
They are not published to the WordPress Plugin/Theme Directory. The intention was just spreading ideas and contributing sourcecode :-)
Here is another implementation in order to access tailwinds classes, https://wordpress.org/plugins/website-builder/
@critterverse can we try moving as a separate section below the "blocks" one?
I wanted to leave a note about what I have tried so far, - and where I got stuck.
To fetch the data from the custom_css
post type to display it in the new global styles screen, I first tried using an existing store. This was not possible because the returned result does not contain the post_content for this particular post type (I was not able to figure out why).
Instead, I needed to created a new REST api route and control, and use it to get the output from the PHP function wp_get_custom_css.
I was not able to find a hook that could be used to apply the custom css correctly inside the Site Editor iframe. This preview is needed so that the user can see the styles, and see them change as they are updating the CSS in the input field.
In the test branch, you can see an attempt to filter BlockListBlock in a way similar to how Duotone uses it; this does not error, but the style tag is repeated, so this will not work.
I also tried adding the CSS as an additional style tag to the EditorStyles component, but I found this to be too early, outside editor styles wrapper.
Also want to reference the work to add custom CSS to other blocks directly, like Group: https://github.com/WordPress/gutenberg/pull/25413
We should see that both approaches are aligned in some of the implementation details.
Also want to reference the work to add custom CSS to other blocks directly, like Group: #25413
We should see that both approaches are aligned in some of the implementation details.
That would be really great. But it is unclear whether work in this direction would be accomplished. Such styles would make it very easy to live
I'm not really sure how deleting any option to input custom CSS helps to make an open and usable platform for the web. Even non tech-saavy users need to adjust some little CSS tweak here and there. Small sites users will often not dev a child theme and won't have/want hire a dev to do it. They will ask for small modifications like "could we make this block from my plugin I use for this and that change in that way". Without custom CSS that won't be possible without a plugin... why force them to a third party plugin when this was always inside Wordpress already? I really don't understand.
I get it: the goal is to make the most things graphical interface, good UI, etc.. But you won't change the fact that the web is built with html and CSS and sometimes, even when a user uses a full graphical interface, they will want, or need to input custom CSS.
I'll add that letting users input their own CSS is also a way into giving them access to more creative freedom and understanding. Removing that possibility by default from them, is making it more difficult for curious people to start to dig into the way a website is built. Which in my opinion is a bad thing. But maybe the path WP want to go is one of enclosing users into being UI users that can't tweak things and start learning. I know that's how I started my career: by inputing some CSS into some field on a site builder.
And I talk about non tech saavy but there is instances where professional also need to make small adjustments or where clients don't want big changes and have limited budget and what not. I'll just install a third party plugin that will possibly change owners in 6 months, or become insecure, or stop following good practices, etc... where I could have just open a "custom CSS" field. I don't get it. Just an example: imagine I built my whole site with TwentyTwentyTwo, it's simple, it works well. I install the very very very famous Contact Form 7 plugin. The default style is shit. How do I customize it? I can't. Unless I install third party plugin. Unless I spend almost the same time it took me to throw this first version at making a child theme, document it for the client, explain it to him, tell him where this very specific part of the website will be edited in a file on the server instead of being accessible from the interface etc etc etc. All I wanted was input 4 lines of CSS.
@Julianoe I don't think anyone is saying that the editor does not need a custom CSS field, I think most of us agree with that: It is a matter of it being difficult to build and to create an interface for it that is easy to use.
I went ahead and updated this issue with a fresh mockup based on feedback in the adjacent #44412 issue, and comments (2) on this thread. Let me know if all is as it should be!
Can we try with a separator between the blocks section and the custom CSS one? In that case, custom css could use an icon. Within the panel, the font-size in the text area seems a bit too big compared to everything else. Might be good to allow opening it in a modal as well with more room if needed. Are there other relevant setting from the current implementation in core that need to be accounted for (like pre-processor, etc)?
Quick take:
- Separation from Blocks
- Ellipsis next to the chat input subheading
- A button to pop out in a modal window
I think the button could be the full screen one we use in the cover block instead.
Could work:
Could work:
What I wanted to see. I needed it like air!
What I wanted to see. I needed it like air!
So do we !!
In general, I think that each block should have the possibility of custom css
In general, I think that each block should have the possibility of custom css
I would really like all these 1. global custom CSS, 2. block custom CSS, but also 3. page custom CSS. It would be useful to have custom CSS on the post/page level, that will be loaded just for a specific page.
In general, I think that each block should have the possibility of custom css
I would really like all these 1. global custom CSS, 2. block custom CSS, but also 3. page custom CSS. It would be useful to have custom CSS on the post/page level, that will be loaded just for a specific page.
Exactly +1 💯 I've been waiting for this for 2 years 😩👴😅 From conversations I had with others that's one of the main drag on using Block Editor instead of page builders they've been used to. I know there is a lack of dev but I don't understand how no dev prioritize this 🤔 I still have hope for 6.2🤞🍀
Exactly +1 💯 I've been waiting for this for 2 years 😩👴😅 From conversations I had with others that's one of the main drag on using Block Editor instead of page builders they've been used to. I know there is a lack of dev but I don't understand how no dev prioritize this 🤔 I still have hope for 6.2🤞🍀
Personally, I dare say that I don't care much about global custom CSS, because style.css has always been my global place for CSS (yeah, I wasn't using the customizer for that), although it would indeed be really nice to be able to do it all via the editor.
I also wouldn't care much about block custom CSS, if I had page custom CSS, although it would be really nice and helpful to have both tools at our disposal.
However, if I don't have a way to write CSS at the post/page level, just for a specific post, page or custom post, then I will be hesitant to move from other page builders (Elementor, WPBakery etc.) that offer this feature (which makes dev life a lot easier), and put my faith in Gutenberg. It's just that important, in my own opinion. Why?
Because with global custom CSS, we'd be writing styles that are not used by all pages.
With block custom CSS, we'd be writing too specific styles that will be all over the place in a page, albeit very easy to find because they'd be attached to whatever block we'd like to change.
BUT... If we had post/page custom CSS, then we'd also be able to have a centralized place for all of the styles of a page, written in our own personalized way. That way, we wouldn't be forced to use a reusable block or change all the blocks that are sharing styles, because we'd only need to change their common classes in the page's custom CSS. It would also be great if that CSS could be stripped off its comments, get combined, minimized and cached.
Additionally, if we could have template custom CSS (need I explain this?), then we'd easily eliminate all use cases of having unused styles in a page, and certain performance tools would stop complaining about it.
I can start working on this probably next week.
@jasmussen, one question regarding the mockups. What options should be available in the "Ellipsis" dropdown?
What options should be available in the "Ellipsis" dropdown?
Good question, sorry that wasn't clear. It was my slipstreamed visual response to Matías comment here:
Are there other relevant setting from the current implementation in core that need to be accounted for (like pre-processor, etc)?
So the ellipsis menu would be where to put preprocessing toggles or anything that comes up during implementation. I would also think it fine to omit it, if not in general if nothing comes to mind, then at least for the first version.
Thank you!