Daily
Weekly
Bi-Weekly
Monthly
Daily
Manage your daily tasks and goals.
Weekly
Manage your weekly tasks and goals.
Bi-Weekly
Manage your bi-weekly tasks and goals.
Monthly
Manage your monthly tasks and goals.
);
}
`}
/>
### CSS Classes
The Tabs component uses these CSS classes:
#### Base Classes
* `.tabs` - Base tabs container
* `.tabs__list-wrapper` - Tab list wrapper
* `.tabs__list` - Tab list container
* `.tabs__tab` - Individual tab button
* `.tabs__panel` - Tab panel content
* `.tabs__indicator` - Tab indicator
#### Orientation Attributes
* `.tabs[data-orientation="horizontal"]` - Horizontal tab layout (default)
* `.tabs[data-orientation="vertical"]` - Vertical tab layout
### Interactive States
The component supports both CSS pseudo-classes and data attributes:
* **Selected**: `[aria-selected="true"]`
* **Hover**: `:hover` or `[data-hover="true"]`
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]`
* **Disabled**: `[aria-disabled="true"]`
## API Reference
### Tabs Props
| Prop | Type | Default | Description |
| -------------------- | ---------------------------- | -------------- | --------------------------- |
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Tab layout orientation |
| `selectedKey` | `string` | - | Controlled selected tab key |
| `defaultSelectedKey` | `string` | - | Default selected tab key |
| `onSelectionChange` | `(key: Key) => void` | - | Selection change handler |
| `className` | `string` | - | Additional CSS classes |
### Tabs.List Props
| Prop | Type | Default | Description |
| ------------ | -------- | ------- | -------------------------------- |
| `aria-label` | `string` | - | Accessibility label for tab list |
| `className` | `string` | - | Additional CSS classes |
### Tabs.Tab Props
| Prop | Type | Default | Description |
| ------------ | --------- | ------- | ----------------------- |
| `id` | `string` | - | Unique tab identifier |
| `isDisabled` | `boolean` | `false` | Whether tab is disabled |
| `className` | `string` | - | Additional CSS classes |
### Tabs.Panel Props
| Prop | Type | Default | Description |
| ----------- | -------- | ------- | -------------------------------- |
| `id` | `string` | - | Panel identifier matching tab id |
| `className` | `string` | - | Additional CSS classes |
# HeroUI v3 > components > TextField
URL: /docs/components/text-field
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/components/text-field.mdx
Text input fields for forms with labels, descriptions, and error messages
***
title: TextField
description: Text input fields for forms with labels, descriptions, and error messages
links:
rac: TextField
source: text-field/text-field.tsx
styles: text-field.css
storybook: text-field
figma: true
-----------
## Import
```tsx
import { TextField } from '@heroui/react';
```
### Usage
### Anatomy
Import all parts and piece them together.
```tsx
import { TextField } from '@heroui/react';
export default () => (
Field label
Helper text for the field
Error message when invalid
)
```
### With Description
### Required Field
### With Error
### Disabled State
### TextArea
### Input Types
## Styling
### Passing Tailwind CSS classes
```tsx
import { TextField } from '@heroui/react';
function CustomTextField() {
return (
Custom styled field
With custom styles
);
}
```
### CSS Classes
The TextField component uses these CSS classes:
#### Base Classes
* `.text-field` - Base container styles
* `.text-field__label` - Label element styles
* `.text-field__input` - Input element styles
* `.text-field__textarea` - TextArea element styles
* `.text-field__description` - Description text styles
* `.text-field__error` - Error message styles
#### State Classes
* `.text-field--disabled` - Disabled state styles
* `.text-field--invalid` - Invalid/error state styles
* `.text-field--required` - Required field styles
### Interactive States
The component supports both CSS pseudo-classes and data attributes:
* **Focus**: `:focus` or `[data-focus="true"]`
* **Focus Within**: `:focus-within` or `[data-focus-within="true"]`
* **Invalid**: `:invalid` or `[aria-invalid="true"]`
* **Disabled**: `:disabled` or `[aria-disabled="true"]`
* **Required**: `:required` or `[aria-required="true"]`
## Accessibility
#### Keyboard Navigation
* **Tab** - Move focus to the input field
* **Shift + Tab** - Move focus to the previous element
* **Arrow keys** - Navigate within textarea content
#### Screen Reader Support
* Labels are properly associated with input fields
* Required fields are announced
* Error messages are announced when present
* Descriptions provide additional context
* Invalid state is communicated via ARIA attributes
#### Focus Management
* Clear focus indicators on interactive elements
* Focus moves naturally through form fields
* Error messages receive focus when validation fails
## API Reference
### TextField Props
| Prop | Type | Default | Description |
| ------------ | --------- | ------- | ----------------------------- |
| `isRequired` | `boolean` | `false` | Whether the field is required |
| `isInvalid` | `boolean` | `false` | Whether the field is invalid |
| `isDisabled` | `boolean` | `false` | Whether the field is disabled |
| `className` | `string` | - | Additional CSS classes |
### TextField.Label Props
| Prop | Type | Default | Description |
| ----------- | -------- | ------- | ---------------------- |
| `className` | `string` | - | Additional CSS classes |
### TextField.Input Props
| Prop | Type | Default | Description |
| ------------- | ------------------------- | -------- | ---------------------------------------- |
| `type` | `string` | `"text"` | Input type (text, email, password, etc.) |
| `placeholder` | `string` | - | Placeholder text |
| `value` | `string` | - | Input value |
| `onChange` | `(value: string) => void` | - | Change handler |
| `className` | `string` | - | Additional CSS classes |
### TextField.TextArea Props
| Prop | Type | Default | Description |
| ------------- | ------------------------- | ------- | ---------------------------- |
| `rows` | `number` | `3` | Number of visible text lines |
| `placeholder` | `string` | - | Placeholder text |
| `value` | `string` | - | TextArea value |
| `onChange` | `(value: string) => void` | - | Change handler |
| `className` | `string` | - | Additional CSS classes |
### TextField.Description Props
| Prop | Type | Default | Description |
| ----------- | -------- | ------- | ---------------------- |
| `className` | `string` | - | Additional CSS classes |
### TextField.Error Props
| Prop | Type | Default | Description |
| ----------- | -------- | ------- | ---------------------- |
| `className` | `string` | - | Additional CSS classes |
# HeroUI v3 > components > Tooltip
URL: /docs/components/tooltip
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/components/tooltip.mdx
Displays informative text when users hover over or focus on an element
***
title: Tooltip
description: Displays informative text when users hover over or focus on an element
links:
rac: Tooltip
source: tooltip/tooltip.tsx
styles: tooltip.css
storybook: tooltip
figma: true
-----------
## Import
```tsx
import { Tooltip } from '@heroui/react';
```
### Usage
### Anatomy
Import all parts and piece them together.
```tsx
import { Tooltip } from '@heroui/react';
export default () => (
Helpful information about this element
)
```
### With Arrow
### Placement
### Custom Triggers
## Styling
### Passing Tailwind CSS classes
```tsx
import {Tooltip, Button} from '@heroui/react';
function CustomTooltip() {
return (
Custom styled tooltip
);
}
```
### Customizing the component classes
To customize the Tooltip component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.tooltip {
@apply rounded-xl shadow-lg;
}
.tooltip__trigger {
@apply cursor-help;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The Tooltip component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/tooltip.css)):
#### Base Classes
* `.tooltip` - Base tooltip styles with animations
* `.tooltip__trigger` - Trigger element styles
### Interactive States
The component supports animation states:
* **Entering**: `[data-entering]` - Applied during tooltip appearance
* **Exiting**: `[data-exiting]` - Applied during tooltip disappearance
* **Placement**: `[data-placement="*"]` - Applied based on tooltip position
## API Reference
### Tooltip Props
| Prop | Type | Default | Description |
| ------------ | -------------------- | --------- | -------------------------------------------- |
| `children` | `React.ReactNode` | - | Trigger element and content |
| `delay` | `number` | `700` | Delay in milliseconds before showing tooltip |
| `closeDelay` | `number` | `0` | Delay in milliseconds before hiding tooltip |
| `trigger` | `"hover" \| "focus"` | `"hover"` | How the tooltip is triggered |
| `isDisabled` | `boolean` | `false` | Whether the tooltip is disabled |
### Tooltip.Content Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------- | ------------------ | ----------------------------------- |
| `children` | `React.ReactNode` | - | Content to display in the tooltip |
| `showArrow` | `boolean` | `false` | Whether to show the arrow indicator |
| `offset` | `number` | `3` (7 with arrow) | Distance from the trigger element |
| `placement` | `"top" \| "bottom" \| "left" \| "right"` (and variants) | `"top"` | Placement of the tooltip |
| `className` | `string` | - | Additional CSS classes |
### Tooltip.Trigger Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | --------------------------------- |
| `children` | `React.ReactNode` | - | Element that triggers the tooltip |
| `className` | `string` | - | Additional CSS classes |
### Tooltip.Arrow Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | ---------------------- |
| `children` | `React.ReactNode` | - | Custom arrow element |
| `className` | `string` | - | Additional CSS classes |
# HeroUI v3 > handbook > Animation
URL: /docs/handbook/animation
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/handbook/animation.mdx
Add smooth animations and transitions to HeroUI v3 components
***
title: Animation
description: Add smooth animations and transitions to HeroUI v3 components
icon: copy-transparent
----------------------
## Overview
HeroUI components are built on React Aria and support multiple animation approaches:
* **Built-in animations** - Components come with default CSS transitions
* **CSS animations** - Customize with Tailwind utilities or custom CSS
* **JavaScript libraries** - Integrate with Framer Motion, React Spring, etc.
## Built-in Animations
HeroUI components use data attributes to expose their state for animation:
```css
/* Popover entrance/exit */
.popover[data-entering] {
@apply animate-in zoom-in-90 fade-in-0 duration-200;
}
.popover[data-exiting] {
@apply animate-out zoom-out-95 fade-out duration-150;
}
/* Button press effect */
.button:active,
.button[data-pressed="true"] {
transform: scale(0.97);
}
/* Accordion expansion */
.accordion__panel[aria-hidden="false"] {
@apply h-[var(--panel-height)] opacity-100;
}
```
### State Attributes
Components expose these states for styling:
* `[data-hover="true"]` - Hover state
* `[data-pressed="true"]` - Active/pressed state
* `[data-focus-visible="true"]` - Keyboard focus
* `[data-disabled="true"]` - Disabled state
* `[data-entering]` / `[data-exiting]` - Transition states
* `[aria-expanded="true"]` - Expanded state
## CSS Animations
### Using Tailwind Utilities
```tsx
// Pulse on hover
// Fade in entrance
Welcome message
// Staggered list
Item 1
Item 2
```
### Custom Transitions
Override default component animations:
```css
/* Slower accordion */
.accordion__panel {
@apply transition-all duration-500;
}
/* Bouncy button */
.button:active {
animation: bounce 0.3s;
}
@keyframes bounce {
50% { transform: scale(0.95); }
}
```
## Framer Motion
HeroUI components work seamlessly with Framer Motion for advanced animations.
### Basic Usage
```tsx
import { motion } from 'framer-motion';
import { Button } from '@heroui/react';
const MotionButton = motion(Button);
Animated Button
```
### Entrance Animations
```tsx
Welcome!
```
### Layout Animations
```tsx
import { AnimatePresence, motion } from 'framer-motion';
function Tabs({ items, selected }) {
return (
{items.map((item, i) => (
))}
);
}
```
## Render Props
Use render props to apply dynamic animations based on component state:
```tsx
```
## Accessibility
### Respecting Motion Preferences
Always respect user motion preferences:
```css
@media (prefers-reduced-motion: reduce) {
.button {
transition: none;
}
.animate-* {
animation: none !important;
}
}
```
With Framer Motion:
```tsx
import { useReducedMotion } from 'framer-motion';
function AnimatedCard() {
const shouldReduceMotion = useReducedMotion();
return (
Content
);
}
```
## Performance Tips
### Use GPU-Accelerated Properties
Prefer `transform` and `opacity` for smooth animations:
```css
/* Good - GPU accelerated */
.slide-in {
transform: translateX(-100%);
transition: transform 0.3s;
}
/* Avoid - Triggers layout */
.slide-in {
left: -100%;
transition: left 0.3s;
}
```
### Will-Change Optimization
```css
.button {
will-change: transform;
}
.button:not(:hover) {
will-change: auto;
}
```
## Next Steps
* Learn about [Styling](/docs/handbook/styling) approaches
* Explore [Component](/docs/components) examples
* View [Theming](/docs/handbook/theming) documentation
# HeroUI v3 > handbook > Colors
URL: /docs/handbook/colors
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/handbook/colors.mdx
Color palette and theming system for HeroUI v3
***
title: Colors
description: Color palette and theming system for HeroUI v3
icon: bucket-paint
links:
themes: true
tailwind: theme
---------------
import {ColorSwatch, ColorPalette} from "@/components/color-swatch";
HeroUI uses CSS variables for colors that automatically switch between light and dark themes. All colors use the `oklch` color space for better color transitions.
## How It Works
HeroUI's color system is built on top of Tailwind CSS v4's theme. When you import `@heroui/styles`, it uses Tailwind's built-in color palettes (like `--color-neutral-*`) and maps them to semantic variables.
Add a theme class to your HTML and apply colors to the body:
```html
```
We follow a simple naming pattern:
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
```tsx
// This gives you the right background and text colors
Hello
```
## Available Colors
### Base Colors
These four colors stay the same in all themes:
### Background & Surface
### Primary Colors
* **Accent**: Your main brand color (used for primary actions)
* **Accent Soft**: A lighter version for secondary actions
### Status Colors
For alerts, validation, and status messages:
### Other Colors
## How to Use Colors
### In Your Components
```jsx
// Use Tailwind classes
```
### In CSS Files
```css title="global.css"
/* Direct CSS variables */
.my-component {
background: var(--accent);
color: var(--accent-foreground);
border: 1px solid var(--border);
}
/* With @apply and @layer */
@layer components {
.button {
@apply bg-accent text-accent-foreground;
&:hover,
&[data-hover="true"] {
@apply bg-accent-hover;
}
&:active,
&[data-pressed="true"] {
@apply bg-accent-hover;
transform: scale(0.97);
}
}
}
```
## Default Theme
The complete theme definition can be found in ([default.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/index.css)). This theme automatically switches between light and dark modes based on the `class="dark"` or `data-theme="dark"` attributes.
> **Note**: Colors like `--color-neutral-*`, `--color-white`, and `--color-black` come from [Tailwind CSS v4's built-in theme](https://tailwindcss.com/docs/colors).
## Customizing Colors
### Add Your Own Colors
```css
: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 you can use it:
```tsx
Info message
```
> **Note**: To learn more about theme variables and how they work in Tailwind CSS v4, see the [Tailwind CSS Theme documentation](https://tailwindcss.com/docs/theme).
### Override Existing Colors
```css
:root {
/* Override default colors */
--accent: oklch(0.7 0.15 250);
--success: oklch(0.65 0.15 155);
}
[data-theme="dark"] {
/* Override dark theme colors */
--accent: oklch(0.8 0.12 250);
--success: oklch(0.75 0.12 155);
}
```
**Tip**: Convert colors at [oklch.com](https://oklch.com)
## Quick Tips
* Always use color variables, not hard-coded values
* Use foreground/background pairs for good contrast
* Test in both light and dark modes
* The system respects user's theme preference automatically
## Related
* [Theming](/docs/handbook/theming) - Learn about the theming system
* [Styling](/docs/handbook/styling) - Styling components with CSS
* [Design Principles](/docs/design-principles) - Understanding HeroUI's design philosophy
# HeroUI v3 > handbook > Composition
URL: /docs/handbook/composition
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/handbook/composition.mdx
Build flexible UI with component composition patterns
***
title: Composition
description: Build flexible UI with component composition patterns
icon: layers
------------
## Overview
HeroUI uses composition patterns to create flexible, customizable components. This allows you to:
* Change the rendered element or component
* Compose components together
* Maintain full control over markup
## The asChild Prop
The `asChild` prop lets you change what element a component renders. When `asChild` is true, HeroUI won't render its default element - instead, it clones the child element and merges props.
### Basic Usage
```tsx
import { Button } from '@heroui/react';
import Link from 'next/link';
// Renders as a Next.js Link
// Renders as a regular anchor
```
### Available Components
These components support `asChild`:
* `Button` - Change button element
* `Alert` parts - Root, Icon, Content, Title, Description, Action, Close
* `Avatar` - Change root element
* More components coming soon
## Compound Components
HeroUI components are built as compound components - they export multiple parts that work together:
```tsx
import { Alert } from '@heroui/react';
Success
Your changes have been saved.
```
This pattern provides:
* **Flexibility** - Arrange parts as needed
* **Customization** - Style each part independently
* **Control** - Add or remove parts
## Style Variants
HeroUI exports variant functions that can be applied to any component. This allows you to use HeroUI's design system with any element or component:
### Using buttonVariants
Apply button styles to any component:
```tsx
import { Link, buttonVariants } from '@heroui/react';
// Link styled as a tertiary button
HeroUI
// Native anchor styled as primary button
Go to Dashboard
```
### Available Variant Functions
Each component exports its variant function:
* `buttonVariants` - Button styles
* `chipVariants` - Chip styles
* `linkVariants` - Link styles
* `spinnerVariants` - Spinner styles
* More variant functions for each component
## Custom Components
Create your own components by composing HeroUI primitives:
```tsx
import { Button, Tooltip } from '@heroui/react';
// Link button component
function LinkButton({ href, children, ...props }) {
return (
);
}
// Icon button with tooltip
function IconButton({ icon, label, ...props }) {
return (
);
}
```
## Custom Variants
You can create your own custom variants by extending the component's variant function.
```tsx
import type {ButtonProps} from "@heroui/react";
import type {VariantProps} from "tailwind-variants";
import {Button, buttonVariants} from "@heroui/react";
import {tv} from "tailwind-variants";
const myButtonVariants = tv({
extend: buttonVariants,
base: "text-md text-shadow-lg font-semibold shadow-md data-[pending=true]:opacity-40",
variants: {
radius: {
lg: "rounded-lg",
md: "rounded-md",
sm: "rounded-sm",
full: "rounded-full",
},
size: {
sm: "h-10 px-4",
md: "h-11 px-6",
lg: "h-12 px-8",
xl: "h-13 px-10",
},
variant: {
primary: "text-white dark:bg-white/10 dark:text-white dark:hover:bg-white/15",
},
},
defaultVariants: {
radius: "full",
variant: "primary",
},
});
type MyButtonVariants = VariantProps;
export type MyButtonProps = Omit &
MyButtonVariants & {className?: string};
function CustomButton({className, radius, variant, ...props}: MyButtonProps) {
return ;
}
export function CustomVariants() {
return Custom Button;
}
```
## With Next.js
Use `asChild` to integrate with Next.js:
```tsx
import Link from 'next/link';
import { Button } from '@heroui/react';
```
## With React Router
Use `asChild` to integrate with routing libraries:
```tsx
import { Link } from 'react-router-dom';
import { Button } from '@heroui/react';
```
## Next Steps
* Learn about [Styling](/docs/handbook/styling) components
* Explore [Animation](/docs/handbook/animation) options
* Browse [Components](/docs/components) for more examples
# HeroUI v3 > handbook > Styling
URL: /docs/handbook/styling
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/handbook/styling.mdx
Style HeroUI components with CSS, Tailwind, or CSS-in-JS
***
title: Styling
description: Style HeroUI components with CSS, Tailwind, or CSS-in-JS
icon: brush
links:
themes: true
tailwind: theme
---------------
## Overview
HeroUI components are built on React Aria and provide flexible styling options:
* **Tailwind CSS** - Use utility classes directly
* **CSS** - Target BEM classes or data attributes
* **CSS-in-JS** - Integrate with styled-components, Emotion, etc.
* **Render props** - Dynamic styling based on component state
## Basic Styling
### Using className
All HeroUI components accept `className` props:
```tsx
{/* content */}
```
### Using style
Components also accept inline styles:
```tsx
```
## State-Based Styling
HeroUI components expose their state through data attributes, similar to CSS pseudo-classes:
```css
/* Target different states */
.button[data-hover="true"], .button:hover {
background: var(--accent-hover);
}
.button[data-pressed="true"], .button:active {
transform: scale(0.97);
}
.button[data-focus-visible="true"], .button:focus-visible {
outline: 2px solid var(--focus);
}
```
## Render Props
Use render props for dynamic styling based on component state:
```tsx
// Dynamic classes
// Dynamic content
```
## BEM Classes
HeroUI uses [BEM methodology](https://getbem.com/) for consistent class naming:
```css
/* Block */
.button { }
.accordion { }
/* Element */
.accordion__trigger { }
.accordion__panel { }
/* Modifier */
.button--primary { }
.button--lg { }
.accordion--outline { }
```
### Customizing Components Globally
```css
/* global.css */
@layer components {
/* Override button styles */
.button {
@apply font-semibold uppercase;
}
.button--primary {
@apply bg-indigo-600 hover:bg-indigo-700;
}
/* Add custom variant */
.button--gradient {
@apply bg-gradient-to-r from-purple-500 to-pink-500;
}
}
```
## Creating Wrapper Components
For reusable custom components, create wrappers using [tailwind-variants](https://tailwind-variants.org/) - a Tailwind CSS first-class variant API created by us as well:
```tsx
import { Button as HeroButton, buttonVariants, type ButtonProps } from '@heroui/react';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
extend: buttonVariants,
base: 'font-medium transition-all',
variants: {
intent: {
primary: 'bg-blue-500 hover:bg-blue-600 text-white',
secondary: 'bg-gray-200 hover:bg-gray-300',
danger: 'bg-red-500 hover:bg-red-600 text-white',
},
size: {
small: 'text-sm px-2 py-1',
medium: 'text-base px-4 py-2',
large: 'text-lg px-6 py-3',
},
},
defaultVariants: {
intent: 'primary',
size: 'medium',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
}
export function CustomButton({ intent, size, className, ...props }: CustomButtonProps) {
return (
);
}
```
## CSS-in-JS Integration
### Styled Components
```tsx
import styled from 'styled-components';
import { Button } from '@heroui/react';
const StyledButton = styled(Button)`
background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%);
border-radius: 8px;
color: white;
padding: 12px 24px;
&:hover {
box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
}
`;
```
### Emotion
```tsx
import { css } from '@emotion/css';
import { Button } from '@heroui/react';
const buttonStyles = css`
background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%);
border-radius: 8px;
color: white;
padding: 12px 24px;
&:hover {
box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
}
`;
```
## Responsive Design
Use Tailwind's responsive utilities:
```tsx
```
Or with CSS:
```css
.button {
font-size: 0.875rem;
padding: 0.5rem 1rem;
}
@media (min-width: 768px) {
.button {
font-size: 1rem;
padding: 0.75rem 1.5rem;
}
}
```
## CSS Modules
For scoped styles, use CSS Modules:
```css
/* Button.module.css */
.button {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 12px 24px;
border-radius: 8px;
}
.button:hover {
transform: translateY(-2px);
}
.button--primary {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 12px 24px;
border-radius: 8px;
}
```
```tsx
import styles from './Button.module.css';
import { Button } from '@heroui/react';
```
## Component Classes Reference
### Button
* `.button` - Base
* `.button--{variant}` - Variants
* `.button--{size}` - Sizes
* `.button--icon-only` - Icon button
> **Note**: See [Button](/docs/components/button#css-classes) for more information on button classes.
### Accordion
* `.accordion` - Container
* `.accordion__item` - Item
* `.accordion__trigger` - Header
* `.accordion__panel` - Content
* `.accordion--outline` - Variant
> **Note**: See [Accordion](/docs/components/accordion#css-classes) for more information on accordion classes.
View all component classes in [@heroui/styles/components](https://github.com/heroui-inc/heroui/tree/main/packages/styles/components).
## Next Steps
* Learn about [Animation](/docs/handbook/animation) techniques
* Explore [Theming](/docs/handbook/theming) system
* Browse [Component](/docs/components) examples
# HeroUI v3 > handbook > Theming
URL: /docs/handbook/theming
Source: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/handbook/theming.mdx
Customize HeroUI's design system with CSS variables and global styles
***
title: Theming
description: Customize HeroUI's design system with CSS variables and global styles
icon: palette
links:
themes: true
tailwind: theme
---------------
## Overview
HeroUI uses CSS variables and [BEM](https://getbem.com/) classes for theming. You can 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](https://tailwindcss.com/docs/theme)'s theme. When you import `@heroui/styles`, it:
1. Uses Tailwind's built-in color palettes (like `--color-neutral-*`)
2. Maps them to semantic variables for easier use
3. Automatically switches between light and dark themes
4. Uses CSS layers and the `@theme` directive for organization
The system follows a simple naming pattern:
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are 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
```
### Switch Themes
```html
```
### Override Colors
```css
/* 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](/docs/handbook/colors) for the complete color palette and visual reference.
### Create your own theme
Use your theme:
```css
/* app/globals.css */
@layer theme, base, components, utilities;
@import "tailwindcss";
@import "@heroui/styles";
@import "./src/themes/ocean.css" layer(theme); /* [!code highlight]*/
```
Apply your theme:
```html
```
## Customize Components
### Global Component Styles
Override any component using BEM classes:
```css
@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](/docs/handbook/styling) for the complete styling reference.
### Find Component Classes
Each component docs page lists all available classes:
* **Base classes**: `.button`, `.accordion`
* **Modifiers**: `.button--primary`, `.button--icon-only`
* **Elements**: `.accordion__trigger`, `.accordion__panel`
* **States**: `[data-hover="true"]`, `[aria-expanded="true"]`
Example: [Button classes](/docs/components/button#css-classes)
## Import Strategies
### Full Import (Recommended)
Get everything with two lines:
```css
@import "tailwindcss";
@import "@heroui/styles";
```
### Selective Import
Import only what you need:
```css
/* Define layers */
@layer theme, base, components, utilities;
/* Base requirements */
@import "tailwindcss";
@import "@heroui/styles/base/base.css" layer(base);
@import "@heroui/styles/themes/theme.css" layer(theme);
@import "@heroui/styles/themes/default.css" layer(theme);
/* Components (all components) */
@import "@heroui/styles/components/index.css" layer(components);
/* OR specific components */
@import "@heroui/styles/components/button.css" layer(components);
@import "@heroui/styles/components/accordion.css" layer(components);
```
### Headless Mode
Build your own styles from scratch:
```css
@import "tailwindcss";
@import "@heroui/styles/base/base.css";
/* Your custom styles */
.button {
/* Your button styles */
}
```
## Adding Custom Colors
You can add your own semantic colors to the theme:
```css
/* 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:
```tsx
Info message
```
## Variables Reference
HeroUI defines three types of variables:
1. **Base Variables**: Non-changing values like `--white`, `--black`, spacing, and typography
2. **Theme Variables**: Colors that change between light/dark themes
3. **Calculated Variables**: Automatically generated hover states and size variants
For a complete reference of all variables and their values, see:
* [Colors Documentation](/docs/handbook/colors) - Visual color palette and base variables
* [Default Theme Source](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/index.css) - Complete theme implementation
### Calculated Variables (Tailwind)
We use Tailwind's `@theme` directive to automatically create calculated variables for hover states and radius variants:
circ @made by https://twitter.com/bdc */
--ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);
--ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
--ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);
--ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
--ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
--ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);
--ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
--ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
--ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
--ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
--ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);
--ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);
--ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
--ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
--ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
--ease-in-out-expo: cubic-bezier(1, 0, 0, 1);
--ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
/* Animations */
--animate-spin-fast: spin 0.75s linear infinite;
--animate-skeleton: skeleton 2s linear infinite;
}
`}
/>
## Resources
* [Colors Documentation](/docs/handbook/colors)
* [Styling Guide](/docs/handbook/styling)
* [Tailwind CSS v4 Theming](https://tailwindcss.com/docs/theme)
* [BEM Methodology](https://getbem.com/)
* [OKLCH Color Tool](https://oklch.com)