Skip to main content

Overview

Tailwind CSS v4 uses CSS variables (custom properties) for theming, enabling dynamic theme switching, dark mode, and customization without rebuilding your CSS.

Theme Architecture

Tailwind v4’s theme system is built on CSS variables defined in the :root selector.

Basic Theme Structure

This generates:
Tailwind applies theme variables to both :root and :host to support Web Components.

Reference Mode

Use @theme reference for values that shouldn’t be output as CSS variables:
These values are used in calculations and media queries but aren’t emitted as CSS variables:
Use reference mode for:
  • Breakpoints (used in media queries)
  • Intermediate calculation values
  • Legacy compatibility values
  • Values only used in build-time calculations

Theme Namespaces

Theme values are organized by namespace prefixes:

Color Namespace

Utilities look up colors with the --color- prefix:

Spacing Namespace

The base --spacing value is used for bare number utilities:

Typography Namespace

Other Namespaces

Dynamic Theme Switching

Because Tailwind v4 uses CSS variables, you can switch themes dynamically with JavaScript or additional CSS.

Multiple Color Schemes

Component-Level Themes

Dark Mode

Tailwind v4’s dark mode is implemented using CSS variables and the dark: variant.

Default Dark Mode

The default implementation uses prefers-color-scheme:
Usage:

Custom Dark Mode Implementation

Override the dark variant for class-based dark mode:
Or using a class:

Per-Component Dark Mode

Semantic Color Systems

Create semantic color systems that can be themed:

Scoped Themes

Create themes scoped to specific sections:

Theme Resolution

Understanding how Tailwind resolves theme values:

Resolution Order

From theme.ts, theme resolution follows this order:
  1. Check the exact key in the specified namespace
  2. Check bare key (without namespace prefix)
  3. Return null if not found

Inline vs. Variable Resolution

Theme Functions

Access theme values using the theme() function:
The theme() function only works with CSS variable names (prefixed with --). It cannot access nested dot-notation paths from v3.

Performance Considerations

CSS Variable Performance

CSS variables have excellent performance characteristics:
  • Variables are resolved at runtime (no recompilation needed)
  • Inheritance is efficient (browsers optimize this)
  • Theme switching is instant (just update the variable value)
  • No JavaScript required for theme switching

When to Use Reference Mode

Use @theme reference to:
  1. Reduce CSS output size
  2. Avoid polluting the global CSS variable scope
  3. Prevent values from being overridden
  4. Keep intermediate calculation values private

Migration from v3

Config to @theme

Tailwind v3 config:
Tailwind v4 theme:

Accessing Theme in CSS

v3 approach:
v4 approach:

Best Practices

Recommendations:
  1. Semantic Naming: Use semantic names (—color-primary) over specific names (—color-blue-500)
  2. Consistent Prefixes: Follow Tailwind’s namespace conventions (—color-, —spacing-, etc.)
  3. Reference Mode: Use for values that don’t need to be CSS variables
  4. Theme Composition: Build complex themes by referencing simpler ones
  5. Documentation: Document your theme structure for team members
  6. Testing: Test theme switching across all components

Examples

Complete Multi-Theme System

Source Code Reference

The theming system is implemented in:
  • /packages/tailwindcss/src/theme.ts - Theme class and resolution
  • /packages/tailwindcss/src/css-functions.ts:68-127 - theme() function
  • /packages/tailwindcss/src/variants.ts:1143 - dark variant