Theme.json configuration with modern Sass (SCSS) features (@use, @forward)
Chisel theme combines WordPress’s
theme.jsondesign tokens with a modular SCSS architecture. Global styles (color palette, typography, spacing, etc.) are declared intheme.jsonand emitted as CSS Custom Properties, while SCSS composes styles via@use/@forwardfor clear, dependency‑safe modules.
Overview
- theme.json: defines color palette, typography, spacing scale, layout, and custom tokens exposed as CSS variables.
- Sass modules: design system split into
settings(tokens) andtools(functions/mixins) using@use/@forward. - Goal: Create styles with stable design tokens while staying aligned with WordPress Global Styles.
theme.json highlights
- Colors
- Custom palette (e.g.,
foreground,background,primary,secondary, etc.). - Available in CSS as
-wp--preset--color--{$slug}and in SCSS withget-color($slug)function - Example use:
- Custom palette (e.g.,
@use '~design' as *;
color: get-color('primary');
background: get-color('background');SCSS- Typography
- Fluid font sizes and a curated
fontSizesscale (small→huge), exposed as-wp--preset--font-size--{slug}and can be used with SCSSget-font-family($slug)function - Custom
fontFamilieswith local files viafile:./assets/fonts/*.woff2:- Body:
Quicksand(-wp--preset--font-family--body)
- Body:
- Example use:
- Fluid font sizes and a curated
@use '~design' as *;
font-family: get-font-family('body');
font-size: get-font-size('normal');SCSS- Spacing
- Custom scale generated via
spacingScaleand enumerated inspacingSizes. - Exposed as
-wp--preset--spacing--{slug}and can be used with SCSSget-padding($slug)orget-margin($slug)functions.
- Custom scale generated via
- Layout
contentSizeandwideSiz**e**used by block editor and templates.
- Global styles
- Base colors, typography, element defaults (links, headings), and block-level spacing rules.
- Blocks
- Per‑block spacing and gap customizations for core blocks.
How theme.json and Sass connect
- CSS variables from theme.json are globally available (e.g.,
-wp--custom--gap--medium). - Sass tools provide ergonomic functions to reference those variables without hardcoding strings.
- Example:
// src/design/tools/_theme.scss
@function get-padding($key) {
@return var(--wp--custom--padding--#{$key});
}SCSSThis makes token usage consistent and refactor‑friendly.
- Best practice: Create components using functions/tokens instead of literals:
@use '~design' as *;
.card {
padding: get-padding('medium');
color: get-color('foreground');
@include bp('medium') {
// bp() is defined in design/tools/_breakpoints.scss
padding: get-padding('large');
}
}SCSSUsing @use and @forward
- Importing tools globally in a file:
@use '~design' as *; // forwards all toolsSCSS- Importing settings explicitly:
@use '../design/settings' as settings;
.grid {
gap: map.get(settings.$gaps, 'normal');
}SCSS- Why this matters:
@usenamespacing avoids variable collisions.@forwardcentralizes what a consumer needs (you importdesignonce, not every tool file).- Clear separation between tokens (
settings) and behaviors (tools).
Using @use and @forward (Sass modules) — short guide
- @use: imports a Sass module once and namespaces its members (variables, mixins, functions).
Basic:
@use '../design/tools'; // access as tools.$var, tools.fn(), tools.mixin()
@use '../design/tools' as *; // flatten into current scope (be careful with naming)
@use '../design/tools' as t; // custom namespaceSCSSWith configuration (override module variables at load time):
@use '../design/settings' with (
$root-font-size: 18px
);SCSS- @forward: re-exports members from another module to build a public API.
In the theme, src/design/_index.scss.This means consumers can just:
@forward 'tools';SCSS@use '../design' as *; // gets everything forwarded by tools/_index.scssSCSSYou can curate exports in a tools/_index.scss:
// src/design/tools/_index.scss
@forward 'breakpoints';
@forward 'px-to-rem';
@forward 'theme';
// etc.SCSS- Why modules (vs @import):
- Single evaluation, no duplication.
- Namespacing avoids collisions.
- Clear, composable public API via
@forward.