Standardizing Theme.json Site Spacing in WordPress Block Themes

EDIT: I’ve updated this post to use the new spacing preset values provided in WordPress 6.1.

This is part three, of three, in a series on standardizing how we build this next generation of WordPress block themes to accompany the Full Site Editing effort.

If you like this article on spacing, read on about standardizing color slugs, and standardizing font sizes. Each of these are what I would consider core design tenets of a website, of which should be functionally standardized.

As I mention in my other articles in this series, by standardizing just key high-level entries within a WordPress theme’s theme.json file, we can finally create a class of themes that truly are interchangeable. Interchangeable in function, while remaining distinct in style.

So here’s my take on spacing.

What do I mean by “spacing”?

Spacing is an ambiguous term, but I’m referring to the baseline spacing that occurs between elements that may be implemented as padding and margin in the form of “white space”.

White space is the blank area around, inside, or between the various elements of a site. The proper use of white space instills a form of “silence” between content, allowing for improved comprehension, balance, rhythm and visual hierarchy.

White spac
White space is the blank area around, inside, or between the various elements of a site

In the context of a WordPress theme, think of the left/right site padding between a page’s content and the viewport, the padding that is applied to a Group block with a background color, the space between Paragraph blocks, or even the gap between columns.

All of these are what I believe should be applied in a systematic fashion, were one or two values can determine the baseline spacing of a site.

So here’s what I’ve explored, and what could unlock a whole new level of simplicity in designing block themes.

Using a consistent spacing scale

While my previous articles on standardizing color and font size slugs within theme.json files is a quicker — edit one file and you’re done — solution, this concept has a bit more weight to it.

First, within the theme.json file, you’ll want to add a spatial scale in settings.spacing. You can assign a spacingScale or implement custom spacingSizes for the block theme.

Here’s how spacingScale works, where the iterations are mapped out for you:

"settings": {
     "spacing": {
	"spacingScale": {
	   "operator": "*",
	   "increment": 2,
	   "steps": 7,
	   "mediumStep": 1.5,
	   "unit": "rem"

What we’re doing here is adding a spatial scale that multiplies for each of the seven levels, by the 1.5rem baseline value.

These values will will then be accessible as a CSS custom property within the block editor, as well as the front-end:

body {
  --wp--preset--spacing--20: 0.63rem;
  --wp--preset--spacing--30: 1.25rem;
  --wp--preset--spacing--40: 2.5rem;
  --wp--preset--spacing--50: 5rem;
  --wp--preset--spacing--60: 10rem;
  --wp--preset--spacing--70: 20rem;
  --wp--preset--spacing--80: 40rem;

And now we can use these values within the theme.json file, and in any of the theme’s block patterns, to allow that one entry to define consistent spacing across the site.

Add custom spacing sizes

Now while spacingScale does allow for a quick and easy spacing mechanism, you may want to leverage custom spacing sizes throughout a site’s design.

You can do that by leveraging the spacingSizes object, like this:

"settings": {
     "spacing": {
	"spacingSizes": [
	          "size": "min(12px, 2vw)",
	          "slug": "20",
	          "name": "2"
	          "size": "min(40px, 4vw)",
	          "slug": "30",
	          "name": "3"

Just add the sizes for each slug 20-70 and you’ll have replaced the out-of-the-box values provided by WordPress core, with your own spacing sizes.

body {
  --wp--preset--spacing--20: min(12px, 2vw);
  --wp--preset--spacing--30: min(40px, 4vw);

This way, if someone applies the spacing size of 20 to a template (then changes themes) they’ll have whatever the theme provides as the smallest spacing value --wp--preset--spacing--20 applied — instead of loosing the spacing altogether.

Supporting block gaps

There’s been quite a bit of work on how block themes can set the spacing between child blocks, such as a flex layout Group block, or the columns within a parent Columns block.

This PR on Github addresses how the block gap will apply to blocks that opt-into the new feature.

A proposal for how block gap will work, sourced from this PR.

This aims to have the block gap support added to the styles.spacing.blockGap, object like this:

"styles": {
    "spacing": {
        "blockGap": "var(--wp--preset--spacing--30)"

That would generate the --wp--style--block-gap CSS property to use throughout the theme’s styling, and set the default value for whichever blocks that support setting a gap between blocks.

What do you think?

A clear and consistent systematic approach to spacing, that works across themes, is huge for unlocking the creative potential of themes — while also making them that much easier to build with.

I recommend that every block theme supports the spacingScale , or spacingSizes (but with the standard integer values) — to encourage portability to, and from, each WordPress theme.

For folks diving into building WordPress block themes, have you implemented a system like this here, or have any other ideas?

I’d love to hear your thoughts — @richard_tabor.

If you like this article on site spacing, read the others in this standardization series covering color slugs and font sizes.