WordPress 6.1+ supports fluid typography and fluid spacing natively in theme.json — font sizes and gap values that interpolate smoothly between a minimum and maximum value across the viewport width using clamp(), generated automatically by WordPress from declarative min and max fields. This eliminates the need for media-query-based typography breakpoints entirely.
Problem: A WordPress block theme uses fixed font sizes in theme.json — the same heading that looks right on a desktop is too large on mobile and too small on a very large screen, requiring multiple breakpoint overrides in CSS.
Solution: Use fluid typography in theme.json by setting a fluid object on font size entries with min and max values. WordPress generates a clamp() CSS value that scales linearly between the minimum and maximum viewport widths. Combine with fluid spacing values for consistent proportional scaling across all screen sizes.
The theme.json below defines a full fluid typography scale, fluid spacing presets, and shows the CSS that WordPress generates, along with block-level overrides for the Query Loop and Cover blocks.
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"typography": {
"fluid": true,
"fontSizes": [
{
"slug": "small",
"name": "Small",
"size": "0.875rem",
"fluid": { "min": "0.75rem", "max": "0.875rem" }
},
{
"slug": "medium",
"name": "Medium",
"size": "1rem",
"fluid": false
},
{
"slug": "large",
"name": "Large",
"size": "1.25rem",
"fluid": { "min": "1.1rem", "max": "1.4rem" }
},
{
"slug": "x-large",
"name": "X Large",
"size": "1.75rem",
"fluid": { "min": "1.25rem", "max": "2rem" }
},
{
"slug": "xx-large",
"name": "2X Large",
"size": "2.5rem",
"fluid": { "min": "1.75rem", "max": "3rem" }
}
]
},
"spacing": {
"fluid": true,
"spacingScale": {
"steps": 7,
"mediumStep": 1.5,
"unit": "rem",
"operator": "*",
"increment": 1.5,
"type": "linear"
},
"spacingSizes": [
{ "slug": "20", "name": "XS", "size": "clamp(0.5rem, 1vw, 0.75rem)" },
{ "slug": "30", "name": "S", "size": "clamp(0.75rem, 2vw, 1rem)" },
{ "slug": "40", "name": "M", "size": "clamp(1rem, 3vw, 1.5rem)" },
{ "slug": "50", "name": "L", "size": "clamp(1.5rem, 4vw, 2rem)" },
{ "slug": "60", "name": "XL", "size": "clamp(2rem, 5vw, 3rem)" }
]
},
"layout": {
"contentSize": "720px",
"wideSize": "1200px"
}
},
"styles": {
"typography": {
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.7"
},
"blocks": {
"core/heading": {
"typography": { "textWrap": "balance" }
},
"core/cover": {
"spacing": { "padding": { "top": "var(--wp--preset--spacing--60)", "bottom": "var(--wp--preset--spacing--60)" } }
}
}
}
}
NOTE: WordPress generates clamp() values using the formula clamp(min, min + (max - min) * ((100vw - 320px) / (1600px - 320px)), max) — the viewport breakpoints (320px–1600px) are the defaults; override them globally with settings.typography.fluid.minFontSize and in layout.contentSize if your design uses a different range.