Theming
Customize HeroUI's design system with CSS variables and global styles
HeroUI uses CSS variables and BEM classes for theming. Customize everything from colors to component styles using standard CSS.
How It Works
HeroUI's theming system is built on top of Tailwind CSS v4's theme. When you import @heroui/styles, it uses Tailwind's built-in color palettes, maps them to semantic variables, automatically switches between light and dark themes, and uses CSS layers and the @theme directive for organization.
Naming pattern:
- Colors without a suffix are backgrounds (e.g.,
--accent) - Colors with
-foregroundare for text on that background (e.g.,--accent-foreground)
Quick Start
Apply a theme: Add a theme class to your HTML and apply colors to the body:
<html class="light" data-theme="light">
<body class="bg-background text-foreground">
<!-- Your app -->
</body>
</html>Switch themes:
<!-- Light theme -->
<html class="light" data-theme="light">
<!-- Dark theme -->
<html class="dark" data-theme="dark">Override colors:
/* app/globals.css */
@import "tailwindcss";
@import "@heroui/styles";
:root {
/* Override any color variable */
--accent: oklch(0.7 0.25 260);
--success: oklch(0.65 0.15 155);
}Note: See Colors for the complete color palette and visual reference.
Create your own theme:
/* src/themes/ocean.css */
@layer base {
/* Ocean Light */
[data-theme="ocean"] {
color-scheme: light;Use your theme:
/* app/globals.css */
@layer theme, base, components, utilities;
@import "tailwindcss";
@import "@heroui/styles";
@import "./src/themes/ocean.css" layer(theme); Apply your theme:
<!-- index.html -->
<!-- Light ocean -->
<html data-theme="ocean">
<!-- Dark ocean -->
<html data-theme="ocean-dark">Customize Components
Global component styles: Override any component using BEM classes:
@layer components {
/* Customize buttons */
.button {
@apply font-semibold tracking-wide;
}
.button--primary {
@apply bg-blue-600 hover:bg-blue-700;
}
/* Customize accordions */
.accordion__trigger {
@apply text-lg font-bold;
}
}Note: See Styling for the complete styling reference.
Find component classes: Each component docs page lists all available classes (base classes, modifiers, elements, states). Example: Button classes
Import Strategies
Full import (recommended): Get everything with two lines:
@import "tailwindcss";
@import "@heroui/styles";Selective import: Import only what you need:
/* Define layers */
@layer theme, base, components, utilities;
/* Base requirements */
@import "tailwindcss";
@import "@heroui/styles/base" layer(base);
/* OR specific base file */
@import "@heroui/styles/base/base.css" layer(base);
/* Theme variables */
@import "@heroui/styles/themes/shared/theme.css" layer(theme);
@import "@heroui/styles/themes/default" layer(theme);
/* OR specific theme files */
@import "@heroui/styles/themes/default/index.css" layer(theme);
@import "@heroui/styles/themes/default/variables.css" layer(theme);
/* Components (all components) */
@import "@heroui/styles/components" layer(components);
/* OR specific component files */
@import "@heroui/styles/components/index.css" layer(components);
@import "@heroui/styles/components/button.css" layer(components);
@import "@heroui/styles/components/accordion.css" layer(components);
/* Utilities (optional) */
@import "@heroui/styles/utilities" layer(utilities);
/* Variants (optional) */
@import "@heroui/styles/variants" layer(utilities);Note: Directory imports (e.g.,
@heroui/styles/components) automatically resolve to theirindex.cssfile. Use explicit file paths (e.g.,@heroui/styles/components/button.css) to import individual component styles.
Headless mode: Build your own styles from scratch:
@import "tailwindcss";
@import "@heroui/styles/base/base.css";
/* Your custom styles */
.button {
/* Your button styles */
}Adding Custom Colors
Add your own semantic colors to the theme:
/* Define in both light and dark themes */
:root,
[data-theme="light"] {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
.dark,
[data-theme="dark"] {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
/* Make the color available to Tailwind */
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}Now use it in your components:
<div className="bg-info text-info-foreground">Info message</div>Variables Reference
HeroUI defines three types of variables:
- Base Variables — Non-changing values like
--white,--black, spacing, and typography - Theme Variables — Colors that change between light/dark themes
- Calculated Variables — Automatically generated hover states and size variants
For a complete reference, see: Colors Documentation, Default Theme Variables, Shared Theme Utilities
Calculated variables (Tailwind):
We use Tailwind's @theme directive to automatically create calculated variables for hover states and radius variants. These are defined in themes/shared/theme.css:
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);Form controls now rely on the --field-* variables and their calculated hover/focus variants. Update them in your theme to restyle inputs, checkboxes, radios, and OTP slots without impacting surfaces like buttons or cards.