Javascript html自定义元素使宿主css改为应用于阴影dom子级

Javascript html自定义元素使宿主css改为应用于阴影dom子级,javascript,html,css,shadow-dom,custom-element,Javascript,Html,Css,Shadow Dom,Custom Element,因此,我目前正在开发一个自定义元素,我希望以后能够像使用普通html元素一样使用css对其进行样式设置。但是,按照我的元素的设置方式,一些css样式(如填充)在应用于元素本身时会打断元素-相反,它们需要应用于自定义元素的阴影dom中的元素才能工作。因此,我的问题是:如何使自定义元素上的用户定义css应用于其阴影dom中的元素? 为了说明这一点,假设在以下代码中使用了自定义元素: <my-element style="padding:10px">Content here</my-

因此,我目前正在开发一个自定义元素,我希望以后能够像使用普通html元素一样使用css对其进行样式设置。但是,按照我的元素的设置方式,一些css样式(如填充)在应用于元素本身时会打断元素-相反,它们需要应用于自定义元素的阴影dom中的元素才能工作。因此,我的问题是:如何使自定义元素上的用户定义css应用于其阴影dom中的元素?

为了说明这一点,假设在以下代码中使用了自定义元素:

<my-element style="padding:10px">Content here</my-element>
这里的内容
通常,对于我使用的阴影dom,这将导致以下平坦的dom树:

<my-element style="padding:10px">
    <div>
        Content here
    </div>
    Some other elements here
</my-element>

满足于此
这里还有其他一些元素
但是我想让平坦的dom树看起来像这样:

<my-element>
    <div style="padding:10px">
        Content here
    </div>
    Some other elements here
</my-element>

满足于此
这里还有其他一些元素
我已经尝试了许多解决方案,但到目前为止,没有一个对我有效:

  • padding:inherit
    应用于内部元素-仅当我将padding也保留在父元素上时才有效,但我需要它为0(或者让子元素在相对定位时忽略父元素的padding,但我认为这是不可能的)
  • 使用css变量
    --padding
    在内部元素上设置padding-这在技术上是可行的,但它需要自定义元素的用户指定
    --padding
    ,而不仅仅是
    padding
    ,从而降低元素的易用性
  • 使用脚本侦听填充的更改—据我所知,当元素的计算样式更改时,无法得到通知,因此我必须定期检查以使其正常工作,这可能会降低页面速度。例如,如果加载了影响自定义元素填充的新css工作表,则仅侦听对
    元素.style的更改将不起作用

  • 这很简单。

对于CSS,只需设置

/* force to clear padding of the element */    
my-element { padding:0px !important; clear:both; } 

/* this indicate the first div found inside the element */
my-element > div:first-child { padding:10px; } 

就这样。它应该可以工作。

您可以定义自定义属性。这是一个基本的例子

class CustomElement扩展了HtmleElement{
构造函数(){
超级();
this.shadow=this.attachShadow({mode:'closed'});
常量css=`
:主持人{
显示:内联块;
}
div{
填充:${this.getAttribute('padding')};
}`
this.styles=document.createElement('style');
this.styles.innerHTML=css;
}
connectedCallback(){
const div=document.createElement('div');
div.innerHTML=this.innerHTML;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
自定义元素。定义('custom-element',CustomElement)

此处的文本
如果您只需要填充就可以让用户控制,并且您需要填充不破坏布局,请指定框大小

host {
  box-sizing: border-box;
}

然后,元素的用户可以以传统方式调整填充,而无需将其吹出…并且无需添加额外的div。

我认为您还没有完全解开这个问题-当然,我可以自己像那样将填充添加到div中,但我希望用户能够控制填充量,因此,我正在寻找一种方法,使div始终具有在自定义元素上指定的填充。最佳实践是只使用
!重要信息
当其他所有操作都已完成但失败时。我想这是一种方法,但它仍然不如css那么容易使用-例如,您必须在每个元素上指定它,而不能仅使用css来选择该类型的所有元素+1对于代码示例,虽然您必须在每个元素上指定它-->这是您的示例所显示的,您正在使用内联样式,所以您已经在这样做了。我已经尝试使用getComputedStyle,问题是我无法检测计算样式何时更改。这对于不打断元素宽度和高度有效,但是也有一些其他的原因不直接在元素上添加填充。我不希望我的示例代码中的“其他一些元素”受到填充的影响,而且在我的示例中,外部元素是可滚动的,因此在其上添加填充在浏览器中的行为是不一致的。将全局样式表注入shadowDOM对您有效吗?使用: