Firefox 128中@property在Shadow DOM中失效问题咨询
Firefox 128中@property在Shadow DOM失效的原因与解决方法
问题现象
Firefox 128正式搭载@property特性后,该功能在常规HTML/CSS环境下可正常工作,但应用到Shadow DOM中时完全失效。
常规DOM正常示例
@property --a1 { syntax: '<angle>'; inherits: false; initial-value: 10deg; } .hi1 { border: 2px solid black; width: fit-content; margin: 0 auto; } .box1 { --a1:10deg; /* Firefox需要显式赋值保证输出有效 */ cursor:pointer; width:250px; height:200px; margin:15px; display:inline-block; transition:--a1 0.5s; background:linear-gradient(var(--a1),red ,blue); } .box1:hover { --a1:180deg; } body { text-align:center; }
<div class="hi1"> <h1>In regular DOM</h1> <div class="box1"></div> <div class="box1" style="background:conic-gradient(from var(--a1), red var(--a1),blue)"></div> <div class="box1" style="background:linear-gradient(calc(180deg - var(--a1)),red ,blue,red )"></div> </div>
Shadow DOM失效示例
const css = `@property --a2 { syntax: '<angle>'; inherits: false; initial-value: 10deg; } .hi2 { border: 2px solid black; width: fit-content; margin: 0 auto; } .box2 { --a2:10deg; /* Firefox需要显式赋值保证输出有效 */ cursor:pointer; width:250px; height:200px; margin:15px; display:inline-block; transition:--a2 0.5s; background:linear-gradient(var(--a2),red ,blue); } .box2:hover { --a2:180deg; }`; class MyComponent extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); root.innerHTML = ` <style>${css}</style> <div class="hi2"> <h1>In shadow DOM</h1> <div class="box2"></div> <div class="box2" style="background:conic-gradient(from var(--a2), red var(--a2),blue)"></div> <div class="box2" style="background:linear-gradient(calc(180deg - var(--a2)),red ,blue,red )"></div> </div>`; } connectedCallback() {} } customElements.define('my-component', MyComponent);
<my-component></my-component>
问题原因
Firefox 128对Shadow DOM内的@property存在作用域限制:当@property定义在Shadow DOM的<style>标签中时,内联style属性无法感知到该自定义属性的类型定义。示例中后两个.box2元素使用内联样式引用--a2,但渐变函数无法识别该变量的<angle>类型,导致过渡效果完全失效。
解决方法
方案1:将内联样式逻辑移到Shadow DOM样式表中
通过新增类定义不同渐变效果,彻底避免内联样式引用自定义属性,让@property的类型定义能覆盖所有样式逻辑:
const css = `@property --a2 { syntax: '<angle>'; inherits: false; initial-value: 10deg; } .hi2 { border: 2px solid black; width: fit-content; margin: 0 auto; } .box2 { --a2:10deg; cursor:pointer; width:250px; height:200px; margin:15px; display:inline-block; transition:--a2 0.5s; background:linear-gradient(var(--a2),red ,blue); } .box2:hover { --a2:180deg; } /* 新增类定义不同渐变效果 */ .box2-conic { background:conic-gradient(from var(--a2), red var(--a2),blue); } .box2-reverse { background:linear-gradient(calc(180deg - var(--a2)),red ,blue,red ); }`; class MyComponent extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); root.innerHTML = ` <style>${css}</style> <div class="hi2"> <h1>In shadow DOM</h1> <div class="box2"></div> <div class="box2 box2-conic"></div> <div class="box2 box2-reverse"></div> </div>`; } connectedCallback() {} } customElements.define('my-component', MyComponent);
方案2:用CSS.registerProperty()在Shadow DOM作用域注册属性
如果必须保留内联样式,可通过JS API在Shadow DOM的作用域内注册自定义属性,确保内联样式能识别变量的类型信息:
class MyComponent extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); // 在Shadow DOM中注册样式表 root.adoptedStyleSheet = new CSSStyleSheet(); root.adoptedStyleSheet.replaceSync(` .box2 { --a2:10deg; cursor:pointer; width:250px; height:200px; margin:15px; display:inline-block; transition:--a2 0.5s; background:linear-gradient(var(--a2),red ,blue); } .box2:hover { --a2:180deg; } .hi2 { border: 2px solid black; width: fit-content; margin: 0 auto; } `); // 针对Shadow DOM作用域注册自定义属性 CSS.registerProperty({ name: '--a2', syntax: '<angle>', inherits: false, initialValue: '10deg', }, root); root.innerHTML = ` <div class="hi2"> <h1>In shadow DOM</h1> <div class="box2"></div> <div class="box2" style="background:conic-gradient(from var(--a2), red var(--a2),blue)"></div> <div class="box2" style="background:linear-gradient(calc(180deg - var(--a2)),red ,blue,red )"></div> </div>`; } connectedCallback() {} } customElements.define('my-component', MyComponent);
内容的提问来源于stack exchange,提问作者Shoghi Simon
相关产品推荐
相关产品推荐

