Global style variations

In this lesson

In previous lessons I have talked about theme.json as a single configuration file for your theme, but you can use multiple JSON files to add alternative settings and global style variations. This feature has been available since WordPress version 6.0, so chances are that if you have used any type of block theme, you have already tried this feature.

For example, you can have one color palette in theme.json, and then add a second JSON file with a different color palette. The user can then choose between the palettes in the Styles sidebar in the Site Editor.

These variations bring value to the user by making it easier for them to change the look of their site without having to switch to a different theme:

  • You can provide a combination of alternative site wide (global) settings and styles
  • Give users multiple color palette choices
  • Help users choose matching font pairs with font family presets
Level: ,

Estimated reading time: 4 minutes

Last updated

How global style variations work

Here is what you need to know to add style variations to your block theme:

  • Style variations use the same format as your standard theme.json file.
  • They inherit the settings and values from theme.json.
  • Anything you add to the variation overrides theme.json.

In other words, you can completely override theme.json and replace every setting. And if all you want to change is the color palette, then that is all you need to include.

When the user activates a style variation, WordPress applies the new styles in addition to the styles from theme.json. The variation overrides the default styles.

To register a style variation, color or font family preset, you need to place the JSON file inside a folder in your theme called styles, or a subfolder to styles (Props to Justin Tadlock for letting us know that subfolders work!).

Use a folder structure and names that makes it easy for you to identify the different types of variations.
In this example folder structure:

  • styles/maelstrom.json is a global variation with a combination of settings and styles.
  • styles/light-blue.json is a color palette preset.
  • styles/fonts/opensans-poppins.json and styles/fonts/instrument-jost.json are font family presets.
styles (dir)
   maelstrom.json 
   light-blue.json
   sections (dir)
      section-1.json
      section-2.json
   fonts (dir)
      opensans-poppins.json
      instrument-jost.json
theme.json

You can register custom block styles, section styles and color presets with PHP or JSON. This lesson focuses on JSON. You can read more about other methods in the lesson Block style variations and section styles.

Combined site wide settings and styles

You can use the first type of style variation to update both theme.json settings and styles. Including but not limited to the content width, spacing and font sizes, or the color of the link in the paragraph block.

Users with access to the Site Editor can preview and select these combined styles from the Styles sidebar > Browse Styles, or from Appearance > Editor > Styles.

If you are sharing your theme on WordPress.org, the theme directory also shows the styles
on your theme page.

Each combined style variation needs its own JSON file. By adding a title and description, you can make it easier for users to identify your style. The title is visible when a user hovers or focuses on the style option. The description is not visible in the Site Editor interface, but used for screen reader users.

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"title": "Maelstrom",
	"description: "Blue background and sans-serif fonts",
	...
}

For more examples please see the style variations in Twenty Twenty-Four.

Color palette presets

Color palette presets are JSON files in the styles folder where you only change the color palette setting and nothing else. WordPress recognizes the format, and displays the variation as a palette that the user can select in the Styles sidebar in the Site Editor.

Your palette presets can use any number of colors, but the preview is limited to five colors:

The styles sidebar in the Site Editor shows two combined style variations and two palettes.
{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"title": "Light blue",
	"description": "Two shades of light blue"
	"settings": {
		"color": {
			"palette": [
				{
					"slug": "base",
					"color": "#f0f0f0",
					"name": "Base"
				},
				{
					"slug": "contrast",
					"color": "#1e1e1e",
					"name": "Contrast"
				},
				{
					"slug": "primary",
					"color": "#00A0D2",
					"name": "Primary"
				},
				{
					"slug": "secondary",
					"color": "#0073AA",
					"name": "Secondary"
				},
				{
					"slug": "transparent",
					"color": "transparent",
					"name": "Transparent"
				}
			]
		}
	}
}

Font family presets

Font family presets work similarly to the color palette presets. You create a new JSON file where you only add the font families, and save the file in the styles folder. However there is an important limitation that you need to know about: You must first register all the fonts in theme.json, otherwise the font files will not be enqueued in the editors.

So you use theme.json to register the fonts, and then use the preset files to add font pairs that the user can preview and select in the Styles sidebar. The font family presets are displayed below the color palette presets, and also in the Typography panel:

The Typography panel in the Styles sidebar in the editor shows the current font names. There are two presets to select from at the bottom of the panel, and the second preset is activate.

Here I have copied parts of the Ember style variation in Twenty Twenty-four to a font family preset:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"title": "Instrument Sans & Jost",
	"settings": {
		"typography": {
			"fontFamilies": [
				{
					"fontFace": [
						{
							"fontFamily": "Instrument Sans",
							"fontStyle": "normal",
							"fontWeight": "400 700",
							"src": [
								"file:./assets/fonts/instrument-sans/InstrumentSans-VariableFont_wdth,wght.woff2"
							]
						},
						{
							"fontFamily": "Instrument Sans",
							"fontStyle": "italic",
							"fontWeight": "400 700",
							"src": [
								"file:./assets/fonts/instrument-sans/InstrumentSans-Italic-VariableFont_wdth,wght.woff2"
							]
						}
					],
					"fontFamily": "\"Instrument Sans\", sans-serif",
					"name": "Instrument Sans",
					"slug": "body"
				},
				{
					"fontFace": [
						{
							"fontFamily": "Jost",
							"fontStyle": "normal",
							"fontWeight": "100 900",
							"src": ["file:./assets/fonts/jost/Jost-VariableFont_wght.woff2"]
						},
						{
							"fontFamily": "Jost",
							"fontStyle": "italic",
							"fontWeight": "100 900",
							"src": [
								"file:./assets/fonts/jost/Jost-Italic-VariableFont_wght.woff2"
							]
						}
					],
					"fontFamily": "\"Jost\", sans-serif",
					"name": "Jost",
					"slug": "heading"
				},
				{
					"fontFamily": "-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif",
					"name": "System Sans-serif",
					"slug": "system-sans-serif"
				},
				{
					"fontFamily": "Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol",
					"name": "System Serif",
					"slug": "system-serif"
				}
			]
		}
	}
}