You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tailwind v4 uses @property to define defaults for custom properties. At the moment, shadow roots do not support@property. It used to be explicitly denied in the spec, but it looks like there's talk on adding it: w3c/css-houdini-drafts#1085
I don't know if this is something tailwind should fix, but it took me a while to find the issue, so it's probably worth keeping this issue to document the limitation.
An easy way to do that with Vite is to create a tailwind css file specifically for the properties and apply a transform:
exportdefaultdefineConfig(()=>{return{
...
plugins: [tailwindcss(),{name: "tailwind-properties",transform(code,id){if(id.endsWith("tailwind-properties.css?inline")){// Change custom properties to inheritcode=code.replaceAll("inherits: false","inherits: true");// Remove everything before the property declarationscode=code.substring(code.indexOf("@property"));returncode;}},},],};});
Reacted by Michael Brunner, Aaron, Gliches, Thomas, Vincelwt, iamolegga, Konstantin, Marcel, Danny Slatkin, Etienne and 45 more
Reacted by Syed Abdullah Yaqoob
Reacted by Matej Leško
Reacted by Piotr Stus, Richard Hess, Gliches, Husam Elbashir, Amit Beckenstein, Masaru Irisawa 入澤 賢, Brendan Deneen, Daniel Wilkowski, maximenavet, Merrick Christensen and 2 more
Not 100% sure if this is related, but I noticed that in a shadow root, the defaults under @theme aren't available. I.e. I can't see --spacing in devtools, and it doesn't have any value.
Essentially rendering Tailwind unusable in shadow roots for most use cases.
Reacted by Michael Brunner, Yuriy Ostapenko, Marcel, Daniel Wilkowski, Maximilian Förster, Artiom Neganov and PYUDNG
@blittle Thanks for the detailed writeup and sorry for the late answer here.
From what I understand after doing some testing, it is indeed still required that the @property definitions are hoisted to the base document.
The snippet you have for that also changes the inherits property. Do you remember why this was necessary? I was playing around it in a simple playground and found that this wasn't necessary for my tests. I didn't transform the sources via Vite though but added this snippet directly within the runtime of a custom component's connectedCallback hook:
I've stumbled upon this today so thanks for the workaround @blittle@philipp-spiess. I've spent an hour pulling my hair out.
@philipp-spiess Does it make sense to be somehow able to configure tailwindcss to build the CSS with simple variables instead of @property for cases like this? Or would that break other stuff?
Reacted by Casey Corcoran, Marcel, MengXi, 51mydao, Daniel Wilkowski and Werner Freytag
Reacted by Thomas Off, Vincelwt, Marcel, Samuel Stroschein, Evgeny Bobkin, Gabriel Uhlíř, Taylor, Daniel Wilkowski, Alexander Bluhm, Artiom Neganov and 1 more
Want to emphasize this answer, since this is no problem of @property itself, but of the enclosing @support block. Especially the -webkit-hyphens: none condition.
This is probably closest to a fully working system (atleast until I find myself pressing f5 10 times when I see my styles not getting applied only to realize tailwind isn't getting along with shadow dom :) )
Would keep updating this hopefully if I find more problems and their potential solutions
import React from 'react';
import ReactDOM from 'react-dom/client';
import ReactShadowRoot from 'react-shadow-root';
import tailwindStyles from './index.css?inline'; // Tailwind compiled CSS
// --- Tailwind normalizer for ShadowRoot ---
function normalizeTailwind(css: string): string {
return css
.replace(/:root\b/g, ':host')
.replaceAll('((-webkit-hyphens:none)) and ', '')
.replaceAll('(-webkit-hyphens: none) and ', '');
}
// --- Demo component ---
function Demo() {
return (
I just ran into this while using Shadow DOM, and I was confused about why some variables didn't work. I would love to see this fixed or a config workaround.
Reacted by Syndesi, Chris, Eric Kim, Hasan Baki Kucukcakiroglu, Daniel Oshiro, Rafael A. Escarabelo, andreypvitor4, Julien Vasseur and Matheus Filype
Reacted by Daniele Nicosia, Fabian Martin, hambergerpls, StinkendeHobbit, Hasan Baki Kucukcakiroglu, Chris, Rafael A. Escarabelo, andreypvitor4, Julien Vasseur, festoney8 and 1 more
exportfunctionaddStyle(shadow: ShadowRoot,styles: string[]){constcss=styles.join('\n').replaceAll(':root',':host')// Extract @property declarations and hoist to document head,// because @property doesn't work inside Shadow DOM <style> elements.// https://github.com/tailwindlabs/tailwindcss/issues/15005constpropertyRules: string[]=[]constshadowCss=css.replace(/@property\s+[^{]+\{[^}]*\}/g,(match)=>{propertyRules.push(match)return''})if(propertyRules.length>0){constpropStyle=document.createElement('style')propStyle.textContent=propertyRules.join('\n')document.head.appendChild(propStyle)}conststyle=document.createElement('style')style.textContent=shadowCssif(shadow.firstChild){shadow.insertBefore(style,shadow.firstChild)}else{shadow.appendChild(style)}}
Reacted by Kévin TURMEL, Artiom Neganov and Matheus Filype
Activity
ErwinAI commentedon Nov 22, 2024
Not 100% sure if this is related, but I noticed that in a shadow root, the defaults under
@themearen't available. I.e. I can't see--spacingin devtools, and it doesn't have any value.Essentially rendering Tailwind unusable in shadow roots for most use cases.
rose21wiley commentedon Nov 28, 2024
philipp-spiess commentedon Jan 29, 2025
@blittle Thanks for the detailed writeup and sorry for the late answer here.
From what I understand after doing some testing, it is indeed still required that the
@propertydefinitions are hoisted to the base document.The snippet you have for that also changes the
inheritsproperty. Do you remember why this was necessary? I was playing around it in a simple playground and found that this wasn't necessary for my tests. I didn't transform the sources via Vite though but added this snippet directly within the runtime of a custom component'sconnectedCallbackhook:Add `:host` rule to `@theme` layer (#15975)
kilobyte2007 commentedon Feb 5, 2025
I've stumbled upon this today so thanks for the workaround @blittle @philipp-spiess. I've spent an hour pulling my hair out.
@philipp-spiess Does it make sense to be somehow able to configure tailwindcss to build the CSS with simple variables instead of
@propertyfor cases like this? Or would that break other stuff?molvqingtai commentedon Feb 14, 2025
Same issue, the shadow dom should follow isolation rules, we need a way not to rely on
@propertyKoJem9Ka commentedon Mar 4, 2025
+1 Same problem(
meefik commentedon Mar 19, 2025
You can use this code to add Tailwind properties to global style sheets:
Or you can replace
@propertywith variables like this:fix(components): apply Tailwind's `@property`s to the `:host` instead.
fix(components): apply Tailwind's `@property`s to the `:host` instead
fix(components): apply daisyui styles to host instead of root
24 remaining items
Add hack to work around issue with shadow DOM and @Property
robertknight commentedon Sep 12, 2025
For reference https://developer.chrome.com/docs/css-ui/css-names discusses how
@propertyis supposed to work with Shadow DOM and how it actually behaves. w3c/csswg-drafts#10541 is a specification issue concerning@propertyand Shadow DOM.Add hack to work around issue with shadow DOM and @Property
Add hack to work around issue with shadow DOM and @Property
Add hack to work around issue with shadow DOM and @Property
Add hack to work around issue with shadow DOM and @Property
fix: handle @Property rules in shadow DOM by injecting into document …
feat(bookmark): Refactor and Beautify Bookmark Preview for Enhanced UX (
fix: hack support for @Property in shadow-dom
fix(ui): add Tailwind v4 @Property rules injection for Shadow DOM com…
Alletkla commentedon Jan 8, 2026
Want to emphasize this answer, since this is no problem of
@propertyitself, but of the enclosing @support block. Especially the-webkit-hyphens: nonecondition.danimalweb commentedon Jan 20, 2026
I just ran into this while using Shadow DOM, and I was confused about why some variables didn't work. I would love to see this fixed or a config workaround.
Alletkla commentedon Jan 21, 2026
@danimalweb just published a small vite plugin that does the job for me: https://www.npmjs.com/package/vite-plugin-tailwind-shadowdom
You might give it a try :)
Edit: updated for safari
rxliuli commentedon Feb 12, 2026
Sharing a runtime solution
khalidsaidi commentedon Mar 25, 2026