wordpress themes – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Tue, 13 Dec 2022 16:27:44 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 wordpress themes – CSS-Tricks https://css-tricks.com 32 32 45537868 Adding Box Shadows to WordPress Blocks and Elements https://css-tricks.com/adding-box-shadows-to-wordpress-blocks-and-elements/ https://css-tricks.com/adding-box-shadows-to-wordpress-blocks-and-elements/#respond Wed, 07 Dec 2022 13:59:50 +0000 https://css-tricks.com/?p=375412 The CSS box-shadow and outline properties gained theme.json support in WordPress 6.1. Let's look at a few examples of how it works in real themes, and what options we have to apply these styles to WordPress blocks and elements.


Adding Box Shadows to WordPress Blocks and Elements originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I stumbled across this tweet from Ana Segota looking for a way to add a CSS box-shadow to a button’s hover state in WordPress in the theme.json file.

She’s asking because theme.json is where WordPress wants us to start moving basic styles for block themes. Traditionally, we’d do any and all styling in style.css when working in a “classic” theme. But with the default Twenty Twenty-Three (TT3) theme that recently shipped with WordPress 6.1 moving all of its styles to theme.json, we’re getting closer and closer to being able to do the same with our own themes. I covered this in great detail in a recent article.

I say “closer and closer” because there are still plenty of CSS properties and selectors that are unsupported in theme.json. For example, if you’re hoping to style something with like perspective-origin in theme.json, it just won’t happen — at least as I’m writing this today.

Ana is looking at box-shadow and, luckily for her, that CSS property is supported by theme.json as of WordPress 6.1. Her tweet is dated Nov. 1, the same exact day that 6.1 released. It’s not like support for the property was a headline feature in the release. The bigger headlines were more related to spacing and layout techniques for blocks and block themes.

Here’s how we can apply a box-shadow to a specific block — say the Featured Image block — in theme.json:

{
  "version": 2,
  "settings": {},
  // etc.
  "styles": {
    "blocks" :{
      "core/post-featured-image": {
        "shadow": "10px 10px 5px 0px rgba(0, 0, 0, 0.66)"
      }
    }
  }
}

Wondering if the new color syntax works? Me too! But when I tried — rgb(0 0 0 / 0.66) — I got nothing. Perhaps that’s already in the works or could use a pull request.

Easy, right? Sure, it’s way different than writing vanilla CSS in style.css and takes some getting used to. But it is indeed possible as of the most recent WordPress release.

And, hey, we can do the same thing to individual “elements”, like a button. A button is a block in and of itself, but it can also be a nested block within another block. So, to apply a box-shadow globally to all buttons, we’d do something like this in theme.json:

{
  "version": 2,
  "settings": {},
  // etc.
  "styles": {
    "elements": {
      "button": {
        "shadow": "10px 10px 5px 0px rgba(0,0,0,0.66)"
      }
    }
  }
}

But Ana wants to add the shadow to the button’s :hover state. Thankfully, support for styling interactive states for certain elements, like buttons and links, using pseudo-classes — including :hover, :focus, :active, and :visited — also gained theme.json support in WordPress 6.1.

{
  "version": 2,
  "settings": {},
  // etc.
  "styles": {
    "elements": {
      "button": {
        ":hover": {
          "shadow": "10px 10px 5px 0px rgba(0,0,0,0.66)"
        }
      }
    }
  }
}

If you’re using a parent theme, you can certainly override a theme’s styles in a child theme. Here, I am completely overriding TT3’s button styles.

View full code
{
  "version": 2,
  "settings": {},
  // etc.
  "styles": {
    "elements": {
      "button": {
        "border": {
          "radius": "0"
        },
        "color": {
          "background": "var(--wp--preset--color--tertiary)",
          "text": "var(--wp--preset--color--contrast)"
        },
        "outline": {
          "offset": "3px",
          "width": "3px",
          "style": "dashed",
          "color": "red"
        },
        "typography": {
          "fontSize": "var(--wp--preset--font-size--medium)"
        },
        "shadow": "5px 5px 5px 0px rgba(9, 30, 66, 0.25), 5px 5px 5px 1px rgba(9, 30, 66, 0.08)",
        ":hover": {
          "color": {
            "background": "var(--wp--preset--color--contrast)",
            "text": "var(--wp--preset--color--base)"
          },
          "outline": {
            "offset": "3px",
            "width": "3px",
            "style": "solid",
            "color": "blue"
          }
        },
        ":focus": {
          "color": {
            "background": "var(--wp--preset--color--contrast)",
            "text": "var(--wp--preset--color--base)"
          }
        },
        ":active": {
          "color": {
            "background": "var(--wp--preset--color--secondary)",
            "text": "var(--wp--preset--color--base)"
          }
        }
      }
    }
  }
}

Here’s how that renders:

Showing two red buttons with box shadows.
The button’s natural state (left) and it’s hovered state (right)

Another way to do it: custom styles

The recently released Pixl block theme provides another example of real-world usage of the box-shadow property in theme.json using an alternative method that defines custom values. In the theme, a custom box-shadow property is defined as .settings.custom.shadow:

{
  "version": 2,
  "settings": {
    // etc. 
    "custom": {
      // etc.
      "shadow": "5px 5px 0px -2px var(--wp--preset--color--background), 5px 5px var(--wp--preset--color--foreground)"
    },
    // etc.
  }
}

Then, later in the file, the custom shadow property is called on a button element:

{
  "version": 2,
  "settings": {
    // etc.
  },
  "styles": {
    "elements": {
      "button": {
        // etc.
        "shadow": "var(--wp--custom--shadow) !important",
        // etc.
        ":active": {
          // etc.
          "shadow": "2px 2px var(--wp--preset--color--primary) !important"
        }
      },
    // etc.
  }
}

I’m not totally sure about the use of !important in this context. My hunch is that it’s an attempt to prevent overriding those styles using the Global Styles UI in the Site Editor, which has high specificity than styles defined in theme.json. Here’s an anchored link to more information from my previous article on managing block theme styles.

Update: Turns out there was a whole discussion about this in Pull Request #34689, which notes that it was addressed in WordPress 5.9.

And there’s more…

In addition to shadows, the CSS outline property also gained theme.json support in WordPress 6.1 and can be applied to buttons and their interactive states. This GitHub PR shows a good example.

"elements": {
  "button": {
    "outline": {
      "offset": "3px",
      "width": "3px",
      "style": "dashed",
      "color": "red"
    },
    ":hover": {
      "outline": {
        "offset": "3px",
        "width": "3px",
        "style": "solid",
        "color": "blue"
      }
    }
  }
}

You can also find the real examples of how the outline property works in other themes, including Loudness, Block Canvas, and Blockbase.

Wrapping up

Who knew there was so much to talk about with a single CSS property when it comes to block theming in WordPress 6.1? We saw the officially supported methods for setting a box-shadow on blocks and individual elements, including the interactive states of a button element. We also checked out how we could override shadows in a child theme. And, finally, we cracked open a real-world example that defines and sets shadows in a custom property.

You can find more detailed in-depth discussions about the WordPress and it’s box-shadow implementation in this GitHub PR. There is also a GitHub proposal for adding UI directly in WordPress to set shadow values on blocks — you can jump directly to an animated GIF showing how that would work.

Speaking of which, Justin Tadlock recently developed a block that renders a progress bar and integrated box shadow controls into it. He shows it off in this video:

More information

If you’d like to dig deeper into the box-shadow and other CSS properties that are supported by the theme.json file in a block theme, here are a couple of resources you can use:


Adding Box Shadows to WordPress Blocks and Elements originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/adding-box-shadows-to-wordpress-blocks-and-elements/feed/ 0 https://www.youtube.com/embed/TMd3NHBPZ-8 Box Shadow Control with the Progress Bar WordPress Block nonadult 375412
Using The New Constrained Layout In WordPress Block Themes https://css-tricks.com/using-the-new-constrained-layout-in-wordpress-block-themes/ https://css-tricks.com/using-the-new-constrained-layout-in-wordpress-block-themes/#comments Wed, 30 Nov 2022 14:11:10 +0000 https://css-tricks.com/?p=375278 One of the main goals of the WordPress Site Editor (and, yes, that is now the “official” name) is to move basic block styling from CSS to structured JSON. JSON files are machine-readable, which makes it consumable by …


Using The New Constrained Layout In WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
One of the main goals of the WordPress Site Editor (and, yes, that is now the “official” name) is to move basic block styling from CSS to structured JSON. JSON files are machine-readable, which makes it consumable by the JavaScript-based Site Editor for configuring a theme’s global styles directly in WordPress.

It’s not all the way there yet! If we look at the Twenty Twenty-Two (TT2) default theme, there were two main unresolved issues: styling interactions (like :hover, :active, :focus), and the margins and padding of layout containers. You can see how those were temporarily fixed in the TT2 style.css file rather than making it into the theme.json file.

WordPress 6.1 fixed those issues and what I want to do is look specifically at the latter. Now that we have JSON-ified styles for the margins and padding of layout containers, that opens us up to more flexible and robust ways to define spacing in our theme layouts.

What kind of spacing are we talking about?

First off, we already have root-level padding which is a fancy way of describing padding on the <body> element. That’s nice because it ensures consistent spacing on an element that is shared on all pages and posts.

But there’s more to it because now we have a way for blocks to bypass that padding and align themselves full-width. That’s thanks to padding-aware alignments which is a new opt-in feature in theme.json. So, even if you have root-level padding, you can still allow, say, an image (or some other block) to break out and go full-width.

That gets us to another thing we get: constrained layouts. The idea here is that any blocks nested in the layout respect the layout’s content width — which is a global setting — and do not flow outside of it. We can override that behavior on a block-by-block basis with alignments, but we’ll get to that.

Let’s start with…

Root-level padding

Again, this isn’t new. We’ve had the ability to set padding on the <body> element in theme.json since the experimental Gutenberg plugin introduced it in version 11.7. We set it on the styles.spacing object, where we have margin and padding objects to define the top, right, bottom, and left spacing on the body:

{
  "version": 2,
  "styles": {
    "spacing": {
      "margin": {
        "top": "60px",
        "right": "30px",
        "bottom": "60px",
        "left": "30px"
      },
      "padding": {
        "top": "30px",
        "right": "30px",
        "bottom": "30px",
        "left": "30px"
      }
    }
  }
}

This is a global setting. So, if we were to crack open DevTools and inspect the <body> element, we would see these CSS styles:

body {
  margin-top: 60px;
  margin-right: 30px;
  margin-bottom: 60px;
  margin-left: 30px;
  padding-top: 30px;
  padding-right: 30px;
  padding-bottom: 30px;
  padding-left: 30px;
}

Cool. But herein lies the issue of how in the world we can allow some blocks to break out of that spacing to fill the full screen, edge-to-edge. That’s why the spacing is there, right? It helps prevent that from happening!

But there are indeed plenty of cases where you might want to break out of that spacing on a one-off instance when working in the Block Editor. Say we plop an Image block on a page and we want it to go full-width while the rest of the content respects the root-level padding?

Enter…

Padding-aware alignments

While attempting to create the first default WordPress theme that defines all styles in the theme.json file, lead designer Kjell Reigstad illustrates the challenging aspects of breaking out of root-level padding in this GitHub issue.

Root-level padding prevents blocks from taking up the full viewport width (left). But with padding-aware alignments, some blocks can “opt-out” of that spacing and take up the full viewport width (right). (Image credit: Kjell Reigstad)

New features in WordPress 6.1 were created to address this issue. Let’s dig into those next.

useRootPaddingAwareAlignments

A new useRootPaddingAwareAlignments property was created to address the problem. It was actually first introduced in the Gutenberg plugin v13.8. The original pull request is a nice primer on how it works.

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "useRootPaddingAwareAlignments": true,
    // etc.
  },

Right off the bat, notice that this is a feature we have to opt into. The property is set to false by default and we have to explicitly set it to true in order to enable it. Also notice that we have appearanceTools set to true as well. That opts us into UI controls in the Site Editor for styling borders, link colors, typography, and, yes, spacing which includes margin and padding.

Setting appearanceTools set to true automatically opts blocks into margin and padding without having to set either settings.spacing.padding or setting.spacing.margin to true.

When we do enable useRootPaddingAwareAlignments, we are provided with custom properties with root padding values that are set on the <body> element on the front end. Interestingly, it also applies the padding to the .editor-styles-wrapper class so the spacing is displayed when working in the back-end Block Editor. Pretty cool!

I was able to confirm those CSS custom properties in DevTools while digging around.

Enabling useRootPaddingAwareAlignments also applies left and right padding to any block that supports the “content” width and “wide” width values in the Global Styles image above. We can also define those values in theme.json:

{
  "version": 2,
  "settings": {
    "layout": {
      "contentSize": "640px",
      "wideSize": "1000px"
    }
  }
}

If the Global Styles settings are different than what is defined in theme.json, then the Global Styles take precedence. You can learn all about managing block theme styles in my last article.

  • contentSize is the default width for blocks.
  • wideSize provides a “wide” layout option and establishes a wider column for blocks to stretch out.

So, that last code example will give us the following CSS:

/* The default content container */
.wp-container-[id] > * {
  max-width: 640px;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* The wider content container */
.wp-container-[id] > .alignwide {
  max-width: 1000px;
}

[id] indicates a unique number automatically generated by WordPress.

But guess what else we get? Full alignment as well!

.wp-container-[id] .alignfull {
  max-width: none;
}

See that? By enabling useRootPaddingAwareAlignments and defining contentSize and wideSize, we also get a full alignment CSS class for a total of three container configurations for controlling the width of blocks that are added to pages and posts.

This applies to the following layout-specific blocks: Columns, Group, Post Content, and Query Loop.

Block layout controls

Let’s say we add any of those aforementioned layout-specific blocks to a page. When we select the block, the block settings UI offers us new layout settings based on the settings.layout values we defined in theme.json (or the Global Styles UI).

We’re dealing with very specific blocks here — ones that can have other blocks nested inside. So, these Layout settings are really about controlling the width and alignment of those nested blocks. The “Inner blocks use content width” setting is enabled by default. If we toggle it off, then we have no max-width on the container and the blocks inside it go edge-to-edge.

If we leave the toggle on, then nested blocks will adhere to either the contentWidth or wideWidth values (more on that in a bit). Or we can use the numeric inputs to define custom contentWidth and wideWidth values in this one-off instance. That’s great flexibility!

Wide blocks

The settings we just looked are set on the parent block. Once we’ve nested a block inside and select it, we have additional options in that block to use the contentWidth, wideWidth, or go full-width.

This Image block is set to respect the contentWidth setting, labeled “None” in the contextual menu, but can also be set to wideWidth (labeled “Wide width”) or “Full width”.

Notice how WordPress multiplies the root-level padding CSS custom properties by -1 to create negative margins when selecting the “Full width” option.

The .alignfull class sets negative margins on a nested block to ensure it takes up the full viewport width without conflicting with the root-level padding settings.

Using a constrained layout

We just covered the new spacing and alignments we get with WordPress 6.1. Those are specific to blocks and any nested blocks within blocks. But WordPress 6.1 also introduces new layout features for even more flexibility and consistency in a theme’s templates.

Case in point: WordPress has completely restructured its Flex and Flow layout types and gave us a constrained layout type that makes it easier to align block layouts in themes using the content width settings in the Site Editor’s Global Styles UI.

Flex, Flow, and Constrained layouts

The difference between these three layout types is the styles that they output. Isabel Brison has an excellent write-up that nicely outlines the differences, but let’s paraphrase them here for reference:

  • Flow layout: Adds vertical spacing between nested blocks in the margin-block direction. Those nested blocks can also be aligned to the left, right, or center.
  • Constrained layout: Same exact deal as a Flow layout, but with width constraints on nested blocks that are based on the contentWidth and wideWidth settings (either in theme.json or Global Styles).
  • Flex layout: This was unchanged in WordPress 6.1. It uses CSS Flexbox to create a layout that flows horizontally (in a row) by default, but can flow vertically as well so blocks stack one on top of another. Spacing is applied using the CSS gap property.

This new slate of layout types creates semantic class names for each layout:

Semantic layout classLayout typeSupported blocks
.is-layout-flowFlow layoutColumns, Group, Post Content, and Query Loop.
.is-layout-constrainedConstrained layoutColumns, Group, Post Content, and Query Loop.
.is-layout-flexFlex layoutColumns, Buttons, Social Icons

Justin Tadlock has an extensive write-up on the different layout types and semantic classes, including use cases and examples.

Updating your theme to support constrained layouts

If you’re already using a block theme of your own making, you’re going to want to update it to support constrained layouts. All it takes is swapping out a couple of things in theme.json:

{
  "version": 2,
  "settings": {
    "layout": {
      "type": "constrained", // replaces `"inherit": true`
      "type": "default", // replaces `"inherit": false`
    }
  }
}

These are recently released block themes that have enabled spacing settings with useRootPaddingAwareAlignments and have an updated theme.json file that defines a constrained layout:

ThemeRoot-level paddingConstrained layout features
TT3Source codeSource codeTemplates
ProWPSource codeSource codeTemplates
TriangulateSource codeSource codeTemplates
OaknutSource codeSource codeTemplates
LoudnessSource codeSource codeTemplates
PixlSource codeSource codeTemplates
Block CanvasSource codeSource code, Templates
RainfallSource codeSource codeTemplates

Disabling layout styles

The base layout styles are default features that ship in WordPress 6.1 Core. In other words, they’re enabled right out of the box. But we can disable them if we need to with this little snippet in functions.php:

// Remove layout styles.
add_theme_support( 'disable-layout-styles' );

Big warning here: disabling support for the default layout types also removes all of the base styling for those layouts. That means you’ll need to roll your own styles for spacing, alignments, and anything else needed to display content in different template and block contexts.

Wrapping up

As a great fan of full-width images, the new contained WordPress 6.1 layout and padding aware alignment features are two of my most favorites yet. Taken together with other tools including, better margin and padding control, fluid typography, and updated List and Quote blocks, among others, is solid proof that WordPress is moving towards a better content creation experience.

Now, we have to wait and look at how the imagination and creativity of ordinary designers and content creators use these incredible tools and take it to a new level.

Because of the site editor development iterations in progress, we should always anticipate a difficult path ahead. However, as an optimist, I am eager to see what will happen in the upcoming version of WordPress 6.2. Some of the thing, that I am keeping a close eye on are things like features being considered for inclusion, support for sticky positioning, new layout class names for inner block wrappers, updated footer alignment options, and adding constrained and flow layout options to Cover blocks.

This GitHub issues #44720 lists the layout related discussions slated for WordPress 6.2.

Additional resources

I consulted and referenced a lot of sources while digging into all of this. Here’s a big ol’ list of things I found helpful and think you might enjoy as well.

Tutorials

WordPress posts

GitHub pull requests and issues


Using The New Constrained Layout In WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/using-the-new-constrained-layout-in-wordpress-block-themes/feed/ 5 375278
Managing CSS Styles in a WordPress Block Theme https://css-tricks.com/managing-css-styles-in-a-wordpress-block-theme/ https://css-tricks.com/managing-css-styles-in-a-wordpress-block-theme/#comments Mon, 07 Nov 2022 14:05:11 +0000 https://css-tricks.com/?p=374910 The way we write CSS for WordPress themes is in the midst of sweeping changes. I recently shared a technique for adding fluid type support in WordPress by way of theme.json, a new file that WordPress has been pushing


Managing CSS Styles in a WordPress Block Theme originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The way we write CSS for WordPress themes is in the midst of sweeping changes. I recently shared a technique for adding fluid type support in WordPress by way of theme.json, a new file that WordPress has been pushing hard to become a central source of truth for defining styles in WordPress themes that support full-site editing (FSE) features.

Wait, no style.css file? We still have that. In fact, style.css is still a required file in block themes, though its role is greatly reduced to meta information used for registering the theme. That said, the fact is that theme.json is still in active development, meaning we’re in a transitional period where you might find styles defined there, in styles.css or even at the block level.

So, what does styling actually look like in these WordPress FSE days? That’s what I want to cover in this article. There’s a lack of documentation for styling block themes in the WordPress Theme Developer Handbook, so everything we’re covering here is what I’ve gathered about where things currently are as well as discussions about the future of WordPress theming.

The evolution of WordPress styles

The new developmental features that are included in WordPress 6.1 get us closer to a system of styles that are completely defined in theme.json, but there is still be plenty of work to do before we can fully lean on it. One way we can get an idea of what’s coming in future releases is by using the Gutenberg plugin. This is where experimental features are often given a dry run.

Another way we can get a feel for where we are is by looking at the evolution of default WordPress themes. To date, there are three default themes that support full-site editing:

But don’t start trading the CSS in style.css for JSON property-value pairs in theme.json just yet. There are still CSS styling rules that need to be supported in theme.json before we think about doing that. The remaining significant issues are currently being discussed with an aim to fully move all the CSS style rules into theme.json and consolidate different sources of theme.json into a UI for for setting global styles directly in the WordPress Site Editor.

The Global Styles UI is integrated with the right panel in the Site Editor. (Credit: Learn WordPress)

That leaves us in a relatively tough spot. Not only is there no clear path for overriding theme styles, but it’s unclear where the source of those styles even come from — is it from different layers of theme.json files, style.css, the Gutenberg plugin, or somewhere else?

Why theme.json instead of style.css?

You might be wondering why WordPress is moving toward a JSON-based definition of styles instead of a traditional CSS file. Ben Dwyer from the Gutenberg development team eloquently articulates why the theme.json approach is a benefit for theme developers.

It’s worth reading Ben’s post, but the meat is in this quote:

Overriding CSS, whether layout, preset, or block styles, presents an obstacle to integration and interoperability: visual parity between the frontend and editor becomes more difficult to maintain, upgrades to block internals may conflict with overrides. Custom CSS is, furthermore, less portable across other block themes.

By encouraging theme authors to use theme.json API where possible, the hierarchy of “base > theme > user” defined styles can be resolved correctly.

One of the major benefits of moving CSS to JSON is that JSON is a machine-readable format, which means it can be exposed in the WordPress Site Editor UI by fetching an API, thus allowing users to modify default values and customize a site’s appearance without writing any CSS at all. It also provides a way to style blocks consistently, while providing a structure that creates layers of specificity such that the user settings take the highest priority over those defined in theme.json. That interplay between theme-level styles in theme.json and the user-defined styles in the Global Styles UI is what makes the JSON approach so appealing.

Developers maintain consistency in JSON, and users gain flexibility with code-less customizations. That’s a win-win.

There are other benefits, for sure, and Mike McAlister from WP Engine lists several in this Twitter thread. You can find even more benefits in this in-depth discussion over at the Make WordPress Core blog. And once you’ve given that a read, compare the benefits of the JSON approach with the available ways to define and override styles in classic themes.

Defining styles with JSON elements

We’ve already seen a lot of progress as far as what parts of a theme theme.json is capable of styling. Prior to WordPress 6.1, all we could really do was style headings and links. Now, with WordPress 6.1, we can add buttons, captions, citations, and headings to the mix.

And we do that by defining JSON elements. Think of elements as individual components that live in a WordPress block. Say we have a block that contains a heading, a paragraph, and a button. Those individual pieces are elements, and there’s an elements object in theme.json where we define their styles:

{
  "version": 2,
  "settings": {},
  // etc.
  "styles": {
    // etc.
    "elements": {
        "button": { ... },
        "h1": { ... },
        "heading": { ... },
    },
  },
  "templateParts": {}
}

A better way to describe JSON elements is as low-level components for themes and blocks that do not need the complexity of blocks. They are representations of HTML primitives that are not defined in a block but can be used across blocks. How they are supported in WordPress (and the Gutenberg plugin) is described in the Block Editor Handbook and this Full Site Editing tutorial by Carolina Nymark.

For example, links are styled in the elements object but are not a block in their own right. But a link can be used in a block and it will inherit the styles defined on the elements.link object in theme.json. This doesn’t fully encapsulate the definition of an element, though, as some elements are also registered as blocks, such as the Heading and Button blocks — but those blocks can still be used within other blocks.

Here is a table of the elements that are currently available to style in theme.json prior to WordPress 6.1, courtesy of Carolina:

ElementSelectorWhere it’s supported
link<a>WordPress Core
h1 – h6The HTML tag for each heading level: <h1><h2><h3><h4><h5> and <h6>WordPress Core
headingStyles all headings globally by individual HTML tag: <h1><h2><h3><h4><h5> and <h6>Gutenberg plugin
button.wp-element-button.wp-block-button__linkGutenberg plugin
caption.wp-element-caption,
.wp-block-audio figcaption,
.wp-block-embed figcaption,
.wp-block-gallery figcaption,
.wp-block-image figcaption,
.wp-block-table figcaption,
.wp-block-video figcaption
Gutenberg plugin
cite.wp-block-pullquote citeGutenberg plugin

As you can see, it’s still early days and plenty still needs to move from the Gutenberg plugin into WordPress Core. But you can see how quick it would be to do something like style all headings in a theme globally without hunting for selectors in CSS files or DevTools.

Further, you can also start to see how the structure of theme.json sort of forms layers of specificity, going from global elements (e.g. headings) to individual elements (e.g. h1), and block-level styles (e.g. h1 contained in a block).

Additional information on JSON elements is available in this Make WordPress proposal and this open ticket in the Gutenberg plugin’s GitHub repo.

JSON and CSS specificity

Let’s keep talking about CSS specificity. I mentioned earlier that the JSON approach to styling establishes a hierarchy. And it’s true. Styles that are defined on JSON elements in theme.json are considered default theme styles. And anything that is set by the user in the Global Styles UI will override the defaults.

In other words: user styles carry more specificity than default theme styles. Let’s take a look at the Button block to get a feel for how this works.

I’m using Emptytheme, a blank WordPress theme with no CSS styling. I’m going to add a Button block on a new page.

The background color, text color, and rounded borders come from the block editor’s default settings.

OK, we know that WordPress Core ships with some light styling. Now, I’m going to switch to the default TT3 theme from WordPress 6.1 and activate it. If I refresh my page with the button, the button changes styles.

The background color, text color, and rounded corner styles have changed.

You can see exactly where those new styles are coming from in TT3’s theme.json file. This tells us that the JSON element styles take precedence over WordPress Core styles.

Now I am going to modify TT3 by overriding it with a theme.json file in a child theme, where the default background color of the Button block is set to red.

The default style for the Button block has been updated to red.

But notice the search button in that last screenshot. It should be red, too, right? That must mean it is styled at another level if the change I made is at the global level. If we want to change both buttons, we could do it at the user level using the Global Styles UI in the site editor.

We changed the background color of both buttons to blue and modified the text as well using the Global styles UI. Notice that the blue from there took precedence over the theme styles!

The Style Engine

That’s a very quick, but good, idea of how CSS specificity is managed in WordPress block themes. But it’s not the complete picture because it’s still unclear where those styles are generated. WordPress has its own default styles that come from somewhere, consumes the data in theme.json for more style rules, and overrides those with anything set in Global Styles.

Are those styles inline? Are they in a separate stylesheet? Maybe they’re injected on the page in a <script>?

That’s what the new Style Engine is hopefully going to solve. 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. I know, I know. Yet another abstraction on top of other abstractions just to author some styles. But having a centralized API for styles is probably the most elegant solution given that styles can come from a number of places.

We’re only getting a first look at the Style Engine. In fact, here’s what has been completed so far, according to the ticket:

  • Audit and consolidate where the code generates block support CSS in the back end so that they are delivered from the same place (as opposed to multiple places). This covers CSS rules such as margin, padding, typography, colors, and borders.
  • Remove repetitive layout-specific styles and generate semantic class names.
  • Reduce the number of inline style tags we print to the page for block, layout, and element support.

Basically, this is the foundation for establishing a single API that contains all the CSS style rules for a theme, wherever they come from. It cleans up the way WordPress would inject inline styles pre-6.1 and establishes a system for semantic class names.

Further details on the long-term and short-term goals of Style Engine can be found in this Make WordPress Core discussion. You can also follow the tracking issue and project board for more updates.

Working with JSON elements

We talked a bit about JSON elements in the theme.json file and how they are basically HTML primitives for defining default styles for things like headings, buttons, and links, among others. Now, let’s look at actually using a JSON element and how it behaves in various styling contexts.

JSON elements generally have two contexts: the global level and the block level. The global level styles are defined with less specificity than they are at the block level to ensure that block-specific styles take precedence for consistency wherever blocks are used.

Global styles for JSON elements

Let’s look at the new default TT3 theme and examine how its buttons are styled. The following is an abbreviated copy-paste of the TT3 theme.json file (here’s the full code) showing the global styles section, but you can find the original code here.

View code
{
  "version": 2,
  "settings": {},
    // ...
  "styles": {
    // ...
    "elements": {
      "button": {
        "border": {
          "radius": "0"
        },
        "color": {
          "background": "var(--wp--preset--color--primary)",
          "text": "var(--wp--preset--color--contrast)"
        },
        ":hover": {
          "color": {
            "background": "var(--wp--preset--color--contrast)",
            "text": "var(--wp--preset--color--base)"
          }
        },
        ":focus": {
          "color": {
            "background": "var(--wp--preset--color--contrast)",
            "text": "var(--wp--preset--color--base)"
          }
        },
        ":active": {
          "color": {
            "background": "var(--wp--preset--color--secondary)",
            "text": "var(--wp--preset--color--base)"
          }
        }
      },
      "h1": {
        "typography": { }
      },
      // ...
      "heading": {
        "typography": {
          "fontWeight": "400",
          "lineHeight": "1.4"
      }
      },
      "link": {
        "color": {
          "text": "var(--wp--preset--color--contrast)"
        },
        ":hover": {
          "typography": {
            "textDecoration": "none"
          }
        },
        ":focus": {
          "typography": {
            "textDecoration": "underline dashed"
          }
        },
        ":active": {
          "color": {
            "text": "var(--wp--preset--color--secondary)"
          },
          "typography": {
            "textDecoration": "none"
          }
        },
        "typography": {
          "textDecoration": "underline"
        }
      }
     },
    // ...
  },
  "templateParts": {}
}

All buttons are styled at the global level (styles.elements.button).

Every button in the Twenty Twenty-Three theme shares the same background color, which is set to the --wp--preset--color--primary CSS variable, or #B4FD55.

We can confirm this in DevTools as well. Notice that a class called .wp-element-button is the selector. The same class is used to style the interactive states as well.

Again, this styling is all happening at the global level, coming from theme.json. Whenever we use a button, it is going to have the same background because they share the same selector and no other style rules are overriding it.

As an aside, WordPress 6.1 added support for styling interactive states for certain elements, like buttons and links, using pseudo-classes in theme.json — including :hover, :focus, and :active — or the Global Styles UI. Automattic Engineer Dave Smith demonstrates this feature in a YouTube video.

We could override the button’s background color either in theme.json (preferably in a child theme since we’re using a default WordPress theme) or in the Global Styles settings in the site editor (no child theme needed since it does not require a code change).

But then the buttons will change all at once. What if we want to override the background color when the button is part of a certain block? That’s where block-level styles come into play.

Block-level styles for elements

To understand how we can use and customize styles at the block level, let’s change the background color of the button that is contained in the Search block. Remember, there is a Button block, but what we’re doing is overriding the background color at the block level of the Search block. That way, we’re only applying the new color there as opposed to applying it globally to all buttons.

To do that, we define the styles on the styles.blocks object in theme.json. That’s right, if we define the global styles for all buttons on styles.elements, we can define the block-specific styles for button elements on styles.block, which follows a similar structure:

{
  "version": 2,
  // ...
  "styles": {
    // Global-level syles
    "elements": { },
    // Block-level styles
    "blocks": {
      "core/search": {
        "elements": {
          "button": {
            "color": {
              "background": "var(--wp--preset--color--quaternary)",
              "text": "var(--wp--preset--color--base)"
            }
          }
        },
        // ...
      }
    }
  }
}

See that? I set the background and text properties on styles.blocks.core/search.elements.button with two CSS variables that are preset in WordPress.

The result? The search button is now red (--wp--preset--color--quaternary), and the default Button block retains its bright green background.

We can see the change in DevTools as well.

The same is true if we want to style buttons that are included in other blocks. And buttons are merely one example, so let’s look at another one.

Example: Styling headings at each level

Let’s drive all this information home with an example. This time, we will:

  • Style all headings globally
  • Style all Heading 2 elements
  • Style Heading 2 elements in the Query Loop block

First, let’s start with the basic structure for theme.json:

{
  "version": 2,
  "styles": {
    // Global-level syles
    "elements": { },
    // Block-level styles
    "blocks": { }
  }
}

This establishes the outline for our global and block-level styles.

Style all headings globally

Let’s add the headings object to our global styles and apply some styles:

{
  "version": 2,
  "styles": {
    // Global-level syles
    "elements": {
      "heading": {
        "color": "var(--wp--preset--color--base)"
      },
    },
    // Block-level styles
    "blocks": { }
  }
}

That sets the color for all headings to the preset base color in WordPress. Let’s change the color and font size of Heading 2 elements at the global level as well:

{
  "version": 2,
  "styles": {
    // Global-level syles
    "elements": {
      "heading": {
        "color": "var(--wp--preset--color--base)"
      },
      "h2": {
        "color": "var(--wp--preset--color--primary)",
        "typography": {
          "fontSize": "clamp(2.625rem, calc(2.625rem + ((1vw - 0.48rem) * 8.4135)), 3.25rem)"
        }
      }
    },
    // Block-level styles
    "blocks": { }
  }
}

Now, all Heading 2 elements are set to be the primary preset color with a fluid font size. But maybe we want a fixed fontSize for the Heading 2 element when it is used in the Query Look block:

{
  "version": 2,
  "styles": {
    // Global-level syles
    "elements": {
      "heading": {
        "color": "var(--wp--preset--color--base)"
      },
      "h2": {
        "color": "var(--wp--preset--color--primary)",
        "typography": {
          "fontSize": "clamp(2.625rem, calc(2.625rem + ((1vw - 0.48rem) * 8.4135)), 3.25rem)"
        }
      }
    },
    // Block-level styles
    "blocks": {
      "core/query": {
        "elements": {
          "h2": {
            "typography": {
              "fontSize": 3.25rem
            }
          }
        }
      }
    }
  }
}

Now we have three levels of styles for Heading 2 elements: all headings, all Heading 2 elements, and Heading 2 elements that are used in the Query Loop block.

Existing theme examples

While we only looked at the styling examples for buttons and headings in this article, WordPress 6.1 supports styling additional elements. There’s a table outlining them in the “Defining styles with JSON elements” section.

You’re probably wondering which JSON elements support which CSS properties, not to mention how you would even declare those. While we wait for official documentation, the best resources we have are going to be the theme.json files for existing themes. I’m going to provide links to themes based on the elements they customize, and point out what properties are customized.

ThemeWhat’s customizedTheme JSON
BlockbaseButtons, headings, links, core blocksSource code
Block CanvasButtons, headings, links, core blocksSource code
DiscoButtons, headings, core blocksSource code
FrostButtons, headings, links, captions, cite, core blocksSource code
PixlButtons, headings, links, core blocksSource code
RainfallButtons, headings, links, core blocksSource code
Twenty Twenty-ThreeButtons, headings, links, core blocksSource code
VivreButtons, headings, links, core blocksSource code

Be sure to give each theme.json file a good look because these themes include excellent examples of block-level styling on the styles.blocks object.

Wrapping up

Frequent changes to the full-site editor are becoming a major sources of irritation to many people, including tech-savvy Gutenberg users. Even very simple CSS rules, which work well with classic themes, don’t seem to work for block themes because of the new layers of specificity we covered earlier.

Regarding a GitHub proposal to re-design the site editor in a new browser mode, Sara Gooding writes in a WP Tavern post:

It’s easy to get lost while trying to get around the Site Editor unless you are working day and night inside the tool. The navigation is jumpy and confusing, especially when going from template browsing to template editing to modifying individual blocks.

Even as a keen early rider in the world of Gutenberg block editor and block-eye themes, I do have tons of my own frustrations. I’m optimistic, though, and anticipate that the site editor, once completed, will be a revolutionary tool for users and techno-savvy theme developers alike. This hopeful tweet already confirms that. In the meantime, it seems that we should be preparing for more changes, and perhaps even a bumpy ride.

References

I’m listing all of the resources I used while researching information for this article.

JSON elements

Global Styles

Style Engine


Thanks for reading! I’d love to hear your own reflections on using the block themes and how you managing your CSS.


Managing CSS Styles in a WordPress Block Theme originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/managing-css-styles-in-a-wordpress-block-theme/feed/ 7 374910
Adding Fluid Typography Support to WordPress Block Themes https://css-tricks.com/fluid-typography-wordpress-block-themes/ https://css-tricks.com/fluid-typography-wordpress-block-themes/#respond Fri, 07 Oct 2022 13:19:23 +0000 https://css-tricks.com/?p=373905 Fluid typography is a fancy way of “describing font properties, such as size or line height, that scale fluidly according to the size of the viewport”. It’s also known by other names, like responsive typography, flexible type, fluid type, …


Adding Fluid Typography Support to WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Fluid typography is a fancy way of “describing font properties, such as size or line height, that scale fluidly according to the size of the viewport”. It’s also known by other names, like responsive typography, flexible type, fluid type, viewport sized typography, fluid typography, and even responsive display text.

Here is an example of fluid typography that you can play live (courtesy of MDN documentation). CSS-Tricks has covered fluid typography extensively as well. But the point here is not to introduce you to fluid typography, but how to use it. More specifically, I want to show you how to implement fluid typography in WordPress 6.1 which recently introduced a fluid type feature directly in the WordPress Block Editor.

Open up your style.css file, slap in a style rule with fancy clamp()-ing on the font-size property, and good to go, right? Sure, that’ll give you fluid text, but to get Block Editor controls that make it possible to apply fluid type anywhere on your WordPress site? That requires a different approach in these block-ified days.

Fluid typography support in Gutenberg

Some WordPress theme developers have been using the clamp() function to define a fluid font-size, in their WordPress themes, even in newer “block” themes such as Twenty Twenty-Two, Twenty Twenty-Three, and others.

But the Gutenberg plugin — the one that contains experimental development for WordPress Block and Site Editor features — introduced support for fluid typography starting in version 13.8. That opened the door for implementing at a theme level so that fluid type can be applied to specific elements and blocks directly in the Block Editor. CSS-Tricks was even given a shout-out in the Pull Request that merged the feature.

That work became part of WordPress Core in WordPress 6.1. Rich Tabor, one of the earlier advocates of fluid typography in the Block Editor says:

[Fluid typography] is also a part of making WordPress more powerful, while not more complicated (which we all know is quite the challenge). […] Fluid typography just works. Actually, I think it works great.

This Make WordPress post highlights the approach taken to support the feature at the block level so that a fluid font size is applied to blocks dynamically by default. There are some benefits to this, of course:

  • It provides a way for theme authors to activate fluid typography without worrying about implementing it in code.
  • It applies fluid typography to specific typographical entities, such as elements or blocks in a maintainable and reusable way.
  • It allows flexibility in terms of font size units (e.g. px, rem, em, and %).

Now that this new feature is available in the WordPress Block Editor by default, theme authors can apply uniform fluid typography without writing additional code.

Blocks that support typography and spacing settings

Gutenberg 14.1 released on September 16, 2022, and introduced typographic settings on a bunch of blocks. That means the text settings for those blocks were set in CSS before and had to be changed in CSS as well. But those blocks now provide font and spacing controls in the Block Editor interface.

Illustrated list of WordPress blocks that received font and spacing controls in the Gutenberg plugin. There are 31 total blocks.

That work is currently slated to be added to WordPress 6.1, as detailed in this Make WordPress blog post. And with it is an expanded number of blocks that with typography support.

Illustrated list of 60 WordPress blocks gaining typography and font size support in WordPress 6.1.
WordPress blocks that will support typography settings in the upcoming WordPress 6.1 release.

Declaring fluid type in a WordPress block theme

So, how do we put this new fluid typography to use in WordPress? The answer is in theme.json, a new-ish file specific to block themes that contains a bunch of theme configurations in key:value pairs.

Let’s look at a rule for a large font in theme.json where contentSize: 768px and we’re working with a widesize: 1600px layout. This is how we can specify a CSS font-size using the clamp() function:

"settings": {
  "appearanceTools": true,
  "layout": {
    "contentSize": "768px",
    "wideSize": "1600px"
  },
  "typography": {
    "fontSizes": [ 
      {
        "name": "Large",
        "size": "clamp(2.25rem, 6vw, 3rem)",
        "slug": "large"
      }
    ]
  }
}

As of WordPress 6.1, only rem, em and px units are supported.

That’s great and works, but with the new fluid type feature we would actually use a different approach. First, we opt into fluid typography on settings.typography, which has a new fluid property:

"settings": {
  "typography": {
    "fluid": true
  }
}

Then we specify our settings.fontSizes like before, but with a new fluidSize property where we can set the min and max size values for our fluid type range.

"settings": {
  "appearanceTools": true,
  "layout": {
    "contentSize": "768px",
    "wideSize": "1600px"
  },
  "typography": {
    "fontSizes": [ 
      {
        "size": "2.25rem",
        "fluidSize": {
          "min": "2.25rem",
          "max": "3rem"
        },
        "slug": "large",
        "name": "Large"
      }
    ]
  }
}

That’s really it. We just added fluid type to a font size called “Large” with a range that starts at 2.25rem and scales up to 3rem. Now, we can apply the “Large” font to any block with font settings.

How does this works under the hood? Rich Tabor offers a nice explanation, as does this Pull Request in GitHub. In short, WordPress converts the theme.json properties into the following CSS rule:

.has-large-font-size {
  font-size: clamp(36px, calc(2.25rem + ((1vw - 7.68px) * 1.4423)), 48px);
}

…which is applied to the element, say a Paragraph Block:

<p class="has-large-font-size">...</p>

Initially, I found it hard to understand and wrap around in my mind the concept of the CSS clamp() function without also learning about the min(), max(), and calc() functions. This calculator tool helped me quite a bit, especially for determining which values to use in my own theme projects.

For demonstration purposes, let’s use the calculator to define our font-size range so that the size is 36px at a 768px viewport width and 48px at a 1600px viewport width.

Entering values into the online calculator for fluid typography.

The calculator automatically generates the following CSS:

/* 36px @ 768px increasing to 48px @ 1600px */
font-size: clamp(36px, calc(2.25rem + ((1vw - 7.68px) * 1.4423)), 48px);

The calculator provide options to select input units as px, rem, and em. If we select rem unit, the calculator generates the following clamp() value:

/* 2.25rem @ 48rem increasing to 3rem @ 100rem */
font-size: clamp(2.25rem, calc(2.25rem + ((1vw - 0.48rem) * 1.4423)), 3rem);

So, those minimum and maximum values correspond to the the fluidSize.min and fluidSize.max values in theme.json. The min value is applied at viewports that are 768px wide and below. Then the font-size scales up as the viewport width grows. If the viewport is wider than 1600px, the max is applied and the font-size is capped there.

Examples

There are detailed testing instructions in the merged Pull Request that introduced the feature. There are even more testing instructions from Justin Tadlock’s pre-prelease post on Make WordPress.

Example 1: Setting a new fluid font setting

Let’s start with Justin’s set of instructions. I used in a modified version of the default Twenty Twenty-Three theme that is currently under development.

First, let’s make sure we’re running the Gutenberg plugin (13.8 and up) or WordPress 6.1, then opt into fluid type on the settings.typography.fluid property in the theme.json file:

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "layout": {
      "contentSize": "768px",
      "wideSize": "1600px"
    },
    "typography": {
      "fluid": true
    }
  }
}

Now, let’s drop the settings.typography.fontSizes examples in there:

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "layout": {
      "contentSize": "768px",
      "wideSize": "1600px"
    },
    "typography": {
      "fluid": true
      "fontSizes": [
        {
          "name": "Normal",
          "size": "1.125rem",
          "fluid": {
            "min": "1rem",
            "max": "1.5rem"
          },
          "slug": "normal"
        }
      ]
    }
  }
}

If everything is working correctly, we can now head into the WordPress Block Editor and apply the “Normal” font setting to our block:

The WordPress Block Editor interface showing a paragraph block and the fluid typography settings for it.

Nice! And if we save and inspect that element on the front end, this is the markup:

Inspecting the WordPress Paragraph block in DevTools.

Very good. Now let’s make sure the CSS is actually there:

DevTools showing the font-size custom property for the WordPress Paragraph block's fluid typography.

Good, good. Let’s expose that CSS custom property to see if it’s really clampin’ things:

Revealing the custom property value in DevTools, showing a CSS clamp function.

Looks like everything is working just as we want it! Let’s look at another example…

Example 2: Excluding a font setting from fluid type

This time, let’s follow the instructions from the merged Pull Request with a nod to this example by Carolina Nymark that shows how we can disable fluid type on a specific font setting.

I used the empty theme as advised in the instructions and opened up the theme.json file for testing. First, we opt into fluid type exactly as we did before:

{
  "version": 2,
  "settings": {
    "appearanceTools": true,
    "layout": {
      "contentSize": "768px",
      "wideSize": "1000px"
    },
    "typography": {
      "fluid": true
    }
  }
}

This time, we’re working with smaller wideSize value of 1000px instead of 1600px. This should allow us to see fluid type working in an exact range.

OK, on to defining some custom font sizes under settings.typography.fontSizes:

{
  "version": 2,
  "settings": {
    "typography": {
      "fluid": true,
      "fontSizes": [
        {
          "size": ".875rem",
          "fluid": {
            "min": "0.875rem",
            "max": "1rem"
        },
          "slug": "small",
          "name": "Small"
        },
        {
          "size": "1rem",
          "fluid": {
            "min": "1rem",
            "max": "1.5rem"
          },
          "slug": "normal",
          "name": "Normal"
        },
        {
          "size": "1.5rem",
          "fluid": {
            "min": "1.5rem",
            "max": "2rem"
          },
          "slug": "large",
          "name": "Large"
        },
        {
          "size": "2.25rem",
          "fluid": false,
          "slug": "x-large",
          "name": "Extra large"
        }
      ]
    }
  }
}

Notice that we’ve applied the fluid type feature only on the “Normal”, “Medium”, and “Large” font settings. “Extra Large” is the odd one out where the fluid object is set to false.

the WordPress Block Editor interface with four Paragraph blocks, each at a different font size setting.

What WordPress does from here — via the Gutenberg style engine — is apply the properties we set into CSS clamp() functions for each font size setting that has opted into fluid type and a single size value for the Extra Large setting:

--wp--preset--font-size--small: clamp(0.875rem, 0.875rem + ((1vw - 0.48rem) * 0.24), 1rem);
--wp--preset--font-size--medium: clamp(1rem, 1rem + ((1vw - 0.48rem) * 0.962), 1.5rem);
--wp--preset--font-size--large: clamp(1.5rem, 1.5rem + ((1vw - 0.48rem) * 0.962), 2rem);
--wp--preset--font-size--x-large: 2.25rem;

Let’s check the markup on the front end:

Inspecting the WordPress Paragraph blocks in DevTools.

Good start! Let’s confirm that the .has-x-large-font-size class is excluded from fluid type:

Showing the font-size custom property for the Extra Large font setting in DevTools.

If we expose the --wp--preset--font-size--x-large variable, we’ll see it’s set to 2.25rem.

Revealing the Extra Large font size custom property value, showing 2.25rem.

That’s exactly what we want!

Block themes that support fluid typography

Many WordPress themes already make use of the clamp() function for fluid type in both block and classic themes. A good example of fluid typography use is the recently released Twenty Twenty-Three default theme.

I’ve reviewed all the block themes from WordPress Block Theme directory, examining theme.json file of each theme and to see just how many block themes currently support fluid typography — not the new feature since it’s still in the Gutenberg plugin as of this writing — using the CSS clamp() function. Of the 146 themes I reviewed, the majority of them used a clamp() function to define spacing. A little more than half of them used clamp() to define font sizes. The Alara theme is the only one to use clamp() for defining the layout container sizes.

Understandably, only a few recently released themes contain the new fluid typography feature. But here are the ones I found that define it in theme.json:

And if you read my previous post here on CSS-Tricks, the TT2 Gopher Blocks theme I used for the demo has also been updated to support the fluid typography feature.

Selected reactions to the WordPress fluid typography features

Having fluid typography in WordPress at the settings level is super exciting! I thought I’d share some thoughts from folks in the WordPress developer community who have commented on it.

Matias Ventura, the lead architect of the Gutenberg project:

Rich Tabor:

As one of the bigger efforts towards making publishing beautifully rich pages in WordPress, fluid typography is a pretty big experience win for both the folks building with WordPress — and those consuming the content.

Automattic developer Ramon Dodd commented in the Pull Request:

Contrast that idea with font sizes that respond to specific viewport sizes, such as those defined by media queries, but do nothing in between those sizes. theme.json already allows authors to insert their own fluid font size values. This won’t change, but this PR offers it to folks who don’t want to worry about the implementation details.

Nick Croft, author of GenesisWP:

Brian Garner, designer and principal developer advocate at WPEngine:

A few developers think some features should be an opt-in. Jason Crist of Automattic says:

I love the power of fluid typography, however I also don’t believe that it should just be enabled by default. It’s usage (and the details of it) are important design decisions that should be made carefully.

You can also find a bunch more comments in the official testing instructions for the feature.

Wrapping up

The fluid typography feature in WordPress is still in active development at the time of this writing. So, right now, theme authors should proceed to use it, but with caution and expect some possible changes before it is officially released. Justin cautions theme authors using this feature and suggests to keep eye on the following two GitHub issues:

There is also still lots of ongoing work on typography and other design-related WordPress tools. If you’re interested, watch this typography tracking GitHub ticket and design tools related GitHub issues.

Resources

I used the following articles when researching fluid type and how WordPress is implementing it as a feature.

Tutorials and opinions

CSS-Tricks


Adding Fluid Typography Support to WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/fluid-typography-wordpress-block-themes/feed/ 0 373905
How to Create Style Variations in WordPress 6.0 Block Themes https://css-tricks.com/creating-style-variations-in-wordpress-block-themes/ https://css-tricks.com/creating-style-variations-in-wordpress-block-themes/#respond Mon, 16 May 2022 14:38:29 +0000 https://css-tricks.com/?p=365377 Global styles, a feature of the block themes, is one of my favorite parts of creating block themes. The concept of global style variations in WordPress were introduced in Gutenberg 12.5 which would allow theme authors to create alternate …


How to Create Style Variations in WordPress 6.0 Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Global styles, a feature of the block themes, is one of my favorite parts of creating block themes. The concept of global style variations in WordPress were introduced in Gutenberg 12.5 which would allow theme authors to create alternate variations of a block theme with different combinations of colors, fonts, typography, spacing, etc. Different theme.json files stored under /styles folder “lets users quickly and easily switch between different looks in the same theme.”

The global styles panel UI is in active development iteration. More details on the development of this feature can be found and tracked here at this GitHub ticket (#35619).

In this article, I will walk through creating a proof-of-concept global style variation using alternate /styles/theme.json files and create child themes with different color modes by swapping color palettes only.

Table of contents

Prerequisites

This article is intended for those who have basic understanding of WordPress block themes and some familiarity of using Full Site Editor (FSE) interface. If you’re new to block themes and the FSE, you can get started here on CSS-Tricks with this deep introduction to WordPress block themes and site editor documentation. This Full Site Editing website is one of the most up-to-date tutorial guides to learn all FSE features including block themes and styles variations discussed in this article.

Global style variations

For some background, let’s briefly overview global style variation. Twenty Twenty-Two (TT2) theme lead and Automattic design director Kjell Reigstad introduced global styles variations with this tweet and GitHub ticket #292 as child themes. In the ticket, Kjell notes that they were initially intended as alternate color patterns and fonts combinations, but they can be used for building simple child themes.

This example from Kjell demonstrates how different style combinations could be selected from options available in the sidebar.

Since then, the Automattic theme team has been experimenting with the concept to create variable child themes (variable color and fonts only), including the following:

  • geologist with blue, cream, slate, yellow variations
  • quadrat with black, green, red, white, and yellow versions

Global style switcher

The Gutenberg 12.5 release has introduced a global styles switcher which would allow users quickly and easily switch between different looks in the same theme via different theme.json files stored under a /styles folder.

The concept of allowing switching global style variation via theme.json has been discussed on GitHub for a while now. Gutenberg lead engineer Matias Ventura gave renewed importance to it by adding it to the WordPress 6.0 roadmap recently.

Embrace style alternates driven by json variations. This was teased in various videos around the new default theme and should be fully unveiled and presented in 6.0. One of the parallel goals is to create a few distinct variations of TT2 made just with styles. (35619)

Matias Ventura, “Preliminary Roadmap to 6.0”

The latest development iteration of theme style variation switcher is available with Gutenberg 13.0 and included in WordPress 6.0. In this Exploring WordPress 6.0 video, Automattic product liaison Anne McCarthy provides an overview of its major features, including style variations and Webfonts API (starting 5:18) discussed in this article.

Theme style variation versus child theme

In my previous article, I briefly covered building block child themes. Global style variations have blurred the line between alternate-theme.json and child themes. For example, the only difference between a recently released alante-dark child theme and its parent theme is an alternate.json file in the child theme that overrides the global theme styles like this:

Screenshot of the Visual Studio Code UI displaying the contents of alante-dark.
The alante-dark theme.

Likewise, the two recent Alara child themes in the WordPress directoryFramboise and Richmond — differ only in their single theme.json file.

Section 1: Creating theme style variations

At the root of your child theme folder, create a /styles folder, which holds style variations as JSON files. For this demo example, I created three variations of Twenty Twenty-Two’s theme.json color palettes — blue.json, maroon.json, and pink.json — by swapping the foreground and background colors:

Screenshot of the Visual Studio Code UI displaying the child theme file structure of "blue.json", "maroon.json", and "pink.json" in the styles directory.
The child theme file structure of “blue.json”, “maroon.json”, and “pink.json” in the styles directory.

Here is the final result after clicking the styles icon from the admin dashboard (located at Appearance → Editor):

Animated GIF showing the theme variations in WordPress.
Walking through the WordPress admin interface to select the “blue”, “maroon”, and “pink” styles.

Click the Other Styles button (recently revised to Browser styles), which displays “blue”, “maroon”, and “pink” color style icons in addition to its original styles.

To change and choose a style, select your preferred variation and click the Save button (top-right), which is displayed on the front end of your browser.

Adding labels to alternate style variations and file name with hover animation effect are available in Gutenberg 13.0.

Step 1: Setup and installation

First, install and set up a WordPress site with some dummy content. For this demo, I made a fresh WordPress install, activated Twenty Twenty-Two theme, and added Gutenberg test data.

The theme style variations and WebFonts API discussed in this article require installation and activation of the Gutenberg 13.0 plugin or WordPress 6.0.

Step 2: Create a TT2 child theme

In this demo child theme example, let’s slightly vary the body color from the header and footer color, with all site content centered:

The lower part of the site design are not visible because it is not scrolled into view. Site navigation is present in the header. A large banner image with a bird is visible. A date and title for the latest blog entry is also visible.
Screenshot of the default appearance of the demo theme in a browser window.

Step 3: Create JSON files

Create /styles in your child theme’s root folder with blue, maroon, and pink.json files:

__ style.css
__ theme.json
__ functions.php
__ index.php
__ templates
__ ...
__ parts
__ ...
__ styles
__ blue.json
__ maroon.json
__ pink.json

Step 4: Create alternate theme JSON files

Next up, create your alternate-theme.json files with desired color pallets under /styles folder. For this demo example, I created three color palettes (blue, maroon, and pink). Here is the code for maroon.json:

{
  "version": 2,
  "title": "Maroon",
  "settings": {
    "color": {
      "palette": [
        { "slug": "foreground", "color": "#7C290F", "name": "Foreground" },
        { "slug": "background", "color": "#ffffff", "name": "Background" },
        { "slug": "foreground-dark", "color": "#000000", "name": "Foreground Dark" },
        { "slug": "background-body", "color": "#ffd8be", "name": "Background Body" },
        { "slug": "primary", "color": "#000000", "name": "Primary" },
        { "slug": "secondary", "color": "#ffe2c7", "name": "Secondary" },
        { "slug": "tertiary", "color": "#55ACEE", "name": "Tertiary" }
      ]
  },
  "typography": {}
},
"styles": {
  "color":
      {
        "background": "var(--wp--preset--color--background-body)",
        "text": "var(--wp--preset--color--foreground-dark)"
      },
  "elements": {
      "link": {
        "color": { "text": "var(--wp--preset--color--primary)" }
      }
    }
  }
}

The other two alternate blue.json and pink.json files swap values of foreground and background-body, foreground-dark and primary color properties with their respective blue and pink hex color values.

Section 2: An example of a use case

As I noted in my previous article, I have been working on block themes and using them for my own personal project site. Inspired by the theme style variations and Webfonts API features in Gutenberg plugin, I started tweaking my work-in-progress block theme with an alternate dark color mode and by configuring the Webfonts API.

In this section, I will walk you through how I created TT2 Gopher Blocks, a demo sibling of my work-in-progress block theme created for this article. The theme includes maroon, dark, and light color modes created using theme style variations and Webfonts API that became available with the Gutenberg 12.8 release.

Showing the homepage we are creating with style variations in WordPress.
Screenshot displaying a sample site using the TT2 Gopher theme with maroon default color.

Some highlights of the TT2 Gopher theme include centered, single-column content display, distinct header and footer, more user-friendly archive and search pages.

A copy of TT2 Gopher Blocks is available at the GitHub repository, which you can fork and customize.

Creating dark mode on WordPress

First, some background on dark mode. Dark mode is a personal preference and developers offer it or other mode toggle switches like on this site, which is not a small job for most regular developers. Creating dark mode is well-covered here at CSS-Tricks, including this complete guide to dark mode and dark mode typography.

In a WordPress site, we can add a dark mode toggle using the WP Dark Mode plugin. Erin Myers of WP Engine and WPBeginner describe how to use the WP Dark Mode plugin, while Brenda Barron lists other dark mode plugin options in this WPExplorer post.

Creating a dark mode in WordPress block themes without a plugin involves several steps. Over a year ago, Ari Stathopoulos created a dark support for the TT1 Blocks theme at the GitHub. Looking at the example here, it involves some JavaScript knowledge to create assets (e.g., toggler, customize, editor-mode-support), dark color CSS variables, and expanded functions.php files.

In this short video, Automattic’s Anne McCarthy demonstrates how simple it is to create a dark mode of TT2 block theme with global style variation by adding kllejr’s gist of JSON snippets in the TT2 /styles folder.

Creating the demo TT2 Gopher blocks theme

The TT2 Gopher is a very simple and modified version of the default Twenty Twenty-Two theme. It includes three theme style variations — maroon, dark, and white.

Describing each customization step is beyond the scope of this article, but you can learn more from my deep introduction to WordPress block themes as well as the Block Editor Handbook over at WordPress.org.

A brief overview of the TT2 Gopher theme color and font combinations include:

  • Light mode
    • The header is white and the footer has a smoky body background color.
    • Open Sans is the primary font.
  • Dark mode
    • The header and footer are black with lighter dark colors for the body backgrounds.
    • Source Serif Pro is the primary font.
  • Maroon mode
    • The header and footer are both a dark maroon color, with a lighter yellowish body background.
    • Work Sans is the primary font.

Let me briefly walk you through how I created theme style variations.

Adding and configuring webfonts

The Gutenberg 12.8 plugin introduced a new Webfonts API that allows the authors to load local (bundled) fonts “in a performance-friendly, privacy-friendly, and future-proof manner.” This feature can be implemented in a block theme the PHP way or the theme.json way.

Currently this feature works only with fonts bundled with block themes and does not support Google-hosted fonts because of privacy concerns. More details on the current status of Webfonts API development are covered in this make WordPress core article and this WP Tavern article.

Step 1: Download and add fonts in block theme

The TT2 theme adds Source Serif Pro font files to the theme’s assets/fonts folder. Two additional fonts — Work Sans and Public Sans — are also provided in he GitHub repository.

Step 2: Registering webfonts

In the TT2 theme, local Source Serif Pro webfonts are registered with PHP in its functions.php file:

function twentytwentytwo_get_font_face_styles() {
  return "
  @font-face{
    font-family: 'Source Serif Pro';
    font-weight: 200 900;
    font-style: normal;
    font-stretch: normal;
    font-display: swap;
    src: url('" . get_theme_file_uri( 'assets/fonts/SourceSerif4Variable-Roman.ttf.woff2' ) . "') format('woff2');
  }
  @font-face{
    font-family: 'Source Serif Pro';
    font-weight: 200 900;
    font-style: italic;
    font-stretch: normal;
    font-display: swap;
    src: url('" . get_theme_file_uri( 'assets/fonts/SourceSerif4Variable-Italic.ttf.woff2' ) . "') format('woff2');
  }
  ";
}

Gutenberg 12.8 introduced the ability to register local web fonts with theme.json file. The following theme.json snippets from the demo TT2 Gopher theme show how local Work Sans web fonts are registered in the maroon theme style variation:

"typography": {
  "fontFamilies": [
    {
      "fontFamily": "'Work Sans', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Helvetica', sans-serif",
      "slug": "work-sans",
      "name": "Work Sans",
      "fontFace": [
        { "fontFamily": "Work Sans", "fontDisplay": "block", "fontWeight": "400", "fontStyle": "normal", "fontStretch": "normal", "src": [ "file:./assets/fonts/work-sans/WorkSans-VariableFont_wght.ttf" ] },
        { "fontFamily": "Work Sans", "fontDisplay": "block", "fontWeight": "700", "fontStyle": "normal", "fontStretch": "normal", "src": [ "file:./assets/fonts/work-sans/WorkSans-VariableFont_wght.ttf" ] },
        { "fontFamily": "Work Sans", "fontDisplay": "block", "fontWeight": "400", "fontStyle": "italic", "fontStretch": "normal", "src": [ "file:./assets/fonts/work-sans/WorkSans-Italic-VariableFont_wght.ttf" ] },
        { "fontFamily": "Work Sans", "fontDisplay": "block", "fontWeight": "700", "fontStyle": "italic", "fontStretch": "normal", "src": [ "file:./assets/fonts/work-sans/WorkSans-Italic-VariableFont_wght.ttf" ] }
      ]
    }
  ]
}

Additional information on how to register and use local webfonts in block themes is described in this tutorial and this WP Tavern article.

Creating theme style variations

Following the steps described in the previous section, I created two alternate versions of the theme.json file — white.json and black.json — with different color and fonts combinations inside the child theme’s /styles folder.

This feature requires version 2 of theme.json. Since Gutenberg 12.5, title can also be added at theme.json to display style label in the site editor or file name (without extension) will be displayed by default.

Here is an example of white.json:

{
  "version": 2,
  "title": "White",
  "settings": {
    "color": {
      "palette": [
        { "slug": "foreground", "color": "#000000", "name": "Foreground" },
        { "slug": "background", "color": "#f2f2f2", "name": "Background" },
        { "slug": "background-header", "color": "#ffffff", "name": "Background header" },
        { "slug": "primary", "color": "#0d0d0d", "name": "Primary" },
        { "slug": "secondary", "color": "#F0EAE6", "name": "Secondary" },
        { "slug": "tertiary", "color": "#eb3425", "name": "Tertiary" },
        { "slug": "quaternary", "color": "#7c7e83", "name": "Quaternary" }
      ]
    },
    "typography": {
      "fontFamilies": [
        {
        "fontFamily": "\"Public Sans\", sans-serif",
        "name": "Public Sans",
        "slug": "public-sans",
        "fontFace": [
          { "fontFamily": "Public Sans", "fontDisplay": "block", "fontStyle": "normal", "fontStretch": "normal", "src": [ "file:.assets/fonts/publicSans/PublicSans-VariableFont_wght.ttf.woff2" ] },
          { "fontFamily": "Public Sans", "fontDisplay": "block", "fontStyle": "italic", "fontStretch": "normal", "src": [ "file:./assets/fonts/publicSans/PublicSans-Italic-VariableFont_wght.ttf.woff2" ] }
        ]
      }
    ]
  }
},
"styles": {
  "blocks": {
    "core/image": {
      "filter": { "duotone": "var(--wp--preset--duotone--default-filter)" }
    },
    "core/post-title": {
      "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "700", "fontSize": "var(--wp--custom--typography--font-size--gigantic)" }
    },
    "core/query-title": {
      "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "300", "fontSize": "var(--wp--custom--typography--font-size--gigantic)" }
    },
    "core/post-featured-image": {
      "filter": { "duotone": "var(--wp--preset--duotone--default-filter)" }
    },
    "core/site-logo": {
      "filter": { "duotone": "var(--wp--preset--duotone--default-filter)" }
    },
    "core/site-title": {
      "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontSize": "var(--wp--preset--font-size--normal)", "fontWeight": "normal" }
    }
    },
    "color": { "background": "var(--wp--preset--color--background)", "text": "var(--wp--preset--color--foreground)" },
    "elements": {
      "h1": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "600", "fontSize": "var(--wp--custom--typography--font-size--colossal)" }
      },
      "h2": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "600", "fontSize": "var(--wp--custom--typography--font-size--gigantic)" }
      },
      "h3": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "300", "fontSize": "var(--wp--custom--typography--font-size--huge)" }
      },
      "h4": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "300", "fontSize": "var(--wp--preset--font-size--x-large)" }
      },
      "h5": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "700", "textTransform": "uppercase", "fontSize": "var(--wp--preset--font-size--medium)" }
      },
      "h6": {
        "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontWeight": "400", "textTransform": "uppercase", "fontSize": "var(--wp--preset--font-size--medium)" }
      },
      "link": {
        "color": { "text": "var(--wp--custom--color--foreground)" }
      }
    },
    "typography": { "fontFamily": "var(--wp--preset--font-family--public-sans)", "fontSize": "var(--wp--preset--font-size--normal)" }
  }
}

This code swaps color palettes from theme.json and also registers and defines the local Public Sans font files.

The black.json is also very similar and uses Source Serif Pro fonts registered in the functions.php file.

Screenshot of the light color theme on the left. And screenshot of the dark color theme on the right. The heading navigation and first blog entry are visible.
Side-by-side comparison of the light (left) and dark (right) color themes for TT2 Gopher.

Example of block themes with theme styles variations

  • Twenty Twenty-Two – the first default theme to include style variations. Its updated 1.2, bundled with WordPress 6.0 includes three style variations — “Blue”, “Pink”, and “Swiss” — allowing users to quickly swap between different visual styles.
  • Frost – an experimental block theme with dark theme style variation.
  • Alara – has above 100 active installs and includes 7 style variations.
  • Wabi– which powers Rich Tabor website contains 3 style variants and 300+ active installations.
  • Brisky – has more than 600 installs and one dark theme style variation.
  • Pendant – a theme by Automattic theme team under development at GitHub contains 3 theme style variation.

In this WP Tavern article, Justin speculates that this new feature may be utilized by theme authors by tying to the site visitor’s settings, while some users may prefer to tweak their site giving a seasonal or event-based design look. This is probably a little early, but only time will tell how this powerful feature would be utilized by both theme authors and users.

Wrapping up

Creating style variations of a block theme with different typography and color combination has been greatly simplified, without using plugins. It’s one of my favorite feature of the block editor that I plan to apply in my personal projects.

In my opinion, theme style variations are definitely a game changer for block themes and with this handy feature there might not be a need for child themes or even many cooky-cutter block themes. A few well-designed base block themes, similar to Automattic theme team’s block-canvas or blockbase (work-in-progress base block themes at GitHub), could be customized with theme style variation.


Resources

Dark Mode


How to Create Style Variations in WordPress 6.0 Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/creating-style-variations-in-wordpress-block-themes/feed/ 0 365377
A Deep Introduction to WordPress Block Themes https://css-tricks.com/a-deep-introduction-to-wordpress-block-themes/ https://css-tricks.com/a-deep-introduction-to-wordpress-block-themes/#comments Fri, 04 Feb 2022 15:07:04 +0000 https://css-tricks.com/?p=362799 The relatively new WordPress editor, also known as the WordPress Block Editor, always under development via the Gutenberg plugin, has been with us since 2018. You can use the block editor on any WordPress theme, provided the theme …


A Deep Introduction to WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
The relatively new WordPress editor, also known as the WordPress Block Editor, always under development via the Gutenberg plugin, has been with us since 2018. You can use the block editor on any WordPress theme, provided the theme loads CSS that the blocks use. But there are new themes that lean into the Block Editor much more deeply.

WordPress Block Themes allow you to build out the entire site using blocks, meaning the theme’s responsibility is mostly design guidelines, and less about controlling the pages and the content on them. This is referred to as Full-Site Editing in WordPress and the themes that are built for this are called Block Themes, because you build out everything with blocks.

Let’s dig into all this.

Illustration of a black vinyl record coming out of a record sleep sleeve from the left that contains a blue tinted image of jazz singer Joséphine Baker's profile looking right with a soft smile and parted lips. The image includes white text that says WordPress 5.9 and code is poetry.
Credit: WordPress.org

Table of Contents

Introduction

Except for those who follow its day-to-day development iterations at GitHub, most development surrounding the block editor is largely visible to users — and that’s not necessarily a bad thing. I have been personally trying to keep myself updated with the block editor through WP Tavern and Gutenberg posts, and have been using both the legacy — or “Classic” editor — as well as the block editor in my personal learning project sites.

After taking a detour to learn and experience headless WordPress sites with Gatsby and Frontity frameworks, I am now back to my native WordPress home.

Though I have been aware of the WordPress theme-experiment GitHub repository for a while — themes made completely out of blocks! — I have only started digging into block themes recently. In fact, I have been using an experimental block-based theme here in this project site.

WordPress 5.9 is now out in the wild and with it comes block-based theming for the masses. This release, dubbed Joséphine, is the formal introduction to WordPress full site editing and Block Themes.

Even though the block-based theming functionality has been available in various iterative forms in previous releases, this is a big deal for the WordPress platform and the ecosystem that relies on it. I’ve had my hands on it and thought I’d share what I’ve learned about block themes in my hands-on experience, as well as some personal thoughts on how it works.

Disclaimer: I am not a block themes expert by any stretch. I am well-versed in WordPress and a major fan of the content management system. My goal here is not to critique WordPress 5.9 or steer you in the direction of whether or not you should like it or want to use it. I’m merely coming from the perspective of an open-minded learner who is building personal sites with fairly deep understanding and familiarity with the WordPress Block Editor.

Before we dive straight into block themes, I think it’s a good idea to form a baseline understanding of just what we’re talking about when we’re tossing around terms, like blocks and site editing, as they’re so incredibly new and game-changing relative to what we’ve known and loved about WordPress for decades.

Block Editor

This is really what we mean any time we refer to the “WordPress Editor.” We call the WordPress Editor the Block Editor because it allows us to create pages and posts where each element— including text, images, videos, headers, footers, etc. — is inserted into the post using blocks that can be arranged modularly to complete page layouts. It evolved from what’s now called the “classic” editor, which was more squarely based on entering content to be published on a page or post in a predefined layout.

A full screenshot of the WordPress Block editor split into three numbers parts that are highlighted in red.
WordPress Block Editor including the block inserter (1), block editor content area (2), and the document and block settings (3)
Credit: WordPress Block Editor Handbook.

It’s sort of like content and layout coming together, where both are managed in the WordPress Editor. So, where we used to rely on the editor for content and (more or less) theme templates to define layout, both are directly editable in the WordPress Editor interface.

You can find more detail here on using the Block Editor.

Block Theme

As explained in the WordPress docs:

A block theme is a WordPress theme with templates entirely composed of blocks so that in addition to the post content of the different post types (pages, posts, …), the block editor can also be used to edit all areas of the site: headers, footers, sidebars, etc.

This WordPress documentation provides an overview of block themes in its knowledgebase, including how to create block themes and styling in this primer.

The bottom line: Block themes are different than “classic” WordPress themes. Rather than relying strictly on PHP files that conform to the WordPress Template Hierarchy, a WordPress Block Theme consists of block-based HTML templates — assembled groups of blocks that can be styled and arranged in the WordPress Site Editor (that’s coming up next) as well as using a theme.json file for global styling tokens.

Site Editor

This is the crown jewel of WordPress 5.9. While it is officially called the WordPress Site Editor, it’s largely been referred to as Full-Site Editing** (FSE) during development and is described as “the cohesive experience that allows you to directly edit and navigate between various templates, template parts, styling options, and more.” Phew, that’s a lot!

Credit: WordPress Support

The WordPress Site Editor allows us to create and editing templates that are made of blocks. So the idea is that we can assemble a group of blocks that can be applied globally to a site. Like a header component, for example. That might consist of blocks for a site logo, a primary menu, and a tagline. The site editor allows us to create a new block theme or modify an existing theme to give the site’s global appearance a completely new look without writing a line of code.

So, you know how you’ve had to build a theme in the past with a bunch of PHP templates? That’s no longer the case. Theme “development” now has a UI that’s available directly in WordPress.

More detail on using site editor is in the WordPress documentation.

The official WordPress Glossary has additional terms and definitions you may want to explore as we dig deeper into WordPress Block Themes and FSE.

Using the block editor with classic themes

The WordPress Block Editor can be used in both the classic and block themes. When the Gutenberg editor project began, the classic TinyMCE-based editor was detached from WordPress Core into the Classic Editor plugin. As long as the Classic Editor plugin is installed and active, content writing is pretty normal as it was before blocks were introduced.

Prior to the formal introduction of block editor features, we had to install the experimental Gutenberg plugin. By simply switching plugins, individual page or post contents could be created with either editor. The WordPress 5.0 release introduced the block editor alongside the default Twenty Nineteen theme, demonstrating how to add block editor features and explore its power.

In other words, the evolution toward FSE has been building for a while. And because of that, we get to enjoy a high level of backwards compatibility that allows us all to adopt block-based features when we’re good and ready.

The anatomy of block-based themes

Experimental block-based themes have been in development since early 2020. At the time I’m writing this, the GitHub theme experiment repository lists 12 block themes that explore some aspect of creating themes using blocks or block templates.

But it was probably the Twenty Twenty-One theme that was the first “default” theme to make blocks a first-class citizen, introducing block styles and block patterns, though the recently updated versions of Twenty Nineteen, and Twenty Twenty also include bundled block styling and block patterns. Currently, there are more than 130 themes from the community with bundled block editor patterns, block styles feature, including my favorite, Anders Noren’s Eksell theme.

With the ongoing development of the WordPress Block Editor’s FSE features, even more block-based themes are also being introduced.

So, what does the development of block-based themes mean for those of us who are deeply entrenched in the “classic” way of building WordPress themes? That’s what I want to look at in this section.

The file structure of block themes

In classic PHP-powered theming, markup elements are generated with PHP and JavaScript, while in block themes those templates are entirely composed of HTML blocks and structural CSS provided by the block editor. This might sound scary for lots of folks, but it’s easy to imagine just how liberating it is for others as it lowers the bar when it comes to developing a WordPress theme.

The structure of a block theme is drastically different from the classic WordPress Template Hierarchy that we all are used to. In classic PHP-based themes, page element markup has to be generated with PHP and JavaScript, whereas in block themes, the WordPress Core provides both the markup and basic styling. For example, the default Twenty Twenty-One theme contains 48 PHP files and 11 JavaScript files weighing in at 4.5 MB. Its block-based sibling, the experimental TT1 Blocks theme, contains only four PHP files, one JavaScript file, and eight HTML files at 3.5 MB.

Screenshot of a Mac window open to the default Twenty Twenty-One WordPress theme, displaying a long list of files.
Twenty Twenty-One theme folder
Screenshot of a Mac window open to the TT1 theme folder, showing that WordPress Block Themes contain fewer files.
TT1 theme folder

A block theme structure can be very simple with just a few required files : index.php, style.css and template/index.html. The following is a typical block theme file structure, pulled from the WordPress Editor Handbook:

#! basic block-theme structure
theme
|__ style.css
|__ functions.php
|__ index.php
|__ theme.json
|__ templates
    |__ index.html
    |__ single.html
    |__ archive.html
    |__ ...
|__ parts
    |__ header.html
    |__ footer.html
    |__ sidebar.html
    |__ ...
  • styles.css: Contains theme’s style sheet
  • functions.php: Contains theme setup and may include additional files, enable an editor style sheet, and enqueue style.css, if there are any
  • index.php: An empty file to switch to default file in case the block theme is activated without the WordPress Block Editor.
  • theme.json: Optional configuration file used to enable or disable features and set default styles for both the website and blocks
  • templates: Contains page templates that are composed of blocks. These files follow the same template hierarchy as traditional themes.
    • index.html: The primary template to generate a post or page, analogous to index.php in classic themes
    • single.html: The template to generate single posts or pages
    • archive.html: The template to generate archive lists of posts
  • parts: The common collections of blocks to be used in block templates
    • header.html: The global header block
    • footer.html: The global footer block
    • sidebar.html: An optional global sidebar block

A list of theme blocks including that are specific to block themes is available in WordPress Block Editor Handbook.

Templates and template parts

Templates are basically group of assembled blocks that might include reusable block parts, like a site header or footer. Different blocks are used to compose a page template. For example, that might be a list of blog posts, a list of products, or even a widget.

Here’s an example of a block template pulled from the WordPress Block Editor Handbook.


<!-- wp:site-title /-->

<!-- wp:image {"sizeSlug":"large"} -->
<figure class="wp-block-image size-large">
    <img src="https://cldup.com/0BNcqkoMdq.jpg" alt="" />
</figure>
<!-- /wp:image -->

<!-- wp:group -->
<div class="wp-block-group">
    <!-- wp:post-title /-->
    <!-- wp:post-content /-->
</div>
<!-- /wp:group -->

<!-- wp:group -->
<div class="wp-block-group">
    <!-- wp:heading -->
    <h2>Footer</h2>
    <!-- /wp:heading -->
</div>
<!-- /wp:group -->

Creating WordPress Block Themes

The WordPress Site Editor is now the primary tool for defining the look and feel of a WordPress website. You may be used to using the WordPress Customizer to do these things — and some themes have heavily tapped into that to do what the site editor is now designed to do.

So, no longer is the block editor for pages and posts; it’s the way WordPress themes are created.

I’m assuming that many of you have already used the block editor, and don’t really need a deep lesson on what it is or how to use it. That said, it’s worth poking at it a bit since it’s the impetus for everything related to WordPress theming moving forward, now that WordPress 5.9 is in the wild.

In fact, when we talk about block editing and theming, yes, we’re talking about the block editor. But really what we’re talking about is the WordPress Site Editor.

The WordPress Site Editor interface

Even as an early adopter of the Gutenberg plugin, I find the experience of the site editor intimidating and frustrating. It changes frequently and often drastically with each new release. I am hopeful, though, that WordPress 5.9 is a sort of line in the sand that helps stabilize that rocky feeling.

The site editor is accessed the same way you’re already used to accessing the WordPress Customizer. It’s located under Appearance in the dashboard menu, called Editor.

Screenshots of the WordPress admin Themes screen side-by-side, the first showing the classic WordPress menu items like Customize, Widgets, and Menus, while the second shows how a WordPress Block Themes only displays a single Editor menu item.
The site editor option is available only when a block theme is activated. If you’re using a classic theme, you’ll get the classic UI to go with it.

Let’s briefly walk-through the new Editor interface.

First, navigate to the site editor by clicking Appearance → Editor from the WordPress admin menu. That menu item may have a red “beta” label on it, like it currently does in WordPress 5.9.

That takes you to the site editor, which displays either your homepage or post archive, depending on what you have your homepage set to in Settings → Reading. From there it sort of looks like the fullscreen version of the block editor when creating or editing a page or post. But click on the WordPress logo in the top-left of the screen, and a left panel opens up revealing the WordPress Site Editor and its menu to navigate between different parts of the site. This includes Site, Templates, and Template Parts.

Screenshot of the WordPress Site Editor. There is a dark gray left panel open with an Editor heading and three links for Site, Templates, and Template Parts. The main content shows a preview of the site homepage in the WordPress Block Editor.

Let’s click into Templates. This shows us a list of the available templates provided by the theme, complete with a description of each one and where it is registered (e.g. the parent or a child theme).

Screenshot of the site editor's Templates screen which shows a two-column table listing template on the left and who a template was added by on the right.

The other way to get to this screen is from the initial page we landed on when entering the site editor. Click the name of the template in the top admin bar to reveal a button that takes you directly to the same Templates screen.

Screenshot of the Home template open in the WordPress Site Editor. The template name is at the top of the screen in a white toolbar and is expanded with a submenu that describes the template and provides a black button with white text to view all templates.

Any of templates can be edited just like any page or post in the block editor. Let’s say I don’t like to have a featured image on my index page and want to remove it. Simply delete the featured image block and save the template.

The other key part of the site editor UI is a list view that outlines the current blocks that are placed in the template. This has been a feature in WordPress since the introduction of the block editor, but what’s new this time around is that you can open and close parent blocks that contain child blocks like an accordion. Not only that, but it supports dragging and dropping blocks to change the layout directly from there.

The WordPress Site Editor with a white left panel expanded revealing an outline of the current blocks that are applied to the template.

One more thing in the site editor UI: you can clear out customizations with the click of a button. From the Templates screen, click the kebob menu next to a template and select the option to Clear customizations. This is a nice way to reset and start from scratch, should you need to.

Screenshot of the Template Parts screen in the WordPress Site Editor, showing a two-column able with a column that displays template names, and a column that identifies the location of the template part.

The WordPress Core team publishes regular updates on what’s new at Make WordPress Core. It’s worth bookmarking that to stay posted on the latest changes to the WordPress Block Editor and Site Editor.

Creating Templates and Template Parts

Templates, as you know, are core to WordPress theming. They enforce consistent and reusable layouts. That doesn’t change in WordPress 5.9. And neither does the fact that we can create template parts that are like module pieces that can be used in multiple template, say a post query that lives in an archive template and the home template.

What’s different in WordPress 5.9 is that they are created and managed with the site editor rather than PHP files that live in the theme folder.

The Block Editor Handbook lists three ways to create templates and template parts: (a) manually, by creating HTML files containing block markup, (b) using the site editor, and (c) using the template editing mode in the block editor.

Brief descriptions of creating template in the site editor and template editing mode are available in the Block Theme handbook. The WordPress 5.9 allows to create a new template using editor mode.

Screenshot of the Template Parts screen open in the WordPress Site Editor. A modal is open above the UI that contains an interface to create a template part, including the part's name and area.

The customized templates can then be exported to include in a block theme. So, yeah, we now have the ability to create a fully functioning WordPress theme without writing a line of code! The exported folder currently does not contain theme.json file, however there is a proposal over at GitHub to allow exporting both block themes and styles.

Screenshot of the WordPress Site Editor preferences panel open as a white panel to the left of the screen.

But for those who prefer working more closely with code, then manually creating WordPress templates and template parts is still a thing. You can still crack open a code editor and create HTML files containing block markup.

Global settings and styles (theme.json)

In classic themes, we write the styling rules in a style.css file. In block themes, styling is more challenging because CSS comes from different sources (e.g. core blocks, themes, and users). WordPress 5.8 introduced a concept of Global Styles — which is essentially a theme.json file — that, according to the docs, consolidate “the various APIs related to styles into a single point – a theme.json file that should be located inside the root of the theme directory.“

Screenshot of a theme dot jayson file open in the VS Code editor. The file contains objects for version and settings. The settings object contains a color object. The color object contains a palette objects which contains properties for slightly, color, name, and default.

The theme.json file is said to have been designed to offer more granular styling structure for theme authors with options to manage and customize the CSS styles coming from various origins. For example, a theme author may set certain styling features that are hidden from users, define default colors, font sizes and other features available to the user, and may set the default layout of the editor as well. Plus, theme.json allows you to customize styling on a per-block basis. It’s powerful, flexible, and super maintainable!

The block editor is expected to provide all the basic styling that theme authors are allowed to customize style, as defined by the theme.json file. However, the theme.json file could get quite long for a complex theme, and currently there is no way to partition it in a more digestible way. There is a GitHub ticket to restructure it so that different theme.json files map to a /styles folder. That would be a nice enhancement for developer experience.

The default Twenty Twenty-Two theme is a good example of how WordPress full-site editing features use theme.json for global settings and styling blocks.

WordPress Block Theme approaches

Maybe you’ve always made WordPress themes from scratch. Perhaps you’ve relied on the Underscores theme as a starting point. Or maybe you have a favorite theme you extend with a child theme. The new features of the WordPress Site Editor really change the way we make themes.

Following are a few emerging strategies for block-based theme development that are deeply integrated with the WordPress Site Editor.

Universal themes

The Automattic team has built a Blockbase universal theme that’s dubbed as a new way to build themes, sort of similar to the Underscores starter theme. The Blockbase theme provides temporary “ponyfill” styles that the block editor “does not yet take into account on theme.json ‘custom’ properties” and that may eventually become obsolete once the Gutenberg plugin fully matures and is integrated into WordPress Core.

Using the universal parent theme approach, the Automattic has already released eight Blockbase child themes, and several others are in progress over at GitHub.

Twenty Twenty-Two default theme

The Twenty Twenty-Two default theme is another excellent starting point, as it’s really the first WordPress theme that ships with WordPress that is designed to work with the site editor.

In my opinion, this theme is excellent for theme developers who are already familiar with FSE features to showcase what is possible. For others users who are not developers and are not familiar with FSE features, customizations it in the block editor, then exporting it as a child theme could be painfully frustrating and overwhelming.

Hybrid themes

The concept of “Hybrid” themes in the context of FSE is discussed in this GitHub ticket. The idea is to provide paths for any user to use the site or template editor to override traditional theme templates.

Justin Tadlock in this WP Tavern post predicts four types of themes — block only, universal, hybrid, and classic — and speculates that theme authors may split between “block themes and a mashup of classic/hybrid themes.”

Proof in the pudding is provided by Frank Klein in “What I Learned Building a Hybrid Theme”:

A hybrid theme mixes the traditional theming approach with full-site editing features. A key component here is the theme.json file. It offers more control over the block editor’s settings, and simplifies styling blocks. A hybrid theme can use block templates as well, but that’s optional.

Frank is the author of the Block-Based Bosco theme and has expanded further on what a “hybrid theme” is by creating a hybrid version of the default Twenty Twenty theme. The theme is available on GitHub. Currently, there are no hybrid themes in the WordPres Theme Directory.

WordPress community themes

At the time of writing, there are 47 block-based themes with FSE features available in the theme directory. As expected, this approach is widely varied.

For example, in this post, Aino block theme author Ellen Bower discusses how they converted their classic theme into a block theme, detailing what makes a theme a “block” theme. The file structure of this approach looks different from the standard block theme structure we covered earlier.

Another popular block theme, Tove by Andars Noren, is described as a flexible base theme that follows the standard block theme file structure.

There’s also a very simple single page proof of the concept theme by Carolina Nymark that contains nothing but a single index.html called Miniblock OOAK. It’s already available in the theme directory, as is another one from Justin Tadlock that’s a work in progress (and he wrote up his process in a separate article).

Block Theme Generator app

Even though we’ve already established how friendly WordPress Block Themes are for non-developers, there are tools that help create complete block themes or merely a customized theme.json file.

David Gwyer, an Automattic engineer, has been working on a Block theme generator app which, at the time of writing, is in beta and available for testing by request.

Screenshot of the Block Theme Generator app homepage. It has a bright blue background and dark blue text that welcomes you to the site, and a screenshot of the app.

In my brief testing, the app only allowed me to generate customized theme.json file. But Gwyer told to WP Tavern that the app isn’t fully baked just yet, but features are being added often. Once complete, this could be a very helpful resource for theme authors to create customized block themes.

Block themes that are currently in use

This Twitter thread from Carolina Nymark shows some examples of block themes that are live and in production at the time of this writing. In a recent Yoast article, Carolina listed a bunch of personal and business websites that use block themes.

Personal sites

Business sites

As I mentioned earlier, I also have been using a block theme for one of my personal websites for a while. The default Twenty Twenty-Two theme also currently shows more than 60,000 active installs, which tells me there are many more examples of block-based theme implementations in the wild.

Building Block Child Themes

Child theming is still a thing in this new era of WordPress blocks, though something that’s still in early days. In other words, there is no clear approach to do make a block-based child theme, and there are no existing tools to help at the moment.

That said, a few approaches for creating WordPress child block themes are emerging.

Create Blockbase Theme plugin

The Automattic team is working on a plugin called Create Blockbase Theme. This will make it fairly trivial to create child themes based on the Blockbase universal theme we talked about earlier. Ben Dwyer has discussed how theme authors can build Blockbase child themes with simple six steps and without writing a line of code.

I tested the plugin in my own local environment, making only small changes to my Blockbase theme install, and everything appeared to work. Just note that the plugin is still experimental and under development, though you can follow the roadmap to see what’s up.

Using an alternate theme.json file

Kjell Reigstad, author of the default WordPress Twenty Twenty-Two theme, demonstrates how swapping a single theme.json file with another theme.json file that contains different style configurations can change the look and feel of a block-based theme design.

Kjell has opened a pull request that shows off several experimental child themes that are available for testing at the GitHub theme-experiment GitHub repository.

A three-by-two grid of screenshots of child themes based on the default WordPress Twenty Twenty-Two theme in alternate colors schemes.

Along these same lines, Ryan Welcher is in the process of developing a theme.json builder tool that will generate a customized theme.json file to facilitate non-coders to create similar child themes. More can be found in this WP Tavern post.

The Framboise child theme (available in theme directory) is an early example of that approach which includes only a single theme.json file.

Is there even a need for child themes?

Rich Tabor asks the question:

Indeed, a single theme.json file could serve as a child theme on its own. There is an ongoing discussion about allowing theme authors to ship multiple theme.json files with block themes that offer multiple global style variations. This way, a WordPress user could pick one of the variations to use on the site.

Some features of global style variations are already included in Gutenberg v12. 5 and expected to be available with WordPress 6.0.

Some personal thoughts

I’d be remiss to end this without weighing in on all this from a personal level. I’ll do this briefly in a few points.

Block themes are a WordPress answer to Jamstack criticisms

Jamstack enthusiasts have lobbed criticisms at the WordPress platform, most notably that WordPress themes are bloated with PHP files. Well, that’s no longer the case with WordPress Block Themes.

We saw earlier how an entire theme can be a single index.html file and a theme.json file. No bloat there. And nothing but markup.

I miss the WordPress Customizer

Especially the ability to inject custom code. From here on out, it’s going to require a deep level of familiarity with the WordPress Site Editor UI to accomplish the same thing.

Customizations a site is easy-peasy.

Customizing a classic theme — even something as minimal as changing fonts — can be difficult if you don’t know what you’re doing. That’s changed now with the site editor and the introduction of the theme.json file, where a theme can be customized (and even exported!) without writing a single line of code.

I still hold my opinion, though that the site editor interface is confusing. I think a pleasant user experience is a far ways off but looking forward to the next WordPress 6.0 release for better user experience.

Barriers to designing themes is getting lower.

It’s less about PHP and template files, and more about developing patterns and creating content. That sounds exactly what a content management system should be designed to do! I am already excited with new features being considered for the WordPress 6.0 release.

Resources

There is already a ton of other articles that cover WordPress Block Themes, full-site editing, and the block editor. And many of those came before WordPress 5.9 was released!

So, in addition to this article, here’s a collection of others for you to consider as you begin or continue down your journey of WordPress blocks and site editing.

WordPress 5.9

Site editor and block themes

Selected blog posts


As expected in beta testing, the site editor is still intimating and confusing, nevertheless, I am finding it a fun to work with block themes. Indeed, I have been already modifying Twenty Twenty-Two as a child theme and plan to create style alternatives using single theme.json file.

Have you been using block themes in your project, if so, share your experience and thoughts; I love reading any comments and feedback!


A Deep Introduction to WordPress Block Themes originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-deep-introduction-to-wordpress-block-themes/feed/ 8 362799