Examples
Data attribute
Applying themes via data attributes instead of CSS classes.
Edit on GitHub
Last updated on
Instead of adding a class to <html>, you can set a data-* attribute. This is useful when you want to avoid conflicts with existing class-based styling.
Setup
<ThemeProvider attribute="data-theme">
{children}
</ThemeProvider>This sets data-theme="light" or data-theme="dark" on <html>. Use it in CSS:
[data-theme="light"] {
--bg: #ffffff;
--fg: #0a0a0a;
}
[data-theme="dark"] {
--bg: #09090b;
--fg: #fafafa;
}Custom attribute values
Map theme names to different attribute values using the value prop:
<ThemeProvider
attribute="data-mode"
value={{ light: "light-mode", dark: "dark-mode" }}
>
{children}
</ThemeProvider>[data-mode="light-mode"] { --bg: #ffffff; }
[data-mode="dark-mode"] { --bg: #09090b; }Multiple attributes
Apply multiple attributes at once by passing an array:
<ThemeProvider attribute={["class", "data-theme"]}>
{children}
</ThemeProvider>This sets both the dark class and data-theme="dark" simultaneously, useful when mixing Tailwind with CSS variable styles.
Class or data attribute?
- Use
classwhen your CSS framework already uses class selectors, or when one theme maps to several utility classes. - Use a
data-*attribute when theme state should be explicit, isolated from unrelated classes, or combined with another independent dimension such asdata-palette. - Selector performance is not a meaningful difference for a root-level theme attribute. Specificity and integration with your existing CSS are the practical concerns.
An attribute array mirrors one theme value to several attributes. For independently controlled values, create separate typed factories with distinct contexts and storage keys.