Analytics cookies
We use optional Google Analytics to understand which tools are useful and improve the site. Analytics stays off unless you accept. Privacy Policy
Build, preview and export Gutenberg-ready spacing systems.
px at a 16 px root font size
Padding: Medium (50), 1.5rem, applied as written
Inside the section, around its content.
Gutenberg control: Range slider — 7 presets
7 or fewer presets: editors drag between 8 stops, None and then each preset by name. Editors can also switch to a custom value.
A simplified illustration of the block editor’s spacing control, not a copy of a particular WordPress version.
A theme.json fragment for version 3 (WordPress 6.6 and later), not a whole file. Merge its settings.spacing into your theme.json.
Your import also had spacingSizes, which are in Fluid Spacing System. This output contains only spacingScale.
{
"settings": {
"spacing": {
"defaultSpacingSizes": false,
"spacingScale": {
"operator": "*",
"increment": 1.5,
"steps": 7,
"mediumStep": 1.5,
"unit": "rem"
}
}
}
}The preset variables in the page’s CSS. WordPress generates them from theme.json, so you don’t add these yourself. Values marked as WordPress defaults come from WordPress’s own presets.
:root {
--wp--preset--spacing--20: 0.44rem;
--wp--preset--spacing--30: 0.67rem;
--wp--preset--spacing--40: 1rem;
--wp--preset--spacing--50: 1.5rem;
--wp--preset--spacing--60: 2.25rem;
--wp--preset--spacing--70: 3.38rem;
--wp--preset--spacing--80: 5.06rem;
}.section {
padding: var(--wp--preset--spacing--50);
}
.cards {
gap: var(--wp--preset--spacing--40);
}
.section + .section {
margin-block-start: var(--wp--preset--spacing--60);
}{
"styles": {
"spacing": {
"blockGap": "var:preset|spacing|40",
"padding": {
"top": "var:preset|spacing|50",
"bottom": "var:preset|spacing|50"
}
}
}
}Blocks and theme.json styles refer to a preset as var:preset|spacing|50; WordPress turns that into var(--wp--preset--spacing--50).
Spacing presets are the named sizes a block theme defines in settings.spacing of its theme.json. The block editor offers them in the padding, margin and block spacing controls, so a site uses a small, consistent set of sizes instead of whatever anyone types.
WordPress turns every preset into a CSS custom property, such as --wp--preset--spacing--50, and blocks store a reference to the preset rather than its value. Change the preset in theme.json and every block that uses it follows.
spacingScale describes a scale with five settings, and WordPress generates the presets from them. This is WordPress’s own default:
{
"spacingScale": {
"operator": "*",
"increment": 1.5,
"steps": 7,
"mediumStep": 1.5,
"unit": "rem"
}
}20 2X-Small: 0.44rem30 X-Small: 0.67rem40 Small: 1rem50 Medium: 1.5rem60 Large: 2.25rem70 X-Large: 3.38rem80 2X-Large: 5.06remMedium is written exactly as given; every other size is rounded to two decimals, as WordPress does. With a multiplier below 1, WordPress divides where it would multiply, so 0.5 gives the same scale as 2.
spacingSizes lists every preset yourself: a name, a slug and any CSS size, including clamp(). That is what the Fluid Spacing System writes. If a theme.json has both, WordPress merges them in theme.json version 3, and a spacingSizes preset replaces a generated one with the same slug.
WordPress gives the middle of a spacing scale the slug 50 and steps the other slugs by 10: 40, 30 and 20 below, 60, 70 and 80 above. A scale of up to 10 steps fits between 10 and 100 without renaming anything, and because every slug is a number, the editor can sort the presets by size. With an even number of steps, the extra preset goes above Medium.
The editor’s spacing control lists None followed by the presets. With 7 or fewer presets it is a range slider that steps through them by name. With more, the slider would get crowded, so the editor switches to a dropdown that also offers Default. A single preset gives the slider nothing to choose between, so the editor shows its custom value field instead.
The count includes WordPress’s default presets whenever they are switched on, which is why defaultSpacingSizes can turn a slider into a dropdown.
A fluid preset grows in a straight line between two viewport widths and holds its size outside them. The tool sets Medium’s size at the minimum and maximum viewport, multiplies by the scale ratio for each step, and writes each preset as clamp(minimum, preferred, maximum), with the preferred value in rem plus vw. The default Medium preset is:
clamp(1rem, 0.8571rem + 0.7143vw, 1.5rem)It is 16 px at 320 px and narrower, 19.2 px at 768 px, and 24 px at 1440 px and wider. The rem values assume the root font size set in the tool, 16 px by default; the preview and the readouts use the same rounded numbers as the copied CSS.
Font sizes can follow the same approach: CSS Clamp / Fluid Typography Generator writes a fluid type scale as CSS or as theme.json font size presets.
WordPress ships its own seven spacing presets, slugs 20 to 80. In theme.json version 3, defaultSpacingSizes decides whether the editor offers them:
Either way, the page’s CSS still defines the default variables for slugs your presets don’t use. When WordPress upgrades a version 2 theme.json that has spacing presets, it sets defaultSpacingSizes to false.
WordPress adds the preset variables to every page, so your theme’s CSS can use them directly:
.section {
padding: var(--wp--preset--spacing--50);
}In theme.json styles and in block markup, refer to a preset with the var:preset form. WordPress writes it out as the CSS variable:
"padding": {
"top": "var:preset|spacing|50"
}Import reads only settings.spacing from pasted text or a local file, in your browser. Nothing is uploaded or stored, and nothing else in the file is read.
A spacingScale loads into Native WordPress Scale exactly as written; missing settings are filled from WordPress’s defaults, as WordPress does. spacingSizes are kept exactly as written and copied back unchanged: the tool doesn’t guess generator settings from arbitrary CSS. Only when its fluid generator reproduces every preset character for character are those settings restored for editing. Values it can’t measure, such as var() or em sizes, are kept but shown without a bar.
Importing never changes your file. The output is a fragment to merge into theme.json yourself. To build or validate the complete file, use WordPress theme.json Generator.