Shadow DOM元素可以继承CSS吗?

Can Shadow DOM elements inherit CSS?

本文关键字:CSS 继承 DOM 元素 Shadow      更新时间:2023-09-26

我在听这一集JavaScript Jabber:

http://javascriptjabber.com/120-jsj-google-polymer-with-rob-dodson-and-eric-bidelman/

罗伯一度说:

每个人都有这种第一倾向,因为它很有意义。你会说,"Bootstrap是组件。我要把它们做成标签。"但随后您会发现,Bootstrap样式表只是一个长长的样式表,在编写时假定它可以触及文档的每个部分。当你突然对标记进行范围界定,使CSS无法触及它时,CSS实际上必须与它一起在Shadow DOM中,你必须从头开始编写该元素,我认为这是人们最初感到非常困惑和沮丧的地方。

这让我想知道,你如何用Web组件解决这个问题?Shadow DOM模板是否有继承通用样式的方法,或者您必须为每个单独的组件重复共享CSS ?还是别的什么?

注意:下面答案的实质内容不再相关,因为所讨论的特性已经被弃用一段时间了。不要使用示例代码,但可以随意查看Internet的过去。


在一个完整的Shadow DOM实现中,CSS有一个::shadow伪类,还有一个/deep/组合子。

::shadow伪类允许您进入元素下的阴影DOM,并且它匹配阴影根。/deep/组合子有效地完全打开了影子DOM。

因此,如果你有一个<x-foo>元素里面有<span>元素,你可以用 把它们变成红色
x-foo::shadow span { color: red; }

或者将所有阴影DOM中的<spans>设置为红色:

body /deep/ span { color: red; }

Shadow DOM/CSS的当前状态是可以链接到外部样式表。更多信息请访问MDN: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM#Internal_versus_external_styles

然后,您可以使用某种实用样式表(Tailwind或类似),所有组件都引用它,这样就不会复制CSS。理论上,CSS文件只下载一次,缓存一次,然后每个自定义元素就可以使用其中的类(只要它们都链接到它)。

看看这个鲜为人知的方法:

<core-style>聚合物元素

你可以在html导入文件中定义样式:

<core-style id="x-test">
  :host {
    backgound-color: steelblue;
  }
</core-style>

可以在多于1个元素中使用

<polymer-element name="x-test" noscript>
  <template>
    <core-style ref="x-test"></core-style>
    <content></content>
  </template>
</polymer-element>

在这篇写得很好的文章中,你可以读到更多关于如何使用该技术的内容。

然而,我能想到的一个缺点是不可能使用SASS,因为样式是在<core-style>标记中定义的,而不是在<style>元素中定义的,并且没有明确的方法来导入外部样式表。

我想我明白你的意思了。您可以在每个自定义元素中使用link来包含主样式或扩展包含它的现有元素。例如(使用Polymer):

<polymer-element name="ui-button" noscript>
  <template>
    <link rel="stylesheet" href="main.css"/>
    <div class="class-from-main" style="">
      <content></content>
    </div>
  </template>
</polymer-element>

我认为它值得你读:https://github.com/necolas/normalize.css/issues/408

下面是一个工作的例子:http://jsbin.com/zayih/1/edit?html,css,output

虽然用#placeholder瞄准它时似乎不起作用

在Chrome devtools配置选项卡中打开"显示用户代理影子DOM",然后检查<input>,看看我的意思