Experimental: Global Styles

What are Global Styles?

Global styles is a system created to help users change the overall style of their site, without having to edit individual blocks or pages.

Users will be able to select a body background color, or change the line height of all their headings from one place.
Styles added to individual blocks will still override the global styles.

Global styles has also been created to make it easier for developers to style their blocks both in the editor and the front.

Even though it is called Global Styles, it is not only used for styles but also for enabling or disabling features. A feature can be for example the drop cap text setting for paragraph blocks.

Global Styles are still experimental, so there are no controls added yet. Once completed, these controls will likely be placed inside a separate sidebar panel in the site editor.

Below are screenshots from the sidebar that is in the process of being built and tested:

Global style controls for website typography and colors.
Global block type controls for the columns block includes text, background, and link colors.

You can follow the progress of the controls with this Github pull request.

Who benefits from Global Styles?

Besides the users who will have more possibilities to change the look of their sites, global styles also benefits new theme developers.

The new controls will drastically reduce the need for custom solutions for styling, for example a theme options panel or customizer settings.

-It lowers the entry barrier for new theme developers, while allowing control of the styles.

How does global styles work?

Global styles work with the help of a new theme settings file called experimental-theme.json. Theme developers can use JSON format to define defaults for both the website and for the supported blocks.

-The block itself must first have support for the properties that we want to change. At this point, the support is limited to a few basic blocks and styles.

Global styles also makes use of the theme support for editor-color-palette, editor-font-sizes, and editor-gradient-presets.

The data from the theme support and the JSON objects is parsed and reformatted as CSS and CSS variables.

The styles are then added to the editor and the front with wp_add_inline_style.

The CSS is added in approximately the following order:

  1. The Gutenberg block library styles (wp-block-library-css, block-library/style.css)
  2. Custom block styles (register_block_style, wp-block-library-inline-css)
  3. The Gutenberg block library theme styles (wp-block-library-theme-css, block-library/theme.css)
  4. CSS variables (on the :root and .editor-styles-wrapper respectively)
  5. Global styles
  6. Block type styles
  7. Additional styles added by the theme, such as style.css
  8. CSS from the additional CSS customizer option

For those who are interested in seeing how the data is fetched, stored and parsed, see the global-styles.php file in Gutenberg.

The current status of Global Styles -August 2020

Global Styles is an experimental feature, so expect many frequent changes.

Global styles requires the Gutenberg Plugin to be installed and active. -It does not currently require full site editing to be enabled, but this may be needed once the controls for the global styles are added.

The official documentation for the experimental-theme.json file continues to be improved and you can read it here:

The number of supported blocks and properties has also increased in the last few weeks.

It is not yet possible to change padding and margin, but most basic blocks now have support for background, text and link color. Some blocks supports font size and line height.

All blocks will not have all properties. But expect the support to be updated and improved.

You can refer to these tables to learn which block has support for which property.

The two most common questions I receive about global styles are:

  • Do I have to use CSS variables?
    • Yes. The CSS variables are added for you, and they will be used with the options that the user selects, once the controls are added.
  • Can theme developers limit the Global Style options that the user can change?
    • Not right now (there are no user controls yet), but as far as I know, the intention is to allow theme developers to limit the options.

You probably have a lot of questions right now, but, hold on to them until the end of the lesson. 🙂

The experimental-theme.json file

The settings file experimental-theme.json is created and placed inside the main folder of the theme. The file will likely be renamed to theme.json once global styles are no longer experimental.

If you have already taken the block attributes lesson, you may recognize the format.

If you are new to JSON and want to read more about it first, try these resources:


You start the file with two curly brackets, { } and all the content will be placed inside these brackets.

You then add property names and values, encased in double quotes and separated with a colon:

{ "property-name": "value" }

The property name can be a block name or a setting:

"core/heading/h2": { "styles": { ... } }

Settings may be nested in several levels, as you will see in the examples below.

Global settings and block settings

The settings are separated into two scopes:

  • Global scope:
    • Settings that generates CSS variables and defaults for the website.
    • The global scope makes use of presets, styles, and features.
  • Block type scope:
    • Settings that adds default, site wide styles to the supported blocks.
    • Right now, the block type scope only uses styles. It will use features, but this has not been implemented yet.

Global presets

Global presets can be explained as settings that creates CSS variables. The presets themselves does not change any styles in your theme until the CSS variables are used.

Global presets via theme support

When you add color- and font size options to a theme, you want them to be presented with a translatable name in the control panel. This translation is made possible with the theme support.

With global styles enabled, adding the following theme support to your theme’s setup function;

add_theme_support( 'editor-color-palette', array( array( 'name' => __( 'Pale turquoise', 'text-domain' ), 'slug' => 'pale-turquoise', 'color' => '#d1f1f1', ), ) );

will create the following CSS variable:

--wp--preset--color--pale-turquoise: #d1f1f1;

Global presets via experimental-theme.json

Presets in the settings file are described using a preset category name and a slug.

In the example below, the preset category is a setting called “line-height”.

Presets with multiple values are placed inside an array. The properties are separated with a comma:

{ "global": { "presets": { "line-height": [ { "slug": "small", "value": "1.3" }, { "slug": "medium", "value": "1.5" } ] } } }

All generated CSS variables follows this pattern:


And the output from the example will be:

--wp--preset--line-height--small: 1.3; --wp--preset--line-height--medium: 1.5;

If a property is added via theme support, and also included in the experimental-theme.json file using the same category and slug, the value in the json file will be used.

Custom global presets

Most of the time, the category name that you use for your preset will be an existing block property that corresponds to a control.

But in contrast to block styles, the presets are not limited to using properties that the block supports. Presets can be used for any valid CSS.

Custom global presets will not have a control in the editor.
But if you want to handle all your themes CSS variables in one settings file, you can use the experimental-theme.json to create custom CSS variables that you can use anywhere in your CSS.

Global styles

The global scope has a second property called styles, hence; global styles.
These are style settings that affect the website.

The typography category inside the styles uses a property called fontSize to set the default base font size for the website:

{ "global": { "styles": { "typography": { "fontSize": "calc(1px * var(--wp--preset--font-size--normal))" } } } }

It uses a CSS variable, and the result is parsed and added as the following CSS on the front:

:root { font-size: calc(1px * var(--wp--preset--font-size--normal)); }

But style properties are not required to use CSS variables as values.

In this body background color example I am using a color name instead:

{ "global": { "styles": { "color": { "background": "red" } } } }

And the CSS output will be:

:root { background-color: red; }

Global Features

The purpose of the global features settings are to let theme authors and users enable or disable block features such as drop caps.

According to the documentation, the drop cap is the only feature that has been implemented so far, but I have not been able to test it successfully.

{ "global": { "features": { "typography": { "dropCap": false } } } }

Block Type Styles

Block type styles are default styles for blocks. The styles are applied to all instances of a block type.

Block type styles overrides global styles.
Additional styles added by the theme can be used to override styles for individual blocks.

The block type styles work similarly to global styles.
For block styles, the category name is always an existing property.

A block must first have support for a property before that property can be changed.

The available properties can be found in the official documentation.

The second difference is that code is not placed inside the global JSON object. Instead, the block name is used as the first property name:

"core/heading/h2": { "styles": { "color": { "text": "#000" } } }

In the example above, a black text color is applied to the heading block with the level H2. The resulting CSS output is:

h2 { color: #000; }

Global Style JSON examples

These examples describes the nesting of the different properties that are needed for the global styles to work.

Updated 7th of august 2020.

Creating presets

{ "global": { "presets": { "line-height": [ { "slug": "small", "value": "1.3" } ], "font-size": [ { "slug": "too-small", "value": "13" }, { "slug": "really-big", "value": "100" }, ], "font-family": [ { "slug": "primary", "value": "Roboto, sans-serif;" }, { "slug": "secondary", "value": "OpenSans, sans-serif;" } ], "color": [ { "slug": "blue", "value": "#69aee7" }, { "slug": "navy", "value": "#022384" } ], "gradient": [ { "slug": "prefix-blue-gradient", "value": "linear-gradient(180deg,rgb(105,174,231) 0%,rgb(65,128,182) 100%)" } ], "border": [ "slug": "thin", "value": "1px solid currentColor" ] } } }

The border in the example is a custom preset that would create the following CSS variable:

--wp--preset--border--thin: 1px solid currentColor;

Color Properties

Color properties are placed under styles, color.

The following color properties are available: Background, text, link, and gradient. Check the official documentation to see if they are available for your block.

{ "global": { "styles": { "color": { "background": "#ffffff", "text": "#000", "link": "#000", "gradient": "linear-gradient(180deg,rgb(105,174,231) 0%,rgb(65,128,182) 100%)" } } }, "core/block-name": { "styles": { "color": { "background": "#ffffff", "text": "#000", "link": "#000", "gradient": "linear-gradient(180deg,rgb(105,174,231) 0%,rgb(65,128,182) 100%)" } } } }

Typography Properties

The typography properties are placed under styles, typography.

The following typography properties are available: fontSize, lineHeight.

The global scope does not have support for line height. Font family is not supported.

The font size preset used in the example is created by the default font sizes in Gutenberg. Calc is used together with the preset since the value is unit less.

{ "global": { "styles": { "typography": { "fontSize": "calc(1px * var(--wp--preset--font-size--normal))", } } }, "core/block-name": { "styles": { "typography": { "fontSize": "2.5rem", "lineHeight": "1.6" } } } }