WordPress Block Theme Development: Fluid Typography and Spacing with theme.json

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.