---
tags:
  - wordpress
  - fse
  - theme.json
  - css
  - variables
title: Defining Global Custom CSS Variables in theme.json
---

# Defining Global Custom CSS Variables in theme.json

Standard presets in `theme.json` are strictly categorized (Color, Typography, Spacing). But often developers need global variables for things that don't fit those boxes, such as:
*   Border Radius values
*   Transition speeds
*   Shadow depths
*   Container widths

The solution is the **`settings.custom`** object.

## 1. The `settings.custom` Object

You can add any arbitrary JSON structure under `settings.custom`. WordPress will recursively crawl this object and generate CSS variables for every leaf node.

**Syntax Formula:**
`--wp--custom--{parent}--{child}`

### Example Configuration

```json
{
    "version": 3,
    "settings": {
        "custom": {
            "animation": {
                "fast": "0.2s ease",
                "slow": "0.5s ease-in-out"
            },
            "shadow": {
                "card": "0px 4px 10px rgba(0,0,0,0.1)",
                "popover": "0px 10px 40px rgba(0,0,0,0.2)"
            },
            "radius": {
                "small": "4px",
                "large": "12px"
            }
        }
    }
}
```

## 2. The Generated CSS

WordPress outputs this in the `<body>` selector:

```css
body {
    --wp--custom--animation--fast: 0.2s ease;
    --wp--custom--animation--slow: 0.5s ease-in-out;
    --wp--custom--shadow--card: 0px 4px 10px rgba(0,0,0,0.1);
    --wp--custom--radius--small: 4px;
    /* ...etc */
}
```

## 3. How to Use Them

You can reference these variables anywhere in your `theme.json` styles or your external CSS files.

### In `theme.json` (Styles)

```json
"styles": {
    "blocks": {
        "core/button": {
            "border": {
                "radius": "var(--wp--custom--radius--small)"
            }
        },
        "core/group": {
            "shadow": "var(--wp--custom--shadow--card)"
        }
    }
}
```

### In `style.css`

```css
.my-custom-component {
    transition: all var(--wp--custom--animation--fast);
    box-shadow: var(--wp--custom--shadow--popover);
}
```

## 4. Why Use This Instead of `style.css` :root?

1.  **Centralization:** All your design tokens (colors, fonts, *and* custom values) live in one file (`theme.json`).
2.  **Editor Support:** Gutenberg is aware of these values. While there isn't a UI picker for them yet, they are loaded in the iframe editor, ensuring your blocks look correct on the backend.