Support Scoped Theme Activation via `data-theme` for Non-Root HTML Elements
Describe the feature in detail (code, mocks, or screenshots encouraged)
Currently, Skeleton documentation instructs users to activate a theme by adding data-theme to the root HTML tag:
<html data-theme="cerberus">...</html>
In Skeleton v2, theme activation worked within any scope — for example, setting data-theme on a <div> correctly applied the theme inside that element’s subtree:
<div data-theme="cerberus">...</div>
However, in Skeleton v4, this no longer works. It appears that the CSS selectors for theme variables are defined as:
[data-theme='catppuccin'] { ... }
instead of being scoped to the root with:
:root [data-theme='catppuccin'] { ... }
Because of that, many theme variables do not propagate to the root, and the default values are still used — making the theme ineffective in scoped or nested contexts.
This limitation prevents using Skeleton in environments without direct control of the root HTML (for example, when building Figma plugins with frameworks like Plugma). In such cases, developers must rely on scoped theming rather than modifying the <html> tag, which isn’t possible.
A change in how Skeleton applies its theme CSS would restore flexible theme scoping and expand usability for plugin and embedded app contexts.
Proposed change:
Enable scoped theme activation by restoring selector behavior similar to Skeleton v2 — allowing theme variables to apply within any container where data-theme is defined, without requiring access to the root HTML.
Example improvement:
:root [data-theme='catppuccin'],
[data-theme='catppuccin'] {
/* Theme variables */
}
This approach would let both root and scoped theme usage coexist.
What type of pull request would this be?
Enhancement
Provide relevant links or additional information.
- Development context: building a Figma plugin with Plugma, where root HTML isn’t accessible
- Expected result: scoped
data-themecorrectly activates the theme local to that container
@Typogram so this was an intentional change in v3 by request of fellow maintainer @Hugos68. His take was that if we don't apply the theme on the <html> element that this could lead to a situation where there might be a "flash" on page load. Details here:
- https://github.com/skeletonlabs/skeleton/issues/2559
Per:
Because of that, many theme variables do not propagate to the root, and the default values are still used — making the theme ineffective in scoped or nested contexts.
Can you give an example of what you mean by "scoped" or "nested" contexts? I'm not immediately clear what this means. And I'm not familiar with how FIgma plugins operate, so perhaps it would help to start there?
I do want to make it clear it's possible to override themes at any scope in the page. You can see this in practice for our Preset Themes interface on the Themes doc: https://www.skeleton.dev/docs/design/themes#preset-themes
This is constructed in a dynamic manner, where we query our internal set of themes (in skeleton-common) and use a loop to generate the small buttons:
https://github.com/skeletonlabs/skeleton/blob/main/sites/skeleton.dev/src/components/ui/theme-list.astro
Specifically we apply the theme here to localize the styling for the button using a local data-theme attribute:
https://github.com/skeletonlabs/skeleton/blob/main/sites/skeleton.dev/src/components/ui/theme-list.astro#L9
TL;DR example
<!DOCTYPE html>
<html lang="en" data-theme="cerberus">
<head>...</head>
<body>
<div>(this will use the parent Cerberus theme</div>
<div data-theme="mint">(this will take the localized Mint theme)</div>
</body>
</html>
But it sounds like the issue is specifically for non-traditional web apps (Figma plugins, etc) that don't have access to the <html> element. is that right?
I'd want to be very cautious about implementing a duplicate selector with the :root prefixed. There may be side effects from using root that may not be immediately clear. This would require some testing to ensure we're not introducing a regression.
@Hugos68 I'd welcome your thoughts on this as well.
@Typogram Hugo and I were discussing internally - out of curiosity, can users insert a custom theme file local to their project for Figma plugins and modify the theme syntax directly to solve this use case? That might be our temporary solution until we can dig into this a bit further - likely as part of the v5 update.
@Typogram Hugo and I were discussing internally - out of curiosity, can users insert a custom theme file local to their project for Figma plugins and modify the theme syntax directly to solve this use case? That might be our temporary solution until we can dig into this a bit further - likely as part of the v5 update.
Yes, this solution is viable and what I am planning to do.
Cool. I've added this to the docket of things to test for v5. We can't promise we'll support every possible technology that exists out there. But we've received similar requests in the past. So I think a bit of research and testing is in order here.