什么是:: content / :: slotted伪元素,它是如何工作的?

这对于Google来说是不可能的,因为每篇文章都谈到:before:after伪元素似乎都使用了“内容”这个词。

我在这篇 CSS-Tricks文章中听说过它,解释了如何实现图像滑块作为Web组件的示例用例。 它出现在内部的代码示例是这样的:

CSS

 #slides ::content img { width: 25%; float: left; } 

HTML

 <template> ... <div class="inner"> <content select="img"></content> </div> </template> 

它似乎是指这个<content>标记,它用于允许用户包含Web组件,但是我更想深入了解这一点。

编辑:

在进一步阅读之后,在前面的文章中,我发现了一个链接作者的“Shadow DOM CSS Cheatsheet”,其中包含一段解释::content伪元素的内容:

select元素内部的分布式节点。 需要与不支持本地select器的浏览器的polyfill-next-selector配合使用。

 ::content h1 { color: red; } 

资料来源: http : //robdodson.me/blog/2014/04/10/shadow-dom-css-cheat-sheet/

这是有帮助的,但我仍然觉得整个事情是不透明的。 任何额外的见解?

::content伪元素在将来的Web Components / Shadow DOM实现中将被replace为::slotted 。 同样,在最新版本的Shadow DOM规范中 ,此伪元素所针对的元素已从<content >更改为<slot >。 你可以在这里看到有关这个变化的相关讨论。

目前浏览器仍然支持<content>::content


原始答案:


概要:

::content从本质上来说是一种深入挖掘ShadowHost后代的ShadowHost ,通常不能用于风格化,因为你的CSS不知道在没有::content情况下寻找ShadowDOM片段。


这个答案假设您至less对<template>元素和Web组件 (特别是ShadowDOM)熟悉 ,它处理ShadowTree及其两个主要元素ShadowHostShadowRoot

注意 – 在撰写本文时,五大浏览器中对于Web组件的支持不足50%(甚至是前缀默认支持)。 虽然所有现代浏览器都支持<template> ,但只有最新版本的Chrome和Opera才支持ShadowDOM; 在Firefox的about:configdom.webcomponents.enabled )中将必要的function切换为true之后,Firefox会支持它的dom.webcomponents.enabled

使用ShadowDOM的目标类似于MVC的关注点分离 。 也就是说,我们希望将我们的内容与我们的演示文稿分开,并允许在我们的代码中封装模板,以使其更易于pipe理。 我们已经有了各种编程语言,但是在HTML和CSS中这个问题还是有一段时间了。 此外,在Web应用程序中对元素进行样式化时,可能会与类名称发生冲突。

通常情况下,我们与LightDOM (一种“Light Realm”)进行交互,但是有时利用封装会有所帮助。 进入这种“影子领域”(Web组件的一部分)是一种通过允许封装来防止上述问题的新方法。 即使使用完全相同的类或select器,在ShadowTree应用于标记的任何样式也不适用于标记。

ShadowTree (它位于ShadowDOM )中有一个来自LightDOM分布在树内的树,或者当ShadowTree被渲染时,结果被浏览器转换成所谓的组合树

当浏览器呈现您的代码时,内容将被分发并插入新的位置, 而不是物理input的位置。 这个分布式输出就是你所看到的(以及浏览器所看到的),被称为composed tree 。 实际上,内容并不是按照它现在出现的顺序input的,但是你不会知道这一点,浏览器也不会。 如果你愿意,“最终结果”和“原始代码”之间的这种分离是封装的主要优点之一。

Web组件和CSS的未来是一个伟大的40分钟的Web组件的video,特别是ShadowDOM,由ZachSaucier指出。


具体到你的问题, ::content伪元素适用于所谓的分布式节点 。 分布式节点是放在<content></content>标记中的任何一个词。 内容将从原始标记中的位置分发到您将模板中的<content>标记放置到的任何位置。

所以,当你在CSS中需要特殊性的时候,你可以正常处理select器的一种方法就是去父元素并将其作为select器的一部分join。 例如:如果.container {}不够具体,可以使用div .container {}.main .container {}来使select器工作。

考虑到ShadowDOM(这是范围和封装)的重点,你必须认识到,你创build的这个新的ShadowTree是一个全新的(离散的)DOM片段。 它和其他内容不在同一个“光之境界”中; 它在一个“阴影领域”。 那么,CSS如何知道这个“暗影领域”呢? 通过使用::content伪元素!

::content伪元素select器充当分布式节点的父元素。

HTML5Rocks 在这里有一个很好的教程序列, 这里覆盖更多的信息,并给出一些很好的例子(一定要使用Chrome或Opera访问,直到更多的浏览器支持这些function)。

例如,请参阅由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> 

太糟糕了! 不幸的是::contentv0 ,并被弃用。

你现在应该使用v1 ::slotted

此外, <content>已被弃用,以支持<slot>

请参阅: http : //hayato.io/2016/shadowdomv1/

另请参阅: Web组件 – 为什么将<内容>replace为<插槽>