Global Styles helps users change the style of their site without having to edit individual blocks or pages. It also lowers the entry barrier and makes it easier for theme developers to style blocks.
Theme.json is a new theme configuration for block settings, site-wide styles, and block styles.
In this lesson, you will learn what Global Styles are, how to create a theme.json file, and how you can benefit from Global Styles.
Estimated reading time: 12 minutes
Last updated
What are Global Styles?
“Global Styles” is both a system for loading CSS and an interface created to help users change the style of their site without having to edit individual blocks or pages.
From a theme developer perspective, Global Styles makes it easier to style blocks in the editor and front.
- Users can select a body background color or change the line height of all their heading blocks from one place.
- With style variations, the theme developer can add multiple styles the user can choose from. For example, having a dark, light, or purple version makes themes more versatile than ever.
- Global Styles have low CSS specificity: Styles added to individually selected blocks, including styles in a block template’s HTML markup, override Global Styles.
Both classic PHP-based themes and block themes can take advantage of global styles using theme.json. But only block themes use the new Styles interface.
The Styles interface
WordPress introduced the Styles interface as part of the Site Editor in version 5.9. You find the controls inside a separate sidebar panel in the Site Editor.
First, access the Site Editor via Appearance > Editor in the WordPress admin.
Next, select the Styles menu item in the sidebar:
In the Site Editor, you can open the Styles sidebar by clicking on the icon with the black and white split circle (next to the save button).
In the first panel, you can access options for typography, colors, and layout for the website:
At the bottom of the sidebar, you can open the Blocks panel to select defaults for block types:
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 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 and designers while allowing control of the styles.
What is theme.json?
Global Styles works with the help of a new theme configuration file called theme.json. Theme developers can use theme.json to define defaults for both the website and blocks.
You use theme.json to enable and disable supported features, but you can not use it to add new unsupported features to blocks.
Format
Theme.json uses JSON format. One of the reasons the Gutenberg developers selected JSON was its ease of use. If you are familiar with arrays or JavaScript Objects, you will have no problems working with theme.json.
New to JSON and want to read more about it? Then, I recommend these resources:
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON
https://www.json.org/json-en.html
WordPress parses the data from the JSON objects and reformats it as CSS and CSS custom properties. WordPress then loads the styles in the editors and on the front.
In classic PHP-based themes, the styles are only loaded in the editors.
Documentation and specification
Since WordPress 5.9, there have been considerable improvements to the official documentation for theme.json. I strongly recommend that you bookmark the theme.json reference.
– I also want to highlight that theme.json will continue to evolve. In this lesson, you are only scratching the surface. You can use new or experimental features if you activate the Gutenberg plugin.
- The documentation in the Block Editor Handbook has information about new features.
- The Theme Developer Handbook has a beginner guide with information about what is supported in WordPress without the Gutenberg plugin.
The “What’s new in Gutenberg” posts on WordPress.org and the Gutenberg Changelog podcast by Birgit Pauli-Haack are good ways to stay informed about the experimental features.
How to create theme.json
This is an introduction and a limited overview of the available features in theme.json.
For more in-depth information, please see the theme.json lessons listed on the course page.
You place the new theme.json configuration file in the theme’s root folder:
patterns (dir)
parts (dir)
- footer.html
- header.html
templates(dir)
- 404.html
- archive.html
- index.html
- page.html
- single.html
- search.html
style.css
theme.json
You start the file with two curly brackets, { }
and you will place all the content inside these brackets.
Then, you will use a format with 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": {
"typography": {
...
}
}
Versioning
You must include the version at the top of your file inside the first curly brackets.
- Version 1 of the theme.json format is considered the earliest stable version.
- Version 2 is used from WordPress 5.9 to 6.5.
- Version 3 is used from WordPress 6.6, with a planned release in July 2024.
{
"version": 2
}
Main sections
You separate the theme.json file into two main sections: settings and styles.
- Settings:
- The editor configuration. Enables or disables features like custom font sizes, custom padding, and colors.
- Defines preset values such as color palettes. Presets generate CSS custom properties (CSS variables) that you can use in the theme. You can define presets for both the website and per block type.
- Styles:
Applies styling to the website or the blocks, with or without the generated CSS custom properties.
{
"version": 2,
"settings": {
"blocks": {
}
},
"styles": {
"blocks": {
}
}
}
Settings
Here are some of the features that you can change in the settings section:
- Color, including the color palette and gradients
- Typography, including font families and font size
- Layout, such as the content width.
- Spacing, for example, preset values for margin and padding
- Border
- Shadow (from WordPress 6.2)
- Dimensions (from WordPress 6.2)
- Position (from WordPress 6.2)
You can also create custom CSS properties.
Color
In the example below, the preset category is color
and the subcategories of color
are palette
, duotone
, and gradients
.
The official documentation sometimes presents this nesting as:settings.color.palette
, settings.blocks.blockname.color.gradients
You place multiple values inside arrays and separate properties with a comma:
{
"version": 2,
"settings": {
"color": {
"palette": [
{
"slug": "primary",
"color": "#D1D1E4",
"name": "Primary"
},
{
"slug": "secondary",
"color": "#E4D1D1",
"name": "Secondary"
}
],
"gradients": [
{
"slug": "primary-to-secondary",
"gradient": "linear-gradient(160deg, var(--wp--preset--color--primary), var(--wp--preset--color--secondary))",
"name": "Primary to Secondary"
}
],
"duotone": [
{
"colors": [ "#1d1f35", "#6cace4" ],
"slug": "dark-blue-and-light-blue",
"name": "Dark blue and light blue"
},
{
"colors": [ "#1d1f35", "#c7c0af" ],
"slug": "dark-blue-and-beige",
"name": "Dark blue and beige"
}
]
}
}
}
If you look at the gradient above, you can see that it uses the primary and secondary colors from the palette. Each preset generates a CSS custom property using this naming convention:
--wp--preset--{preset-category}--{preset-slug}
The output from the example is:
--wp--preset--color--primary: #D1D1E4;
--wp--preset--color--secondary: #E4D1D1;
--wp--preset--gradient--primary-to-secondary: linear-gradient(160deg, var(--wp--preset--color--primary), var(--wp--preset--color--secondary));
Typography
You can add font families and font sizes under the typography category.
FontFamilies
contains an array with the following keys:
fontFamily
: A list of one or more font family names.slug
: The slug is used to identify the font families and to name the CSS custom property. It is strongly recommended that you use a lower-case slug.name
: The visible name of the font families in the editor. Optional.- fontFace: An object that represents the CSS font-face declaration. Optional.
FontSizes
is the theme.json equivalent of add_theme_support( "editor-font-sizes" )
.
The size
property can use any valid CSS font size.
{
"version": 2,
"settings": {
"typography": {
"fontFamilies": [
{
"fontFamily": "-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell,\"Helvetica Neue\",sans-serif",
"slug": "system-fonts",
"name": "System Fonts"
},
{
"fontFamily": "Geneva, Tahoma, Verdana, sans-serif",
"slug": "geneva-verdana"
}
],
"fontSizes": [
{
"slug": "small",
"size": "1rem",
"name": "Small"
},
{
"slug": "extra-large",
"size": "3rem",
"name": "Extra large"
}
]
}
}
}
Layout and content width
The layout category replaces add_theme_support( 'align-wide'
);
and defines the width of the content.
- contentSize -Default block width.
- wideSize -Width of blocks with the wide align setting enabled.
This setting does not output CSS custom properties.
Place this code under settings
:
"layout": {
"contentSize": "840px",
"wideSize": "1100px"
}
Custom presets
When you create a theme.json file and add custom presets, you are not limited to using properties supported by the block. Compared to standard presets, they do not influence the block controls in the editor. A custom preset can be anything. If you want to handle all your CSS custom properties in one settings file, you can use theme.json to create CSS custom properties that you can use anywhere in your CSS.
"custom": {
"spacing": "14px"
}
Custom preset generates a CSS custom property using this naming convention:
--wp--custom--slug
Because of this, you should not use --
in your slug or values.
The output from the example is:
--wp--custom--spacing: 14px;
Presets for blocks
With block presets, you can add settings to a specific block type. In the next example, I will show you how to add a custom color palette to the heading block. When you add a custom palette to a block, it replaces the default palette.
Create a new section called blocks
inside settings
:
{
"version": 2,
"settings": {
"blocks": {
}
}
}
Add the name of the block, core/heading
, inside the new blocks section:
{
"version": 2,
"settings": {
"blocks": {
"core/heading":{
}
}
}
}
Any presets you create inside this section will only apply to the heading block.
"core/heading":{
"color": {
"palette": [
{
"slug": "tertiary",
"color": "#1d1f35",
"name": "Tertiary"
}
]
}
}
Example with both color palettes together
{
"version": 2,
"settings": {
"color": {
"palette": [
{
"slug": "primary",
"color": "#ff0000",
"name": "Primary"
},
{
"slug": "secondary",
"color": "#00b000",
"name": "Secondary"
}
]
},
"blocks": {
"core/heading": {
"color": {
"palette": [
{
"slug": "tertiary",
"color": "#1d1f35",
"name": "Tertiary"
}
]
}
}
}
}
}
Enable or disable features
Reminder: When a feature is enabled, the editor control is available, but only for the blocks that have registered support. You can learn which block has which supports in the block reference.
AppearanceTools -A setting that enables multiple features
AppearanceTools enables the following features:
- Border radius, color, style, and width
- Link color
- Block gap, margin, and padding
- Line height
- Position (from WordPress 6.2)
- Min height (from WordPress 6.2)
- Background image (from WordPress 6.4)
- Aspect ratio (from WordPress 6.5)
Typography features
customFontSize:
Let the user select a custom size value. Enabled by default, set to false to disable.dropCap
: Let the user add a drop cap to paragraphs. Enabled by default, set to false to disable.fontWeight
: Enabled by default, set to false to disable.lineHeight:
Opt-in, set to true to enable.fontStyle
: Enabled by default, set to false to disable.textDecoration:
Let the user add an underline or line through the text. Enabled by default, set to false to disable.textTransform:
Let the user select uppercase, capitalized, and lowercase text. Enabled by default, set to false to disable.writingMode
: Let the user change the direction of the text to vertical. Disabled by default, set to true to enable (from WordPress 6.3).
Example code:
"typography": {
"lineHeight": true,
"customFontSize": false,
"dropCap": false
}
– It is not possible to choose which font weights should be available in the editor, and the weights do not change depending on the font family.
This feature has been requested but has not been built yet.
Color features
The color options include:
custom
: Let the user select custom colors using the color picker. Enabled by default, set to false to disable.customGradient
: Let the user select custom gradients using the color picker. Enabled by default, set to false to disable.customDuotone
: Let the user select custom highlights and shadows for the duotone. Enabled by default, set to false to disable.link
: Let the user select a link text color. Used for all link states. Opt-in, set to true to enable.background
: Let the user select background colors. Set to false to disable.text:
Let the user select text colors. Set to false to disable.
"color": {
"custom": false,
"customGradient": false,
"customDuotone": false,
"background": false,
"text": false,
"link": true
}
For more color options, please read the lesson about theme.json colors.
Spacing features
Enable support for padding, margin, and block gap.
"spacing": {
"padding": true,
"margin": true,
"blockGap": true
}
Enable custom units for the margin and padding:
"spacing": {
"padding": true,
"margin": true,
"units": [ "px", "em", "rem", "vh", "vw" ]
}
To learn about the blockGap spacing feature, please continue to the lesson about Layout.
Borders
Enable support for borders. You can enable all or some, and allow different settings for different blocks:
"border": {
"color": true,
"radius": true,
"style": true,
"width": true
}
Styles
Objects at the top level of the styles
section are styles that affect the website.
Objects inside “blocks
” are styles that affect the named block type.
In the example, I use a color hex value for the background and a global styles preset for the text. I have defined the preset in the settings but truncated it for readability.
{
"version": 2,
"settings": { ... },
"styles": {
"color": {
"background": "#FFF",
"text": "var(--wp--preset--color--primary)"
}
}
}
The CSS output is:
body {
background-color: #FFF;
color: var(--wp--preset--color--primary);
}
Block Styles
Block styles override the default styles for blocks. WordPress applies the styles to all instances of the block. For block styles, the category name is always an existing property.
You can find the available properties in the official documentation and the block reference.
In the example, I am adding the secondary text color to the heading block:
{
"version": 2,
"settings": {...},
"styles": {
...,
"blocks": {
"core/heading": {
"color": {
"text": "var(--wp--preset--color--secondary)"
}
}
}
}
}
The resulting CSS output is:
h2 { color: var(--wp--preset--color--secondary); }
Referencing styles
You can also reference previously registered styles. If you have registered a style for the root of the site, you can reuse the same style for a block using the term ref:
.
This code example reuses the color that you registered for the body:
{
"version": 2,
"styles": {
"color": {
"background": "#FFF",
"text": "var(--wp--preset--color--primary)"
}
"blocks": {
"core/heading": {
"color": {
"background: { "ref": "styles.color.text" },
"text": { "ref": "styles.color.background" }
}
}
}
}
}
Additional sections
Template parts
With full site editing, there are three optional template part areas: header, footer, and uncategorized (general). You can assign a template part that you have designed as a header to the header area. This helps users select the correct template parts when they are creating or editing their website.
This section is at the base level of theme.json. The section name is templateParts
, followed by the template part slug (name) and the area. The title is the visible name in the editor.
In the example, the template part file name is header.htm
l, which means that header
is the slug you need to use as a value for the name
property:
"templateParts": [
{
"name": "header",
"area": "header",
"title": "Header"
}
]
wp_template_part_area
is a taxonomy for the wp_template_part
post type.
Custom templates
With a traditional PHP-based theme, you place the required information in the file header of the template file:
/**
* Template Name: Grid
*
* Description: A Page Template that displays your posts in a grid.
*
* @package Aaron
*/
With full site editing, you can list templates in theme.json.
The section name is customTemplates
and just like the settings
, styles
, and templateParts
, the section is at the base level of theme.json.
The first key is the name and slug of the template. In the example, I have named the template file page-about.html
, and the slug is page-about
.
title
is the template name that is visible in the editor.postTypes
is an array of supported post types.
"customTemplates": [
{
"name": "page-about",
"title": "About page without title",
"postTypes": [ "page", "post" ]
}
]
Patterns
The patterns
section was added to theme.json in Gutenberg version 12.7 to make it easier to include patterns from the WordPress.org pattern directory.
It is in the root level of theme.json and uses an array of block pattern slugs:
"patterns": [ "short-text-surrounded-by-round-images", "partner-logos" ]
Visit the pattern directory and select the pattern you want to include. For example, I have created this popular heading pattern.
The slug of the pattern is the last part of the URL: paragraph-heading
, and the code for the pattern section would be:
"patterns": [ "paragraph-heading" ]
Theme.json schema
WordPress contributors have created a schema to help you use theme.json.
By including the schema at the top of the file, you can validate the file, see tooltips with descriptions of the settings, and autocomplete in your code editor.
Schema for theme.json version 2:
"$schema": "https://schemas.wp.org/wp/6.5/theme.json"
Schema for theme.json version 3:
"$schema": "https://schemas.wp.org/trunk/theme.json"
Placement:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
...
– Adding the schema to the file is not required for theme.json to work but is strongly recommended. It is incredibly helpful while you are making edits.
Official documentation for the schema
Style priority
Now you know that theme.json creates custom CSS properties and overrides default styles for blocks. I have also shown a screenshot of the interface where users can select global styles. The user-selected styles have priority over the styles created with theme.json.
- Styles on an individual block that users add in the block editor. For example, a color change. Note that some of these styles are inline in block’s the style attribute.
- Stylesheets that you enqueue: Specificity and use of
!important
matters! There are always ways to override styles. - Styles that are added in the theme.json file and via the Styles interface in the Site Editor.
- Default block styles from WordPress (or Gutenberg if the plugin is active).