如何在 shadow dom 中使用全局 CSS 样式

Posted

技术标签:

【中文标题】如何在 shadow dom 中使用全局 CSS 样式【英文标题】:How to use global css styles in shadow dom 【发布时间】:2016-06-12 04:24:41 【问题描述】:

Shadow dom 封装 css 样式,选择器不跨越阴影边界。

问题:如何在shadow dom中使用全局通用css样式? (假设有一些常见的css样式会在所有页面中使用(例如:font-family、h1、h2、clear、reset ...),如何使其在shadow dom中工作?)

【问题讨论】:

2019 年已经过去了 3 年:大量的样式选择:jsfiddle.net/dannye/z8g1v532 【参考方案1】:

你可以通过 ::shadow 伪元素来实现。像这样:

::shadow .redColor

    background-color: red;    

这会将样式应用于具有 .redColor 类的阴影树内的所有元素。

这篇精彩文章中的更多信息和其他样式可能性:Shadow DOM 201

【讨论】:

:shadow 已被弃用,Amid。 我知道。但就目前而言,它是可行的,并且是我引用的文章中提到的其他可行解决方案。 它将被完全删除,所以我猜应该没有人使用它。当然,文章还可以。 弃用意味着是时候从项目中摆脱它了。浏览器供应商这样做并不是为了让您有更多时间对旧规范感到满意,而是让您有时间放弃它。在新项目中使用已弃用的规范不仅仅是一种反模式,如果我的团队中有人知道它已被弃用,我会在我注意到的那一刻解雇他们。 ::shadow 已弃用: developers.google.com/web/updates/2017/10/…【参考方案2】:

一些解决方案:

CSS 变量:
    http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/ https://developers.google.com/web/updates/2016/02/css-variables-why-should-you-care?hl=en http://blog.chromium.org/2016/02/chrome-49-beta-css-custom-properties.html
:host-context: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/ 另外,我没有测试过,但是有人建议@import url('/common-style.css');,这里:Polymer share styles across elements

请注意,上面列出的其中一篇文章也是由 Amid 指出的。到写这篇文章的时候,Chrome 还没有 CSS 变量。但现在它已经可以与最近推出的 Google Chrome 49 原生兼容了。

【讨论】:

谢谢!所以 CSS 变量、:host-context、::shadow(deprecated) 是这个问题的答案。虽然,这个问题的上下文是:当我尝试 angular2 时,它为组件引入了 shadow DOM。我担心的是,如果我们将整个页面封装到一个嵌套的 shadow DOM 树中,上面的东西可能不是 css 共享的解决方案,假设我们涉及 bootstrap,我们如何在 shadow DOM 中使用它? 我看到了如何使用 CSS 变量,但是不能全局覆盖浏览器内置样式感觉很尴尬。文档和规格似乎一次又一次地改变。有更改 @apply 语法、不推荐使用的 ::shadow、实验性的 ::theme 等等。有人有可持续的解决方案吗?【参考方案3】:

在 Chrome 66(截至 2018 年)中,提供的链接都不适用于我,所以我最终用这个来从外部自定义自定义元素:

<custom-element tabindex=10>
  <style>
    :host div 
      --color: red;
    
  </style>
</custom-element>

class Element extends HTMLElement 
    constructor() 
        super();
        var shadow = this.attachShadow(mode: 'open');

        var user_style = shadow.host.innerHTML.match(/<style>([\s\S]*?)<\/style>/);
        var style = document.createElement('style');
        style.innerHTML = `
            :host div 
                color: var(--color, #aaa);
             
        ` + user_style ? user_style[1] : '';    

        shadow.appendChild(style);
        shadow.host.querySelector('style').remove();
    


customElements.define(
  "custom-element",
  Element
) 

【讨论】:

【参考方案4】:

我刚刚在与原始问题相同的问题上苦苦挣扎,即:为 &lt;h3&gt; 元素定义 一次 一些全局规则,并从中受益于任何/许多 ShadowDOM秒。

不,css-variables非常适合这个东西,因为即使我已经为 &lt;h3&gt; 定义过一次,比如 fontcolor 变量,我也会仍然需要检查每个阴影样式表并添加使用它们的 CSS 规则。

在撰写本文时(是的,我们现在是 2019 年)最短的标准化解决方案确实是导入一些全球通用的 CSS。在 Chrome、Firefox 和 Anaheim(Chromium 上的 Edge)中完美运行。

它仍然需要在每个组件中添加一个@import 规则,因此仍然很昂贵(从编码/维护 POV,样式表只获取一次),但这是我们现在可以支付的最低价格。

【讨论】:

直到我一直听说的 Edgium 被正式命名为 Anaheim

以上是关于如何在 shadow dom 中使用全局 CSS 样式的主要内容,如果未能解决你的问题,请参考以下文章

如何让导入的css字体/图标对shadow dom中的元素产生影响?

Shadow dom 中的 FontAwesome svg

基于 Shadow DOM 根的字体大小 css-values

Firefox:shadow-DOM 兼容性

Shadow DOM 元素可以继承 CSS 吗?

当我们有 iframe 时为啥要使用 Shadow DOM?