Skip to content
djust/docs
Appearance
Mode
djust.org →
Browse documentation

2 min read

extra_css_vars

The standard token set covers colors, typography, animation, and a few geometric primitives. Anything else — project-specific gutter widths, custom accent colors, animation timing constants, layout knobs — lives in the extra_css_vars slots on ThemePreset.

Three slots, one purpose

ThemePreset(
    name='docs',
    light=LIGHT_TOKENS,
    dark=DARK_TOKENS,

    # Emitted in :root regardless of mode.
    extra_css_vars={
        '--docs-gutter': '32px',
        '--docs-section-num-color': 'var(--primary)',
        '--docs-pull-quote-bg': 'rgba(255 255 255 / 0.03)',
    },

    # Mode-specific overrides. If omitted, extra_css_vars is used for
    # both modes. Useful for surface colors that differ between light
    # and dark.
    extra_css_vars_light={
        '--docs-paper': '#fafaf7',
        '--docs-shadow': 'rgba(0 0 0 / 0.1)',
    },
    extra_css_vars_dark={
        '--docs-paper': '#11100d',
        '--docs-shadow': 'rgba(0 0 0 / 0.5)',
    },
)

When to use which slot

SlotWhen to use
extra_css_varsVariables whose value is the same in light and dark mode (gutter widths, animation durations, layout knobs that aren't color-coupled).
extra_css_vars_lightLight-mode-specific values (paper color, soft shadow, light noise texture).
extra_css_vars_darkDark-mode-specific values (deep ink, harder shadow, dark noise texture).

You can use all three together: a base extra_css_vars for shared constants, then mode-specific overrides for the values that do differ between modes.

Consuming in CSS

Reference your custom variables anywhere in your stylesheet:

.docs-section {
    padding: 48px var(--docs-gutter);
    border-bottom: 1px solid var(--color-brand-border);
}

.docs-section__num {
    color: var(--docs-section-num-color);
}

.docs-paper {
    background: var(--docs-paper);
    box-shadow: 0 4px 12px var(--docs-shadow);
}

Mode swaps repaint these the same way they repaint the standard tokens — no JavaScript needed.

Naming conventions

Two conventions cover most cases:

  • Prefix with your project name for site-wide knobs: --docs-gutter, --docs-paper, --marketing-hero-height.
  • Prefix with your component name for component-scoped knobs: --card-padding, --combobox-max-height, --toast-duration.

The standard --background / --primary / --border namespace is reserved for djust's shadcn-style tokens — don't redeclare those in extra_css_vars. If you need to override --primary for a specific page or section, use the Recipes patterns.

Don't put structural CSS here

extra_css_vars is for named knobs, not for CSS rules or selectors. Putting structural rules in a theme pack means every other pack on your site needs to redefine them — see Structure vs. style for the failure mode and the right alternative.

A real example

The docs.djust.org house theme uses extra_css_vars for one knob:

# djust/python/djust/theming/themes/docs.py
PRESET = ThemePreset(
    name='docs',
    display_name='docs.djust.org',
    light=LIGHT,
    dark=DARK,
    default_mode='dark',
    extra_css_vars={
        '--docs-gutter': '32px',
    },
)

That single knob is consumed by every editorial section in static/css/input.css (.docs-hero, .docs-features, .docs-section, etc.). If the editorial layout ever needed wider or narrower gutters per pack, we'd just override the value in a different pack's extra_css_vars — no CSS changes.

See also

  • Authoring a pack — where extra_css_vars lives in the full pack definition.
  • Structure vs. style — what does NOT belong in extra_css_vars (or anywhere in a pack).
  • Tokens — the standard token set you're extending, not replacing.

Spotted a typo or want to improve this page? Edit on GitHub →