theme.json for Designers: A Practical Guide to WordPress Block Themes
Many of the core design decisions in a modern WordPress theme — colours, typography, spacing, content widths and block styles — can be centralised in a theme.json file.
For designers working with block themes, this makes theme.json an important bridge between a design system and its implementation in WordPress. Instead of relying on a collection of unrelated CSS rules and PHP configuration, a theme can express many of its design choices in a structured format that WordPress itself understands.
This guide explains how theme.json works from a designer's perspective: what belongs in it, how it relates to Global Styles, how to define palettes and typography, how responsive styles work, and where CSS is still appropriate.
Key takeaways
theme.jsoncentralises many design settings and styles used by WordPress block themes.- Designers can define approved colour palettes, typography scales, spacing presets and layout widths that are available throughout the editor.
- Settings can restrict or enable design tools, helping editors work within an established visual system.
- Global Styles and block-specific styles can use the same design tokens, reducing duplication and design drift.
- WordPress 7.1 adds responsive style states for mobile and tablet, extending what can be controlled through the WordPress styling system.
- Style variations can provide alternative palettes, typography systems or complete visual treatments without requiring a separate theme.
theme.jsonreduces the need for custom CSS, but does not replace CSS in every situation.- Templates, template parts and patterns work alongside
theme.json; they are not contained entirely within it.
What is theme.json?
Introduced in WordPress 5.8, theme.json is a configuration file that allows themes to define settings and styles understood by both WordPress and the block editor.
A typical theme.json file sits in the root directory of a theme.
In classic themes, design decisions were commonly distributed across style.css, functions.php, theme options and other configuration. theme.json provides a standardised way to centralise many of these decisions.
From a designer's perspective, it can be considered part of the implementation layer of a design system. It can describe approved colours, font families, font sizes, spacing presets, content widths and default styles, while also controlling which design tools are available to content editors.
This helps bring the editing experience closer to the intended front-end design.
theme.json does not contain the entire site architecture. Templates, template parts and patterns remain separate resources, but they can all use the settings, presets and styles established by theme.json.
Why designers should care about theme.json
The main advantage is not that designers suddenly need to become developers. It is that many design decisions can be expressed in a format that WordPress understands consistently.
Consistency
A defined palette, typography scale and spacing system gives editors approved choices instead of requiring them to remember hexadecimal colour values, font sizes or arbitrary spacing measurements.
This can reduce design drift: the gradual appearance of slightly different colours, inconsistent type sizes and irregular spacing as more pages are created.
Better collaboration
A designer can define the intended tokens and rules while a developer implements them in theme.json.
Instead of a specification saying simply “use the brand blue”, the implementation can contain a named brand-primary colour preset that WordPress exposes throughout the editing interface.
The design specification and the WordPress implementation therefore share a recognisable vocabulary.
Controlled flexibility
A design system does not necessarily mean preventing editors from making design decisions.
theme.json can determine which choices should be fixed and where editors should have flexibility. A site might restrict colours to an approved palette while allowing editors to choose among several predefined spacing or typography options.
Easier maintenance
When a design token is used consistently, a later change can be made centrally.
If the organisation's primary colour changes, updating the corresponding preset can affect the places that use that preset rather than requiring individual colour values to be found throughout the theme.
The basic structure of theme.json
A theme.json file is standard JSON. Its available top-level properties include:
$schema— identifies the JSON schema used for validation and editing assistance.version— identifies thetheme.jsonschema version.settings— defines presets and controls available through the editor.styles— establishes default visual styles.customTemplates— provides metadata for custom templates.templateParts— provides metadata for template parts.patterns— can register patterns from the WordPress.org Pattern Directory.
Not every property is required.
A simple starting point might look like this:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {},
"styles": {}
}Schema version 3 is the current theme.json schema generation.
The file must be valid JSON: keys and strings use double quotation marks, items are separated by commas, and there is no trailing comma after the final item.
Designers do not need to memorise every available property. It is more useful to understand how the main sections correspond to familiar design decisions.
Using the JSON schema
The $schema property is particularly useful when editing theme.json in a compatible code editor such as Visual Studio Code.
For current development, a theme can use:
"$schema": "https://schemas.wp.org/trunk/theme.json"
This points to the current schema.
A team that deliberately targets a particular WordPress version can instead use a version-specific schema URL. Pinning the schema in this way helps ensure that autocomplete and validation correspond to the WordPress version the project supports.
The schema tells a compatible editor which properties are valid, what kind of values they accept and where they belong. This enables features such as autocomplete, inline documentation and error highlighting.
For designers who are comfortable working with design tokens but less familiar with JSON, these hints make the file considerably easier to navigate.
Settings: defining the design guardrails
The settings section primarily defines the options and tools WordPress makes available rather than the site's finished appearance.
It answers questions such as:
- Which colours can editors choose?
- Which font sizes are available?
- Can editors enter arbitrary colours?
- Which spacing controls are enabled?
- What are the standard and wide content widths?
This is where theme.json becomes particularly useful for maintaining a design system.
A tightly controlled corporate site might expose only approved colours and type sizes. A more flexible editorial site might provide additional controls while still supplying sensible presets.
Important areas include color, typography, spacing, layout and appearanceTools.
appearanceTools can enable a group of additional design controls, including spacing, borders and link-colour tools, where the relevant blocks support them.
Designing a colour palette with theme.json
Colour is one of the clearest examples of translating a design system into WordPress.
A palette can be defined under settings.color.palette:
{
"settings": {
"color": {
"palette": [
{
"slug": "brand-primary",
"name": "Brand Primary",
"color": "#1A3D7C"
},
{
"slug": "brand-accent",
"name": "Brand Accent",
"color": "#FF6B35"
},
{
"slug": "neutral-light",
"name": "Neutral Light",
"color": "#F5F5F5"
}
],
"custom": false
}
}
}Each colour receives a machine-readable slug, a human-readable name and a colour value.
WordPress then generates CSS custom properties such as:
--wp--preset--color--brand-primaryThese variables can be used elsewhere in the theme.
The palette exposes approved brand colours as presets in compatible editor controls. Setting custom to false disables custom colour selection, which is useful when the design requires stricter control.
A good palette should do more than reproduce a brand guideline. Designers should consider how each colour will actually be used.
Define appropriate colours for text, backgrounds, accents and interactive elements, and test intended text/background combinations for sufficient contrast. Naming should also remain consistent with the terminology used in design tools such as Figma.
Defining typography
Typography usually involves two related areas of theme.json.
The settings.typography section defines the options available to editors, while styles.typography can establish the typography actually applied by default.
A simplified font-family configuration might look like this:
{
"settings": {
"typography": {
"fontFamilies": [
{
"slug": "sans-ui",
"name": "Sans UI",
"fontFamily": "'Inter', sans-serif"
},
{
"slug": "serif-display",
"name": "Serif Display",
"fontFamily": "'Playfair Display', serif"
}
]
}
}
}A type scale can be represented with named font-size presets:
{
"fontSizes": [
{
"slug": "small",
"size": "0.875rem",
"name": "Small"
},
{
"slug": "medium",
"size": "1rem",
"name": "Medium"
},
{
"slug": "large",
"size": "1.5rem",
"name": "Large"
},
{
"slug": "xl",
"size": "2.25rem",
"name": "Extra Large"
}
]
}These presets become available through typography controls on blocks that support them.
If arbitrary font sizes are inappropriate for the project, custom font sizing can be disabled so editors work from the established scale.
WordPress also supports fluid typography. This allows type sizes to scale between minimum and maximum values according to viewport size rather than relying entirely on fixed sizes and manually written media queries.
Line height should be considered alongside font size to maintain comfortable reading across different screen sizes.
Spacing and layout
Spacing is another area where small inconsistencies can accumulate quickly.
Instead of allowing every page to use arbitrary margins and padding, theme.json can define spacing presets that represent the design system's intended rhythm.
Editors can then select those presets when supported by a block.
Layout settings establish the principal content widths:
{
"settings": {
"layout": {
"contentSize": "720px",
"wideSize": "1200px"
}
}
}contentSize establishes the normal content width, while wideSize provides the width used for wide-aligned content.
For designers, these values provide a direct connection between layout specifications and the WordPress implementation.
useRootPaddingAwareAlignments can also help coordinate root-level padding with wide and full-width content, avoiding some of the custom CSS that would otherwise be required to maintain consistent alignment.
Responsive styles in WordPress 7.1
Responsive styling is an important addition for designers working with current WordPress block themes.
WordPress 7.1 introduces responsive style states that allow styles to vary for mobile and tablet contexts within the WordPress styling system.
The system provides @mobile and @tablet states. The normal style acts as the base presentation, so a separate @desktop state is not required.
WordPress uses default breakpoints of 480px for mobile and 782px for tablet, and themes can configure these values through settings.viewport.
This means that many common responsive adjustments can be represented within the theme's structured styling system rather than requiring a separate custom media query for every change.
It does not eliminate the need for CSS in complex responsive designs. It does, however, give designers and developers another standardised way to express responsive decisions.
Fluid typography, spacing presets and responsive style states can therefore work together: fluid values handle gradual scaling, while responsive states handle design changes that should occur at defined viewport thresholds.
Global Styles and block-specific styles
If settings determines what options exist, styles determines how elements should look by default.
For example:
{
"styles": {
"color": {
"background": "var(--wp--preset--color--neutral-light)",
"text": "var(--wp--preset--color--brand-primary)"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--sans-ui)",
"lineHeight": "1.6"
}
}
}These values establish global defaults using the presets already defined by the theme.
Designers can also target HTML elements through styles.elements. Headings, links and buttons can receive default styles without relying on conventional CSS selectors for every rule.
Individual blocks can be styled through styles.blocks.
For example, a Quote block might use a particular type treatment while the Navigation block uses its own spacing rules. Both can still reference the same shared colour, typography and spacing presets.
This is one of the most useful aspects of theme.json: design tokens, global defaults, element styles and block-specific rules can be expressed within the same system.
It does not mean that CSS becomes unnecessary. Complex selectors, specialised interactions, animations and other requirements may still be better handled with stylesheets. The objective is to use theme.json for the design decisions it represents well and CSS where CSS remains the appropriate tool.
Creating style variations
A designer does not always want a single visual treatment for a theme.
WordPress style variations make it possible to provide alternative combinations of colours, typography and other styles without creating a separate theme.
Variations can be stored in the theme's /styles directory and offered through the Styles interface.
A variation might provide a dark treatment, an alternative brand palette or a different typographic personality while retaining the same underlying templates and blocks.
More focused variations can concentrate on particular areas such as colour or typography.
This is especially useful when a design system contains approved alternatives rather than a single rigid visual configuration.
For example, an organisation could provide a default corporate palette alongside an approved high-contrast variation. A publication might offer several typography treatments while retaining the same layout system.
Style variations allow those alternatives to remain deliberate parts of the theme rather than becoming collections of manual overrides.
Working with templates and template parts
theme.json works alongside the structural elements of a block theme.
Template parts can be described with metadata such as:
{
"templateParts": [
{
"name": "header",
"title": "Header",
"area": "header"
},
{
"name": "footer",
"title": "Footer",
"area": "footer"
}
]
}These entries describe reusable structural areas such as headers and footers.
customTemplates can provide metadata for alternative templates, such as a special landing-page layout.
The distinction is useful:
theme.jsondefines design settings, styles and related metadata.- Templates determine the broader structure of pages and content types.
- Template parts provide reusable structural areas such as headers and footers.
Keeping these responsibilities separate makes a block theme easier to understand and maintain.
How patterns relate to theme.json
Patterns are reusable compositions of blocks. They might represent a hero section, testimonial layout, article introduction or call to action.
They work particularly well with theme.json because they can use the theme's established presets rather than embedding unrelated design values.
A pattern using brand-primary, for example, can respond when the value of that preset changes.
There are two different mechanisms worth distinguishing.
The patterns property in theme.json can register patterns from the WordPress.org Pattern Directory using their slugs.
Patterns bundled directly with a theme are normally stored as files in the theme's /patterns directory, where WordPress can register them automatically.
This makes patterns an important layer in a broader design system:
design tokens and global rules → blocks → patterns → templates
theme.json helps establish the rules that those other layers inherit.
A practical workflow for designers
A productive workflow starts with design decisions rather than JSON syntax.
First, define the design system in the tool your team normally uses. Identify the colours, typography, spacing, content widths and other reusable tokens.
Then determine which of those decisions belong in theme.json.
A typical workflow is:
- Define colours, typography, spacing and layout rules in a design tool such as Figma.
- Give reusable decisions clear, stable names.
- Translate those tokens into
theme.jsonsettings and styles. - Check the results in the block editor and Site Editor.
- Test templates, patterns and representative content.
- Test across relevant viewport sizes, devices and the browsers the project supports.
- Refine the design system when real content exposes problems that were not apparent in the original mock-ups.
Version control is valuable even when most decisions originate with designers. Changes to the palette, typography scale or spacing system can then be reviewed and traced.
Internal documentation can also map design terminology directly to WordPress presets:
| Design specification | WordPress implementation |
|---|---|
| Brand Blue | brand-primary |
| Accent Orange | brand-accent |
| Body Copy | medium font-size preset |
| Display Typeface | serif-display |
| Standard Content | contentSize |
The objective is not to force designers to think like programmers. It is to ensure that the names and rules used in design correspond clearly to their implementation.
Testing changes safely
Because theme.json can affect global styles, changes should be tested before deployment to a production site.
A staging environment allows designers and developers to inspect representative pages, templates and patterns with real content.
Pay particular attention to:
- headings of different lengths;
- unusual image proportions;
- forms and interactive blocks;
- mobile and tablet layouts;
- older content;
- third-party blocks;
- accessible colour contrast;
- patterns that rely heavily on theme presets.
JSON validation and version control also help catch configuration mistakes before deployment.
Does theme.json improve performance?
theme.json should primarily be viewed as a design and configuration system rather than as a performance optimisation.
Its structured approach can simplify the CSS architecture of a theme and reduce the need for some manually maintained global CSS. WordPress can also generate styles from the presets and rules defined in the file.
That does not mean a theme becomes faster simply because it uses theme.json.
Performance still depends on factors such as images, fonts, scripts, blocks, plugins, external resources and additional stylesheets.
WordPress also provides mechanisms for loading block-specific styles only when relevant blocks are present. Those mechanisms can improve CSS loading efficiency, but they should not be confused with a general promise that theme.json automatically generates only the CSS required by each page.
Frequently asked questions
Do I still need CSS if I use theme.json?
Usually, yes.
theme.json can handle many common design settings and styles, including palettes, typography, spacing, layout rules, element styles and block-specific styling.
CSS remains appropriate when the design requires capabilities that the structured theme.json system does not express well, such as complex selectors, specialised interactions, animations or unusual responsive behaviour.
The aim is not to eliminate CSS but to avoid using custom CSS for design decisions WordPress can already represent structurally.
Do I need a style.css file?
Do not treat style.css and theme.json as interchangeable files.
theme.json handles structured settings and styles for the block system. Stylesheets remain available for CSS that belongs outside that system, and WordPress also supports block-specific stylesheets.
The exact files required by a theme depend on its structure and the WordPress theme requirements being targeted, so theme developers should follow the current block-theme documentation rather than assuming that every theme needs the same classic-theme file structure.
Can theme.json style older or third-party content?
theme.json works most directly with blocks and features that support WordPress's Global Styles system.
Many third-party blocks integrate with these settings and presets, but support is not universal. Legacy markup and custom plugin output may still require conventional CSS.
Test representative content rather than assuming that every element will inherit the design system automatically.
Can designers edit theme.json themselves?
Yes, if they are comfortable working with structured text and understand the project's development workflow.
The JSON schema provides autocomplete and validation in compatible editors, which makes the file considerably more approachable.
In larger teams, designers may instead define the tokens and rules while developers maintain the implementation. Both approaches can work; the important point is that the design specification and theme.json remain aligned.
Is it safe to edit theme.json on a live site?
It is better to make and test theme changes in a development or staging environment.
Incorrect configuration can affect styles throughout the site. Using schema validation, version control and a staging environment makes it easier to detect problems and reverse changes when necessary.
What happens when WordPress adds new design tools?
New WordPress releases can add properties and capabilities to the theme.json system.
Themes do not need to adopt every new feature immediately. Review the release documentation, decide whether a new capability benefits the design system, and test it against the WordPress versions the theme supports.
The theme.json schema itself has evolved through several versions, so upgrading should be treated as a deliberate, tested change rather than assuming that every old and new property will behave identically forever.
From design system to WordPress
The most useful way for designers to think about theme.json is not as a replacement for CSS or as a configuration file that must be memorised.
It is a way to turn recurring design decisions into rules that WordPress understands.
A palette becomes a set of named colour presets. A typography specification becomes a collection of font families and sizes. Spacing values become reusable presets. Content widths become layout settings. Approved alternatives can become style variations. Responsive decisions can increasingly be represented within the same styling system.
Templates, patterns and blocks can then build on those shared foundations.
Used this way, theme.json becomes the connection between the design system and the WordPress editing experience: designers establish the visual language, developers encode the necessary rules, and content editors work with choices that already reflect the intended design.
Changed