Javascript webcomponentsjs在safari和firefox中应用的webcomponent样式

Javascript webcomponentsjs在safari和firefox中应用的webcomponent样式,javascript,web-component,Javascript,Web Component,我有两个自定义元素: <name-card data-color="#000000"></name-card> <name-card data-color="#80B88C"></name-card> 两个都改变了正确的颜色,但我仍然不知道为什么他们会在safari和firefox上对元素样式应用最后一种颜色。这是因为polyfill无法完全实现css隔离 因此,添加到多填充阴影DOM中的CSS样式表实际上应用于整个文档。当使用同一名称规则两次时

我有两个自定义元素:

<name-card data-color="#000000"></name-card>
<name-card data-color="#80B88C"></name-card>

两个都改变了正确的颜色,但我仍然不知道为什么他们会在safari和firefox上对元素样式应用最后一种颜色。

这是因为polyfill无法完全实现css隔离

因此,添加到多填充阴影DOM中的CSS样式表实际上应用于整个文档。当使用同一名称规则两次时,最后一个规则获胜。这就是为什么你会在Safari和Firefox中观察到这种行为

在您的案例中,有一个解决此问题的方法,它处理
::before
::after
伪元素:

当前解决方案

  • 生成更具体的
    cssRule
    ,其中包括特定的颜色:
attachedCallback()函数中:


未来解决方案

将在每个属性上实现
attr()
的CSS 3规范时:

  • 将颜色传播到目标元素,并使用
    attr()
    CSS函数应用通过属性传递的正确颜色(
    data color
此解决方案的优点是,它的工作方式与polyfill和本机实现相同,并且具有无限数量或颜色

attachedCallback()函数中:

var proto=Object.create(HTMLElement.prototype)
proto.createdCallback=函数()
{
this.createShadowRoot()
var tmpl=document.querySelector('template')
this.shadowRoot.appendChild(tmpl.content.cloneNode(true))
}
proto.attachedCallback=函数()
{
//获取自定义颜色
var bgColor=this.dataset.color
//将其添加到顶级内部阴影DOM中
this.shadowRoot.querySelector('section').dataset.color=bgColor
//在下一个微任务中更改样式表
var style=this.shadowRoot.querySelector('style')
setTimeout(函数()
{
var sheet=style.sheet
sheet.insertRule(“[data color=”+bgColor
+'].base::在{background:'+bgColor+';}之后
,sheet.cssRules.length)
} )
}
document.registerement('name card',{prototype:proto})

.base::在{
内容:“-后缀”;
}
自定义元素
基本元素

非常感谢你,让我高兴极了。但我使用cssRules解决方案是因为我有伪元素样式需要更改。。。。我无法更改
::在使用您的解决方案之后或
::在使用您的解决方案之前。如果我想解决此问题,唯一的方法是重新编写css,使用
div
而不是
:在
之后:在
之前,对吗?然后我可以使用解决方案1。我不能使用
背景:attr(数据颜色)
,它显示无效的属性值-黄色三角形。css
attr()
似乎只适用于
内容
。没错,它在规范中,但尚未在borwsers中实现!因此,解决方法是使用旧的第二种解决方案。我更新了我的答案。
insertRule()
将返回问题,只在chrome上工作。safari和firefox显示最后一种颜色将获胜。他们俩都涂上了颜色。
for(i = 0; i < rules.length; i++){
    if(rules[i].selectorText === '.base'){
       rules[i].style.background = bgColor;
    }
}
sheet.insertRule( '[data-color=' + bgColor + '] .base::before { background: ' + bgColor + ' ; }', sheet.length )
var targets = this.querySelectorAll( '.base' )
for ( var i = 0 ; i < targets.length ; i++ )
{
    targets[i].dataset.color = bgColor  
}
.base::before {
    background: attr( data-color )
}