Skip to main content

CSS Functions

Tailwind CSS provides several CSS functions for accessing theme values and manipulating colors.

theme() Function

The theme() function resolves values from your theme configuration.

Basic Usage

.custom-component {
  padding: theme(--spacing);
  color: theme(--color-blue-500);
  font-size: theme(--text-lg);
}
In Tailwind CSS v4, theme values are accessed using CSS variable names that start with --.

With Fallback Values

.custom-component {
  /* Use theme value, fallback to 1rem */
  padding: theme(--spacing, 1rem);
  
  /* Multiple fallback values */
  color: theme(--color-primary, theme(--color-blue-500, blue));
}

Inline Resolution

Some contexts require inline resolution rather than CSS variable references:
/* Force inline resolution with 'inline' keyword */
.custom-component {
  padding: theme(--spacing inline);
}

/* Automatically inlined in at-rules */
@media (width >= theme(--breakpoint-md)) {
  /* theme() is automatically resolved inline here */
  .custom-component {
    padding: 2rem;
  }
}
CSS variables cannot be used in certain contexts like media queries. Tailwind automatically inlines theme values in these cases.

Implementation Details

From css-functions.ts:68-127:
function theme(
  designSystem: DesignSystem,
  source: AstNode,
  path: string,
  ...fallback: string[]
): string {
  if (!path.startsWith('--')) {
    throw new Error(
      `The --theme(…) function can only be used with CSS variables from your theme.`
    )
  }

  let inline = false

  // Handle `--theme(… inline)` to force inline resolution
  if (path.endsWith(' inline')) {
    inline = true
    path = path.slice(0, -7)
  }

  // If used within at-rule, always inline
  if (source.kind === 'at-rule') {
    inline = true
  }

  let resolvedValue = designSystem.resolveThemeValue(path, inline)

  if (!resolvedValue) {
    if (fallback.length > 0) return fallback.join(', ')
    throw new Error(
      `Could not resolve value for theme function: \`theme(${path})\`.`
    )
  }

  return resolvedValue
}

—alpha() Function

Apply opacity to colors using the --alpha() function.
.custom-component {
  /* Apply 50% opacity to a color */
  background: --alpha(var(--color-blue-500) / 50%);
  
  /* Using a numeric value (converted to percentage) */
  color: --alpha(var(--color-red-500) / 0.5);
}
Implementation from css-functions.ts:19-40:
function alpha(
  _designSystem: DesignSystem,
  _source: AstNode,
  value: string,
  ...rest: string[]
): string {
  let [color, alpha] = segment(value, '/').map((v) => v.trim())

  if (!color || !alpha) {
    throw new Error(
      `The --alpha(…) function requires a color and an alpha value, e.g.: \`--alpha(var(--my-color) / 50%)\``
    )
  }

  return withAlpha(color, alpha)
}
The result uses color-mix():
/* Input */
background: --alpha(blue / 50%);

/* Output */
background: color-mix(in oklab, blue 50%, transparent);

—spacing() Function

Multiply the theme’s base spacing value:
@theme {
  --spacing: 0.25rem;
}

.custom-component {
  /* 4 * 0.25rem = 1rem */
  margin: --spacing(4);
  
  /* 8 * 0.25rem = 2rem */
  padding: --spacing(8);
}
Implementation from css-functions.ts:42-66:
function spacing(
  designSystem: DesignSystem,
  _source: AstNode,
  value: string,
  ...rest: string[]
): string {
  if (!value) {
    throw new Error(
      `The --spacing(…) function requires an argument.`
    )
  }

  let multiplier = designSystem.theme.resolve(null, ['--spacing'])
  if (!multiplier) {
    throw new Error(
      'The --spacing(…) function requires that the `--spacing` theme variable exists.'
    )
  }

  return `calc(${multiplier} * ${value})`
}

Directives

@apply Directive

The @apply directive extracts utility classes into custom CSS.

Basic Usage

.btn-primary {
  @apply bg-blue-500 text-white px-4 py-2 rounded;
}

.card {
  @apply p-6 bg-white shadow-lg rounded-lg;
}
Use @apply to extract repeated utility patterns into semantic component classes.

With Variants

.interactive-card {
  @apply bg-white hover:bg-gray-50;
  @apply transition-colors duration-200;
  @apply dark:bg-gray-800 dark:hover:bg-gray-700;
}

In Custom Utilities

@utility my-button {
  @apply px-4 py-2 rounded;
  @apply font-semibold;
  transition: all 0.2s;
}

Circular Dependency Detection

Tailwind prevents circular dependencies:
@utility foo {
  @apply bar;
}

@utility bar {
  @apply foo; /* ❌ Error: Circular dependency */
}

Implementation Highlights

From apply.ts:10-325:
  • Topological sorting ensures utilities are applied in dependency order
  • Circular dependencies are detected and reported with helpful errors
  • @apply inside @utility is fully supported
  • Nested @apply is handled correctly
@apply Restrictions:
  • Cannot be used inside @keyframes
  • Must be used within a rule context (has a parent selector)
  • Cannot apply unprefixed utilities when a prefix is configured
  • Cannot apply blocklisted classes

@theme Directive

Define theme values using the @theme directive.

Basic Theme Definition

@theme {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
  --spacing: 0.25rem;
  --font-sans: 'Inter', system-ui, sans-serif;
}

Reference Mode

Use @theme reference to define theme values that can be referenced but won’t be output as CSS variables:
@theme reference {
  --breakpoint-sm: 640px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 1024px;
  --breakpoint-xl: 1280px;
}
Reference mode is useful for values that are only used in specific contexts (like breakpoints in media queries) and don’t need to be available as CSS custom properties.

Namespace Organization

@theme {
  /* Color palette */
  --color-blue-50: #eff6ff;
  --color-blue-100: #dbeafe;
  --color-blue-500: #3b82f6;
  --color-blue-900: #1e3a8a;
  
  /* Spacing scale */
  --spacing: 0.25rem;
  --spacing-xs: 0.5rem;
  --spacing-sm: 0.75rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  
  /* Typography */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
}

Theme Keys for Utilities

Utilities look up values in specific theme namespaces:
// From utilities.ts
functionalUtility('text', {
  themeKeys: ['--font-size'],
  // text-lg looks up --font-size-lg
})

functionalUtility('bg', {
  themeKeys: ['--color'],
  // bg-blue-500 looks up --color-blue-500
})

@source Directive

The @source directive controls which files are scanned for utility classes.

Basic Usage

/* Scan specific directories */
@source "./src/**/*.{html,jsx,tsx}";

/* Multiple source patterns */
@source "./src/components/**/*.tsx";
@source "./src/pages/**/*.tsx";

Excluding Content

Use not to exclude patterns:
/* Scan everything except test files */
@source "./src/**/*.tsx";
@source not "./src/**/*.test.tsx";

/* Exclude inline content */
@source not inline("some-class");

Inline Content

/* Include specific classes */
@source inline("bg-blue-500 text-white");
The @source directive is useful when you need fine-grained control over content scanning, especially in monorepo setups or when integrating with specific frameworks.

Combining Functions and Directives

Custom Component Pattern

@theme {
  --button-primary: #3b82f6;
  --button-padding: 1rem;
  --button-radius: 0.375rem;
}

.custom-button {
  /* Use theme values */
  background-color: theme(--button-primary);
  padding: theme(--button-padding);
  border-radius: theme(--button-radius);
  
  /* Apply utilities */
  @apply font-semibold text-white;
  @apply transition-colors duration-200;
  
  /* Custom hover with alpha */
  &:hover {
    background-color: --alpha(theme(--button-primary) / 90%);
  }
}

Responsive Utilities

@theme reference {
  --breakpoint-md: 768px;
}

.responsive-grid {
  display: grid;
  gap: --spacing(4);
  grid-template-columns: 1fr;
  
  @media (width >= theme(--breakpoint-md)) {
    grid-template-columns: repeat(3, 1fr);
    gap: --spacing(6);
  }
}

Best Practices

Recommendations:
  1. Theme Organization: Group related theme values by namespace (colors, spacing, typography)
  2. Reference Mode: Use @theme reference for values only needed in calculations
  3. Fallback Values: Always provide fallbacks for critical theme values
  4. @apply Sparingly: Use @apply for extracting repeated patterns, not for everything
  5. Inline Resolution: Be aware of when theme values are inlined vs. remaining as CSS variables

Source Code Reference

The functions and directives are implemented in:
  • /packages/tailwindcss/src/css-functions.ts - CSS function implementations
  • /packages/tailwindcss/src/apply.ts - @apply directive
  • /packages/tailwindcss/src/theme.ts - Theme resolution
  • /packages/tailwindcss/src/utilities.ts:174-191 - withAlpha helper

Build docs developers (and LLMs) love