0
# CSS Class-Based Theming
1
2
Theme switching by applying CSS classes to parent elements. This approach is ideal for CSS frameworks, traditional stylesheet-based themes, and any styling system that relies on CSS class names.
3
4
## Capabilities
5
6
### withThemeByClassName
7
8
Creates a decorator that applies theme-specific CSS classes to a parent element (typically `html` or `body`).
9
10
```typescript { .api }
11
/**
12
* Creates a decorator for CSS class-based theme switching
13
* @param config - Configuration object specifying themes and options
14
* @returns Storybook decorator function
15
*/
16
function withThemeByClassName<TRenderer extends Renderer = Renderer>(
17
config: ClassNameStrategyConfiguration
18
): DecoratorFunction<TRenderer>;
19
20
interface ClassNameStrategyConfiguration {
21
/** Mapping of theme names to CSS class names */
22
themes: Record<string, string>;
23
/** Name of the default theme */
24
defaultTheme: string;
25
/** CSS selector for the parent element (defaults to 'html') */
26
parentSelector?: string;
27
}
28
```
29
30
**Usage Examples:**
31
32
```typescript
33
import { withThemeByClassName } from '@storybook/addon-themes';
34
35
// Basic usage with light/dark themes
36
export const decorators = [
37
withThemeByClassName({
38
themes: {
39
light: 'light-theme',
40
dark: 'dark-theme',
41
},
42
defaultTheme: 'light',
43
}),
44
];
45
46
// Multiple theme classes
47
export const decorators = [
48
withThemeByClassName({
49
themes: {
50
light: 'theme-light bg-white',
51
dark: 'theme-dark bg-gray-900',
52
blue: 'theme-blue bg-blue-100',
53
},
54
defaultTheme: 'light',
55
}),
56
];
57
58
// Custom parent selector
59
export const decorators = [
60
withThemeByClassName({
61
themes: {
62
default: 'default-theme',
63
contrast: 'high-contrast-theme',
64
},
65
defaultTheme: 'default',
66
parentSelector: 'body',
67
}),
68
];
69
```
70
71
## Implementation Details
72
73
### Class Management
74
75
The decorator automatically:
76
- Removes classes from previously selected themes
77
- Adds classes for the newly selected theme
78
- Handles multiple CSS classes per theme (space-separated)
79
- Works with any CSS selector as the parent element
80
81
### Theme Override Support
82
83
Stories can override the global theme selection:
84
85
```javascript
86
export const DarkVariant = {
87
parameters: {
88
themes: {
89
themeOverride: 'dark'
90
}
91
}
92
};
93
```
94
95
### Integration with CSS Frameworks
96
97
Perfect for CSS frameworks that use class-based theming:
98
99
```css
100
/* Tailwind CSS example */
101
.light-theme {
102
@apply bg-white text-gray-900;
103
}
104
105
.dark-theme {
106
@apply bg-gray-900 text-white;
107
}
108
109
/* Bootstrap example */
110
.theme-light {
111
background-color: var(--bs-light);
112
color: var(--bs-dark);
113
}
114
115
.theme-dark {
116
background-color: var(--bs-dark);
117
color: var(--bs-light);
118
}
119
```