I recently signed up for Fränk Klein’s WordPress course Theme.json Explained. Frank has other courses but in the meantime I thought this basic course would be a good intro into to only theme.json but also his style of teaching. Here are my notes as I work though the course.

These notes are as much for me as they are you. This is a free course so go sign up as I won’t be mentioning everything plus there are videos to watch as well.

Email Course

My first email stated that “every day for the next 6 days, you’ll receive an email with the lesson of the day. Each lesson contains one or more videos teaching a particular feature of the theme.json file.” Sounds good. Let’s begin.

Day 1 – Set up theme.json

Learn how to set up the theme.json file on a 2020 hybrid theme and add the version number. Fränk mentions here to use schema (read more) but it’s not in the lesson (Throughout the examples below the theme.json will be abbreviated to show a certain lesson.)

theme.json

{
    "version": 2,
}

Just by adding the theme.json file it enables the template editor which you likely do not want for a hybrid theme. Here’s how you remove it:

functions.php

// remove the template editor
remove_theme_support( 'block-templates');

Day 2 – Adjust layout settings

Theme.json overrides the php support for the width layout settings (set up in the 2020 theme). We need to add it to our theme.json file instead. Once the layout settings and values are added the appropriate css is applied in the editor.

theme.json

{
    "version": 2,
    "settings": {
        "layout": {
            "contentSize": "610px",
            "wideSize": "1200px"
        }
    }
}

You still need the css styles on the frontend for hybrid themes. The example given was setting the content width on a group block. Think of this as the container classes you use in css to control the width of your site or if you ever set this in WordPress via php (I haven’t).

Day 3 – Custom presets

Custom presets are sets of key value pairs that you can define in theme.json that WP turns into css custom variables (properties) for your theme. The example given was on colors but it could include anything I suppose just like css.

theme.json

{
    "settings": {
        "custom": {
            "colors": {
                "black": "#000",
                "red": "#cd2653",
                "grey": "#6d6d6d"
            }
        }
    }
}

The css gets inlined on the frontend (removed all other inline styles):

<style id="global-styles-inline-css">
body {
    --wp--custom--colors--black: #000;
    --wp--custom--colors--red: #cd2653;
    --wp--custom--colors--grey: #6d6d6d;
}
</style>

As you’ll see we use these for setting colors on other elements and blocks, just as we can do in css.

Day 4 – Adding a custom palette

Similar to how custom colors are defined, a palette with an array of colors (notice the brackets in the syntax) can also be set. Since we already have some colors set up we can reference them by using the css var function in our palette but you could also just add the color code.

theme.json

{
    "settings": {
        "color": {
            "palette": [
                {
                    "name": "Accent Color",
                    "slug": "accent",
                    "color": "var(--wp--custom--colors--red)"
                }
            ]
        },
        "custom": {
            "colors": {
                "black": "#000",
                "red": "#cd2653",
                "grey": "#6d6d6d"
            }
        }
    }
}

We’ll add more to the palette but here’s editor’s palette after declaring the single accent color:

2020 hybrid theme with a custom palette accent color defined

Day 5 – Font Sizes

Implementing font sizes within the “settings” section of the theme.json file. We add a single font size called “small” that is 18px. You could also use other units such as rem. Once again we’re removing a function defined in this hybrid 2020 theme and instead adding it to the theme.json file.

theme.json

{
    "settings": {
        "typography": {
            "fontSizes": [
                {
                    "slug": "small",
                    "name": "Small",
                    "size": "18px"
                }
            ]
        }
    }
}

Day 6 – Styling

Here we explore another top level key which is “styles”. We explore this section of theme.json by setting up some base styles for the body of the site. The json structure of styles works like css specificity in that everything at the root level applies to the whole page (body) but you can also set other elements like you do in css. Here we defined the background and text colors, using our custom class values from before, and font size of the body.

theme.json

{
    "styles": {
        "color": {
            "background": "var(--wp--custom--colors--grey)",
            "text": "var(--wp--custom--colors--black)"
        },
        "typography": {
            "fontSize": "1.8rem"
        }
    }
}

Setting these base values applies the correct css to the frontend on the body element and on the backend to the .editor-styles-wrapper div to provide a consistent experience.

Day 7 – Styling elements and blocks

The last lesson shows a bit more about the style section of theme.json by implementing more specific styles on certain elements. You do this by using the “elements” key and targeting the specific selectors (h1, h2, etc.). In this example we style the h1 and h2 font sizes and the color of our links.

theme.json

{
    "styles": {
        "elements": {
            "h1": {
                "fontSize": "3.6rem"
            },
            "h2": {
                "fontSize": "3.2rem"
            },
            "link": {
                "color": {
                    "text": "var(--wp--custom--colors--red)"
                }
            }
        }
    }
}

Styling blocks is also done within the styles key but instead of elements we use “blocks”. In this example we’re styling the quote block by using the unique block slug to target the block then styling the border.

theme.json

{
    "styles": {
        "blocks": {
            "core/quote": {
                "border": {
                    "color": "var(--wp--custom--colors--red)"
                }

            }
        }
    }
}

This theme.json reference will likely come in handy so you can view all the settings and option names.

That’s it!

This course was easy enough that I could do it pretty quickly each day and gave me a glimpse into not only what the theme.json was but also how it affects your theme. While I somewhat knew how this all worked, it’s one thing to read about it, but it’s another to actually do it. I enjoyed setting something up in theme.json then seeing the options it gave me and inspecting to see the css as well to see what changed.

If you have Local installed and 5-20 minutes a day, depending on how much you want to explore, give this free course a try. It’s brief enough to not feel overwhelming if you are busy and simple enough that anyone could learn.

Thoughts & Notes:

  • Instead of writing CSS I’m writing json. I don’t like the trade-off.
  • I dislike json format. No comments and lots of commas and quotation marks everywhere. Adding the schema turns on autocomplete and using json with comments in VS Code really helps.
  • Writing json removes the necessity of a backend stylesheet (editor stylesheet) that tries to match your frontend stylesheet. If you want them to match this is pretty huge.
  • I now better understand the why behind this file.
  • A benefit is that it allows WP to control the markup allowing future changes within WP much easier to deal with. I’ve heard of nightmares where WP just changes classes or markup which makes any custom css obsolete.