How do block themes work?
Block themes use templates made entirely of blocks. The layout is configured using a combination of theme.json and CSS. The settings in theme.json are used to generate CSS – this is part of the Global Styles feature. The theme CSS is added after the theme.json CSS and together these rules define the layout for a theme. If you’re just getting started with block themes, this guide should help.
Can I style my whole theme with Global Styles?
Global Style allows us to set styles for some aspects of the theme, but many common customisations are not yet available. We are actively helping to add more customisations to Global Styles, but in the meantime we have been working on a mechanism to define a lot more theme styles in a custom section of theme.json, until they are available in Global Styles.
The result of this work is a new theme called Blockbase, loosely based on the classic theme Blank Canvas. This block theme attempts to make all the common theme styles configurable in theme.json, and provides the CSS needed to make them work until the blocks themselves support these settings. As more of these configurations are added to Global Styles, we will remove the corresponding CSS from Blockbase.
Can Blockbase be used to build more block themes?
We are currently using Blockbase as a parent theme for all of our block themes; in time we hope that it won’t be needed. This means that child themes only need to define their settings in a theme.json file, and the parent theme CSS will adjust to these settings. This approach gives us an agreed standard when configuring block styles. It also will make it trivial to move to the Global Styles implementation when that becomes available in core.
Blockbase is intended to be a representation of all the theme style settings that we believe should eventually live in Global Styles and be configurable by users. Some themes need customizations beyond what would be possible with Global Styles. These more unique styles continue to be defined in the theme CSS file.
How it works
Style configurations live in the “styles” section of theme.json. Rules can be defined for both “blocks” and “elements”, and these will be interpreted by Global Styles and generate the appropriate CSS.
The theme.json file also contains a section for “custom” configurations, inside the “settings” property. Settings defined in “custom” are output by Global Styles as CSS variables. These variables are used by the theme CSS files to style blocks and other elements.
Child themes of Blockbase are able to redefine these CSS variables by setting different values in its theme.json. The child theme inherits the Blockbase CSS, but with the new CSS variables defined in theme.json.
To avoid a child theme needing to redefine every value in the theme.json file, child themes can create a child-theme.json file and a script will generate a theme.json file, taking the defaults from Blockbase and updating it with the new values from the child theme.
This mechanism will be particularly useful as more customizations are added to Global Styles; in many cases it will only be necessary to update Blockbase itself and rebuild each child theme, to update the theme.json files. You can find out more about this in the theme’s readme file.
Aside from the benefits outlined above, we have also found that this approach to building themes has resulted in a drastic reduction in the amount of code we need to write for both the parent theme and any child themes. As much as possible we rely on the styles that come with Gutenberg, and only add extra rules where necessary. Blockbase CSS is, at the time of writing about 1000 lines of code, whereas Seedlet CSS is over 4000.
As more of these customizations are added to Global Styles, we will be able to remove the corresponding CSS from Blockbase, so we anticipate the size of the theme CSS to reduce over time.
How Can I Use This?
Blockbase is available on the Automattic themes repo. If there is interest from others in using this approach to build themes we can investigate making it available as an npm package for others to use.
Permanent link to this post here