Defining Global Settings

Avatar of Ganesh Dahal
Ganesh Dahal on (Updated on )

Let’s take what we learned about the theme.json structure in WordPress block themes and apply it to two main sections of the file: settings and styles. These arrays are the “top level” for configuring WordPress features and the theme’s CSS output.

So far, we’ve spent time getting familiar with theme.json, the foundation for all WordPress block themes. We covered the various JSON data types and common terminology related to working with the JSON syntax.

We are going to build on that knowledge in this article.

Table of contents


What we mean by “top level”

We discussed how JSON has a structured syntax. We can see that in the basic outline of the theme.json file:

{
  "version": 2,
  "settings": {},
  "styles": {},
  "customTemplates": {},
  "templateParts": {}
}

Each object in the basic outline is a “top level” of the file. You can think of the objects as sections where various things are configured. Disregarding the version, there are four top-level sections:

  • settings: This is where we define WordPress presets and defaults; it’s also where we can enable or disable certain WordPress features.
  • styles: This is where we define CSS for global and block-level theme styles.
  • customTemplates: This is where we register new custom theme templates. It’s the equivalent of dropping a new PHP template file in a classic theme.
  • templateParts: This section contains modular pieces that can be included in templates. It’s the equivalent of the parts subfolder you typically see in classic themes.

We’re spending most of our time in the settings and styles sections. Both provide ways to configure the global styles of a WordPress block theme. So, let’s look at each one and the various options we have to customize the theme appearance.

The settings section (settings)

Again, this is where we configure WordPress features, sort of like the add_theme_support function you’d reach for in a classic theme’s functions.php file.

{
  "version": 2,
  "settings": {
    // etc.
  }
}

Why is this relevant to a theme’s global styles? Several WordPress features affect styling, like UI controls for padding, margins, colors, and fonts. Without enabling those, there’s no way to apply these and other styles in the Global Styles UI in the Site Editor.

In short: what we define here is what WordPress uses to add theme support for the Site Editor’s global style settings that are used throughout the theme.

Supported features

The WordPress Block Editor Handbook provides a table that outlines available features we can enable in the settings section and compares them to their equivalent add_theme_support function arguments.

Theme JSON settingsadd_theme_support
color.customcustom-colors
color.paletteeditor-color-palette
color.gradientseditor-gradient-presets
spacing.paddingcustom-spacing
spacing.unitscustom-units
typography.lineHeightcustom-line-height
typography.fontSizeseditor-font-sizes
useRootPaddingAwareAlignmentsN/A

For example, you were using add_theme_support in your classic theme to disable custom font sizes:

<?php
add_theme_support(disable-custom-font-sizes);

The equivalent in theme.json is the settings.typography.customFontSize property:

{
  "version": 2,
  "settings": {
    "typography": {
      "customFontSize": false;
    }
  }
}

As you might imagine, there are nested features within these features. For example, if we were adding support for spacing controls, there are a number of spacing-related features we can individually enable:

{
  "version": 2,
  "settings": {
    "spacing": {
      "margin": false,
      "padding": false,
      "blockGap": null,
      "units": [ "px", "em", "rem", "vh", "vw" ]
    },
  }
}

As of WordPress 6.1, these are the settings features that can be configured in theme.json:

View full table
SettingFeatureData type
borderradiusBoolean
colorBoolean
styleBoolean
widthBoolean
colorcustomBoolean
customDuotoneBoolean
customGradientBoolean
duotoneArray
gradientsArray
linkBoolean
paletteArray
textBoolean
backgroundBoolean
defaultGradientsBoolean
defaultPaletteBoolean
layoutcontentSizeString
wideSizeString
typeString (default and constrained)
spacingmarginBoolean
paddingBoolean
blockGapString
unitsArray
typographycustomFontSizeBoolean
lineHeightBoolean
dropCapBoolean
fontStyleBoolean
fontWeightBoolean
letterSpacingBoolean
textDecorationBoolean
textTransformBoolean
fontSizesArray
fontFamiliesArray

There are ongoing discussions to add the outline and border properties to the Global Styles panel. They are included in this table before formal adoption.

The appearanceTools shorthand

I know that the table shows a ton of features. Configuring each setting could get cumbersome. That’s where the appearanceTools setting comes into play.

{
  "version": 2,
  "settings": {
    "appearanceTools": true
  }
}

Setting it to true enables the following settings in one fell swoop:

{
  "version": 2,
  "settings": {
    "border": {
      "color": true,
      "radius": true,
      "style": true,
      "width": true
    },
    "color": {
      "link": true
    }
    "spacing": {
      "margin": true,
      "padding": true,
      "blockGap": true,
    },
    "typography": {
      "lineHeight": true
    }
  }
}

You can see how many lines of code we can save this way! But let’s say you want to take advantage of appearanceTools, but disable one or two of its supported features. You can do that on an individual basis to override that particular setting:

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "border": {
      "radius": false
    }
  }
}

The following screenshot shows how setting appearanceTools to true exposes those controls in the Global Styles UI, taken from the default Twenty Twenty-Three theme.

The WordPress Site Editor.

This Learn WordPress video by Nick Diego explains the appearanceTools properties and the Global Styles interface in great detail.

Padding-aware alignments

This feature is worth calling out because it shipped more recently than many other features as part of WordPress 6.1. It is another shortcut for setting two spacing features.

So, this:

{
  "version": 2,
  "settings": {
    "useRootPaddingAwareAlignments": true
  }
}

…is the equivalent of this:

{
  "version": 2,
  "settings": {
    "spacing": {
      "margin": true,
      "padding": true
    },
  }
}

The real benefit of useRootPaddingAwareAlignments is in the name. By enabling it, we opt into a feature that defines global padding on the <body> of our theme and allows blocks to “break out” of that padding and go full-width if we need a block to span edge-to-edge.

See my previous article for a detailed overview of padding-aware alignments.

Configuring preset values

Presets are predefined values used by Global Styles features. More specifically, they define CSS custom properties used throughout a block theme.

So, let’s say you are defining your block theme’s default color palette and add black (#000000) to it:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          "color": "#000000",
          "name": "Base",
          "slug": "base"
        }
      ]
    }
  }
}

Behind the scenes, something called the Style Engine takes those values and generates the theme’s CSS classes and custom properties. I described the Style Engine in a previous article:

The Style Engine is a new API in WordPress 6.1 that is meant to bring consistency to how styles are generated and where styles are applied. In other words, it takes all of the possible sources of styling and is singularly responsible for properly generating block styles. […] Having a centralized API for styles is probably the most elegant solution given that styles can come from a number of places.

When the Style Engine notices our styles, it creates a set of preset custom properties. For example, that color palette example above? It produces a CSS custom property based on the information we supply it.

If we were to open up DevTools and inspect the <body> element, we would see our custom properties there:

DevTools window showing CSS custom variables on the body element.

Notice how the custom property names are formatted:

--wp-preset--<feature>--<slug>: <value>

So, going back to our original example where we defined black in a color palette:

"color": {
  "palette": [
    {
      "color": "#000000",
      "name": "Base",
      "slug": "Base"
    }
  ]
}

We can expect to find this custom property applied to the <body> element:

body {
  --wp--preset--color--base: #000000;
}

All we’ve looked at are settings.color presets, but nearly every value we define in the settings section results in a custom property:

{
  "version": 2,
  "settings": {
    "spacing": {
      "spacingSizes": [
        {
          // Creates: --wp-preset--spacing--40: 1rem
          "slug": "40",
          "size": "1rem",
          "name": "Small"
        },
        // etc.
      ]
    }
  }
}

Global presets

Now that we know how to define preset values in theme.json, you might want to know what presets are available. The following table outlines what is currently available as of this writing and what they produce.

SettingFeatureCSS custom propertyCSS class
colorduotoneN/AN/A
gradients--wp-preset--gradient--<preset-slug>.has-<preset-slug>-<preset-category>
palette--wp--preset--palette--<preset-slug>Three classes per value:

.has-<preset-value>-color

.has-<preset-value>-background-color

.has-<preset-value>-border-color
spacingspacingScaleN/AN/A
spacingSizes--wp--preset--spacing--<preset-slug>.has-<preset-slug>-spacing
typographyfontSizes--wp--preset--font-size--<preset-slug>.has-<preset-slug>-font-size
fontFamilies--wp--preset--font-family--<preset-slug>.has-<preset-slug>-font-family

Block presets

We can get more granular when defining preset values in theme.json. In addition to the global presets we just saw, we can define presents at the block level.

Let’s say we have the following global color presets:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        {
          // --wp-preset--color--base: #ffffff
          "color": "#FFFFFF",
          "name": "Base",
          "slug": "base"
        },
        {
          // --wp-preset--color--contrast: #000000
          "color": "#000000",
          "name": "Contrast",
          "slug": "contrast"
        }
      ]
    }
  }
}

The custom properties generated by those settings are used throughout the theme, including blocks. So, if we were to add a Separator block to a page in the Block Editor, it will refer to the same color palette when it renders.

But we can override that palette — or any of the others in the global settings — with a palette specifically for the Separator block:

{
  "version": 2,
  "settings": {
    "color": {
      "palette": [ // etc. ]
    },
    "blocks": {
      "separator": {
        "color": {
          "palette": [
            {
              "color": "#F8A100",
              "name": "Orange",
              "slug": "orange"
            }
          ]
        }
      }
    }
  }
}

In this example, the Separator block’s palette overrides the global palette with a single orange (#F8A100) color value.

Custom presets

You can also create “custom” CSS custom properties on any property. In addition to the settings features we’ve looked at so far, there is a custom property where we can do that.

{
  "version": 2,
  "settings": {
    "custom": {
      // etc.
    }
  }
}

The Style Engine takes anything we define in there and generates CSS custom properties from it. The naming convention is pretty similar to the custom properties generated by the other settings:

--wp--custom--<variable-name>: <value>

Your defined values in custom will be transformed into CSS custom properties and use the --wp--custom--<variable-name> naming convention.

Here’s an abbreviated example of custom settings pulled straight from the default Twenty Twenty-Two theme. In it are custom settings for typography.font-size and typography.line-height:

{
  "version": 2,
  "settings": {
    "custom": {
      "typography": {
        "font-size": {
          "huge": "clamp(2.25rem, 4vw, 2.75rem)",
          "gigantic": "clamp(2.75rem, 6vw, 3.25rem)",
          "colossal": "clamp(3.25rem, 8vw, 6.25rem)"
        },
        "line-height": {
          "tiny": 1.15,
          "small": 1.2,
          "medium": 1.4,
          "normal": 1.6
        }
      }
    }
  }
}

Wrapping up

We learned a great deal about the settings section of the theme.json file. We covered the available settings and how they are used to define global styles that are used in the Global Styles UI of the WordPress Site Editor. From there, we learned about preset values, including which ones we can configure and how they are generated into CSS custom properties by the Style Engine.

What we haven’t covered is how we can use theme.json to define CSS styles in a block theme. That happens in another top-level section called styles, which is the focus of the next part of this series.