Block Theme Building Tips

When building block themes there is often more than one way to achieve the same thing. It’s often not clear which of these options is preferable. Below I outline some tips and guidelines that I find helpful. The guiding principle here is to remove as much complexity as possible from the theme; instead block themes should be using the affordances provided by Gutenberg.

1. Avoid using CSS

As much as possible, block themes should avoid providing CSS. Gutenberg increasingly offers design tools which allow theme builder to control the design of the theme without using CSS. If it is not possible to achieve a particular design without CSS please create an issue for it on Gutenberg so we can consider adding a design tool to achieve the design.

2. Reuse patterns rather than implementing custom templates

As the number of block themes we build grows we will have an ever increasing number of templates and template parts in each theme. In practice there are a small number of patterns which can be reused on many themes. We should be aiming to reuse existing patterns rather than implementing new templates. This means we need clever patterns which are able to reuse settings from theme.json.

3. Prefer theme.json to block settings

Connected to the point above, when we want to change the appearance of a block in a template or a pattern it is usually better to do so in the theme.json file than in the block template. This means that the design will be used for all instances of the block, not just the edited instance. It also keeps templates design agnostic, so that they be reused (see above).

What other tips do you have for building block themes?

Create A Blockbase Child Theme

We have been working on a plugin to help you create a Blockbase child theme. The idea is that you can use the existing tools to make changes to a Blockbase theme, and then export a bundle of templates and theme.json as a new child theme.

I tried to create a new theme called “Typewriter” using these tools.

Step 1 – Setup

Install and activate Blockbase , and the Create Blockbase Theme plugin.

Step 2 – Global Styles

Make changes to your site using the Global Styles editor. First I chose some new colors:

You can also use the Global Styles editor to update Typography and Layout settings:

Then I changed the fonts, using the Customizer:

I made all my changes using the Global Styles editor and the Customizer, but you might want to make more changes directly to the theme.json file after the theme is created.

Step 3 – Templates

Edit your templates using the Site Editor:

I managed to achieve everything I needed to in this theme using the Site Editor, but for some things you might need to edit the template files directly once the theme is created.

Step 4 – Export

Under Appearance there will be a new page called “Create Blockbase Theme”:

You can add the details for the theme here. These will be used in the style.css file. When you click the “Create Blockbase Theme” button, a zip file will be downloaded, which contains all the files for your theme. Here’s mine:

Step 5 – Test

At this point you should have a zip file containing a working theme. You can upload this to your WordPress and activate it.

The theme contains an screenshot file, which you will need to update manually.

Now when you look at the frontend of your site it should look the same as it did before you activated the new theme. Here’s my new theme:

Further changes

Once the theme has been created you can unzip the theme zip file and make further changes to the theme files. This might be necessary to make more advanced changes to the theme. You can:

  • Modify and add configuration in the theme.json file.
  • Update the html template files in block-templates and block-template-parts
  • Add custom CSS to the file in assets/theme.css


We’d love you to try this new tool and let us know how you get on in the comments!

Universal Themes

Since our last post about Universal Themes we have fleshed out this idea and are using it to build all our themes.

The Problem

WordPress is introducing the Full Site Editor and with it new ways to build themes.  These themes are called “Block” themes and integrate deeply with Gutenberg Blocks. These types of themes require the use of the new (and still in development) Full Site Editor. 

The Site Editor is still being built, and block themes are in a nascent stage; they don’t yet offer the full gamut of features that will be available in the future. Block themes also require a very recent version of WordPress. How can we build themes which work with the classic dashboard to today and will continue to work with the Site Editor when it is more fully featured? This is the problem Universal themes are seeking to solve.

What is a Universal Theme?

Universal themes are an attempt to bridge the gap between the classic themes and block themes, by adding some layers to a block theme to make it work.

A Universal theme is a block theme that can use the Full Site Editor but can also be configured in a more classic way.  That means that you can use classic WordPress tools, like the Customizer, Menus and Widgets dashboards as well as the Site Editor.


Block themes load templates from the block-templates directory. However classic themes load them from the root. To ensure that we don’t end up duplicating code and that users can move between the Classic Dashboard and the Site Editor, we use the function gutenberg_block_template_part inside our classic templates. For example header.php:

<header class="wp-block-template-part">
	<?php echo gutenberg_block_template_part( 'header' ); ?>


Because block themes use html templates, its not possible to translate any copy inside them. In most cases we can avoid putting copy inside our templates, but there are some cases where it is impossible, for example the 404 page.

In these cases we are simply providing a classic template instead of a block template so that the strings can be translated. We can avoid any issues of code duplication by using the approach described above for templates. Here’s the 404.php from Blockbase:

 * The template for displaying 404 pages (not found)
 * @package Blockbase
 * @since 1.1.1
	<main class="container-404">
		<h1 class="has-text-align-center has-medium-font-size"><?php _e( 'Oops! That page can&rsquo;t be found.', 'blockbase' ); ?></h1>

		<p><?php _e( 'It looks like nothing was found at this location. Maybe try a search?', 'blockbase' ); ?></p>

		<?php echo do_blocks('<!-- wp:search {"label":""} /-->'); ?>

Fonts & Colors

Global Styles allows themes to customize their font and color options via theme.json. This gives universal themes a way to modify the fonts and colors in a theme, by modifying theme.json. In Blockbase we have attached some hooks to the font and color controls in the Customizer so that when you modify them the changes are made in theme.json. This gives us a single source of truth for these settings.


We have created a universal theme called Blockbase, which can be used as a parent theme; any child themes created with Blockbase will automatically be universal themes. You can learn more about Blockbase at


Universal themes are a temporary measure. As the Site Editor continues to improve and more features are added, the need for universal themes will diminish. These wrappers will be made obsolete and in time universal themes will become block themes.

Introducing Seedlet

A typography-led theme, built for the future of block-based theming.

This week the Automattic theme team launched a brand new theme called Seedlet. Seedlet is a simple, typography-driven foundation for folks to build their websites on. Its styles are opinionated, but generic enough that the theme can apply to a wide variety of different use cases.

This is a particularly exciting launch for us, because not only is Seedlet a lovely theme on the front end, but its backend was crafted with the future of theming in mind.

It ships with block patterns

As we’ve written before, block patterns are an incredible new tool for theme authors. We anticipate building these into every one of our themes going forward, giving users easy shortcuts to creating some of what they see in the theme demo.

Seedlet ships with a few patterns. Two of them leverage some creative use of gradient background presets, and the other makes your posts appear to snake down the page like a vine.

It’s built to be flexible

Behind the scenes, Seedlet has been built with a comprehensive system of CSS variables. If you’ve seen our Varia theme, you’ll be somewhat familiar with the system. Essentially, it’s a tiered system of variables inspired by modular CSS. In effect, everything from the site’s color palette to its spacing and structure is hooked into CSS variables.

Seedlet uses CSS variables as design tokens, instead of the SASS variables used in Varia. By relying on CSS variables for all of the core style attributes, we’re able to bridge the gap between the front end and the editor styles. If we change the value of Seedlet’s --global--color--background variable, the background of the site will update in both the front end and the editor immediately, with no compiling necessary.

CSS variables are also easily manipulated in the Customizer (as in Seedlet’s custom colors implementation), or in child themes. In the tests we’ve done, you can easily create a drastically different child theme by modifying only Seedlet’s CSS variables. Stay tuned for more to come on this, as we build out the first round of child themes based on Seedlet.

It’s ready for our block-based future

Seedlet’s extensive use of CSS variables also sets it up nicely to integrate with the block editor’s upcoming Global Styles functionality. CSS variables are what make Global Styles work, and Seedlet is full of them.

To demonstrate this transition, we put together a child theme that maps a number of Seedlet’s CSS variables to Global Styles values defined in experimental-theme.json. That, plus a few block templates, results in a fully functional, block-based version of Seedlet. You can explore this today by visiting Seedlet’s GitHub repository:

We plan to iterate on (and eventually launch!) this block-based version alongside the standard version of Seedlet.

We’re excited to see how Seedlet evolves as we continue moving towards block-based themes. In the meantime, give Seedlet a try, and feel free to contribute on GitHub if you’re so inclined.

Visit Seedlet on:

For more block-based exploration using Seedlet, check out this demo using Seedlet on the Gutenberg Times livestream:

A schema for Gutenberg blocks

At Jetpack we recently created a new Gutenberg block which displays “Related Posts”. This block is similar in content to the “Latest Posts” block in; it’s just a list of posts. The difference is the way the posts are displayed:

There are plans afoot to update the “Latest Posts” block, so that it contains an image and a post summary (see image below).

As these two blocks grow they seem to be converging on similar layouts, but with different content.

There are similar overlaps with other blocks. For example the layout of the gallery block could also be used to display a list of posts, as could the recently launched Tiled Gallery block. Evidently there are many layout possibilities for a list of posts!

The problem

As the number of Gutenberg blocks grows these overlaps become more obvious. As we start to build pages with Gutenberg it starts to become apparent that this is going to get very messy very quickly.

Essentially blocks have a content and a presentation element. Taking the example we began with, we can see overlap between many different types of content:

Lists of content

One type of content is a list of text, images and links. These come in many different forms, but they share the same structure:

  • Latest posts
  • List of posts in a category
  • List of post in a tag
  • Archive of posts by month/year etc
  • List of categories/tags
  • List featured posts
  • List of images
  • List of authors
  • List of [custom post type]

Similarly, all of the above types of content could be displayed in any of the following ways:


Here are some examples of the different types of layout that this content could use:

The challenge is that each of these different types content can be displayed in each of these different layouts. If we wanted to create blocks for each of these combinations we’d end up with over a hundred different blocks. On the other hand we could build one single block which was so complex that it could display all these combinations within one block. Neither of these would be sensible solutions.

Can we use Block Style Variations?

Block Style Variations offer an API which allows us to modify the CSS for a block – they let us overlay a presentation layer on top of an existing block. This is ideal when modifying the way a block looks. However many of the layout variations I have examined above require more than just a different CSS, they need different markup and additional JavaScript.

Separating Content and Presentation

One solution to this problem could be to separate content from presentation in our blocks. What if we were able to define semantics for the content in our blocks, which could be interpreted by different layouts? This would mean users would first think about the content they wanted to show, and then all display options would be open to them.

A Shared Data Structure

The overlap between these blocks occurs because they all share the same data structure (an array of text, image and link). It would be possible to define a standard data structure that blocks can use. When blocks share a data structure, then it should be possible for them to share common layouts. This would mean a photo gallery display could be reused to display a list of posts, or a block that displays a list of recent posts could be reused to show a list of authors.

How Could this work?

“Block Transformations” are an existing mechanism which converts one block into another. At present every transformation has to be coded separately.

Could we re-imagine the way that transformations work, so that if blocks share a common data-structure, they can easily be transformed into each other, without writing custom transformation code?

Similarly, could we make changes to the way “Block Style Variations” work, so that they can apply a layout to our structured data?


What do you think? Is this a problem? Are there other solutions I haven’t considered? Leave a comment!