我听说了在this css-Tricks文章,解释如何实现图像滑块作为示例用例的Web组件。其中出现的代码示例是:
CSS
#slides ::content img { width: 25%; float: left; }
HTML
<template> ... <div class="inner"> <content select="img"></content> </div> </template>
它似乎是指这个<内容>标签,用于允许用户包括Web组件,但我想更深入地了解这一点。
编辑:
进一步阅读之后,在上述文章中,我发现了一个链接作者的“Shadow DOM CSS Cheatsheet”,其中包括一个解释什么是:: content伪元素的段落:
Selects distributed nodes inside of an element. Needs to be paired
with polyfill-next-selector for browsers that do not support the
native selector.
::content h1 { color: red; }
资料来源:http://robdodson.me/blog/2014/04/10/shadow-dom-css-cheat-sheet/
这是有帮助的,但我仍然发现整个事情相当不透明。任何额外的见解?
解决方法
目前,浏览器仍支持< content>和:: content。
原始答案:
概要:
:: content本质上是一种挖掘更深层和风格的ShadowHost的后代的方式,通常不能对它们进行样式化,因为你的CSS不知道在没有:: content的情况下寻找ShadowDOM片段。
这个答案假设你至少有点熟悉<template>
元素和Web Components,特别是ShadowDOM,它处理ShadowTrees和他们的两个主要元素,ShadowHost和ShadowRoot。
注 – 在撰写本文时,在五个主要浏览器上对Web组件的支持不到50%(即使是前缀默认支持)。虽然所有现代浏览器都支持< template>,但只有最新版本的Chrome和Opera支持ShadowDOM;在你切换about:config(dom.webcomponents.enabled)中的必需功能后,Firefox支持它的一部分。
使用ShadowDOM的目标与MVC的separation of concerns类似。也就是说,我们要将内容与演示分开,并允许我们的代码中封装的模板使它更易于管理。我们已经在各种编程语言,但它仍然是一个问题在一段时间在HTML和CSS。此外,在对web应用中的元素进行样式化时,可能会与类名称发生冲突。
通常,我们与LightDOM(一种“Light Realm”)交互,但有时利用封装是有帮助的。跨越到这种“影子领域”(Web组件的一部分)是一种新的方法,通过允许封装来防止上述问题。应用于ShadowTree中的标记的任何样式将不会应用于您的ShadowTree之外的标记,即使使用完全相同的类或选择器也是如此。
当ShadowTree(位于ShadowDOM中)具有来自其中分布的LightDOM的树时,和/或当渲染ShadowTree时,浏览器将结果转换为所谓的composed tree。
当浏览器呈现您的代码时,内容将被分发并插入到除了实际输入的位置以外的新位置。这个分布式输出是你看到的(和浏览器看到的),并且被称为组合树。在现实中,内容不是按照现在出现的顺序输入的,但是你不会知道这一点,浏览器也不会知道。 “最终结果”和“原始代码”之间的这种分隔,如果你愿意,是封装的主要好处之一。
Web Components & the Future of CSS是一个伟大的40分钟视频Web组件,特别是ShadowDOM,ZachSaucier指出我。
特定于您的问题,:: content伪元素适用于所谓的分布式节点。分布式节点是您在< content>< / content>中放置的任何内容的另一个术语。标签。内容从原始标记中的位置分发到您放置了< content>标签。
所以,当你需要在CSS中的特殊性,一种方法,你可以处理选择器通常是你去的父元素,并添加它作为选择器的一部分。例如:如果.container {}不够具体,你可以使用div .container {}或.main .container {}来使你的选择器工作。
考虑ShadowDOM的点,它是范围和封装,你必须意识到,你创建的这个新的ShadowTree是一个全新的(离散)DOM片段。它与其他内容不在同一个“Light Realm”中;它在一个“影子领域”。那么,CSS如何知道定位这个“影子领域”?通过使用:: content伪元素!
The ::content
pseudo-element selector acts as the parent element of distributed nodes.
HTML5Rocks有很多教程here,here和here,其中涵盖更多信息并提供一些很好的示例(一定要访问Chrome或Opera,直到更多浏览器支持这些功能)。
例如,请参阅来自HTML5Rocks的此修改和改进的(通过Leo)代码的版本:
var div = document.querySelector('div'); var root = div.createShadowRoot(); var template = document.querySelector('template'); root.appendChild(template.content);
<template> <style> h3 { color: red; } content[select="h3"]::content > h3 { color: green; } ::content section p { text-decoration: underline; } </style> <h3>Shadow DOM</h3> <content select="h3"></content> <content select="section"></content> </template> <div> <h3>Light DOM</h3> <section> <div>I'm not underlined</div> <p>I'm underlined in Shadow DOM!</p> </section> </div>
也可在JSFiddle(记得访问基于WebKit的浏览器,如Chrome或Opera)
在这里你可以看到:: contentsection p伪元素首先选择ShadowRoot的内容,这是您的标记中的div元素的内容,然后通过添加节p进一步指定。
与正常的CSS选择器使用(例如,为什么不只是使用section p {}?)相比,这似乎没有必要,直到你记住,当遍历ShadowTree时,你通常不能选择主机元素的后代(分布式节点是) ,因为他们在我之前提到的“阴影领域”。