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

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

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

CSS

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

超文本标示语言

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

它似乎指的是这个 <content>标记,它用于允许用户包含 Web 组件,但我希望能够更深入地理解这一点。

编辑:

在进一步阅读之后,在前面提到的文章中,我发现了作者的“ Shadow DOM CSS Cheatsheet”链接,其中包括一段解释什么是 ::content伪元素的文章:

选择元素内部的分布式节点。需要配对 对于不支持 本地选择器。

::content h1 {
color: red;
}

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

这是有帮助的,但我仍然觉得整个事件相当不透明。还有其他见解吗?

8655 次浏览

在未来的 Web 组件/Shadow DOM 实现中,::content伪元素将被 ::slotted伪元素所取代。同样,在最新版本的 Shadow DOM 规范中,这个伪元素所针对的元素已经从 <content变为 <slot > 。您可以看到关于该更改的相关讨论 给你

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


原答案:


摘要:

::content本质上是一种挖掘 ShadowHost更深层次和样式的后代的方法,这种方法通常不能用于样式化,因为您的 CSS 不知道如何在没有 ::content的情况下查找 ShadowDOM 片段。


这个答案假设您至少对 翻译: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇芳校对: 奇元素和 网络组件有所了解,特别是 编译: pestwave,它处理 ShadowTree及其两个主要元素 ShadowHostShadowRoot

注意 -截至撰写本文时,五大主要浏览器对 Web 组件的支持率不到50% (即使是前缀支持,默认情况下也是如此)。虽然所有的现代浏览器都支持 <template>,但是只有最新版本的 Chrome 和 Opera 完全支持 ShadowDOM; 只要将 about:config(dom.webcomponents.enabled)中的必要功能切换到 没错,Firefox 就会支持部分 ShadowDOM。

使用 ShadowDOM的目标类似于 MVC 的 返回文章页面关注点分离。也就是说,我们希望将内容从表示中分离出来,并允许在代码中使用封装的模板,以帮助使其更易于管理。我们已经在各种编程语言中使用了这种方法,但在 HTML 和 CSS 中仍然存在一段时间的问题。此外,在设计 Web 应用程序中的元素样式时,可能会与类名发生冲突。

通常,我们与 LightDOM(一种“光之王国”)交互,但有时利用封装会有所帮助。进入这种“阴影领域”(Web 组件的一部分)是一种新的方法,以防止上述问题的 允许封装。应用于 ShadowTree中标记的任何样式都不会应用于 ShadowTree之外的标记,即使使用了完全相同的类或选择器。

ShadowTree(存在于 ShadowDOM中)有一棵来自 LightDOM的树分布在其中,并且/或者当 ShadowTree被呈现时,结果被浏览器转换为所谓的 组合树

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

Web Component & the Future of CSS 是一个很棒的40分钟的关于 Web Component 的视频,特别是 ShadowDOM,由 ZachSaucier向我指出。


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

因此,当您需要 CSS 中的特殊性时,通常处理选择器的一种方法是转到父元素并将其作为选择器的一部分添加进来。例: 如果 .container {}不够具体,你可以使用 div .container {}.main .container {}来使你的选择器工作。

考虑 ShadowDOM 的要点,即作用域和封装,您必须意识到您创建的新 ShadowTree 是一个全新的(离散的) DOM 片段。它不是在同一个“光明王国”作为您的其余内容,它是在一个“阴影王国”。那么,CSS 是如何知道如何定位这个“阴影王国”的呢?通过使用 ::content伪元素!

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

HTML5Rocks 有一系列的教程 给你给你给你,涵盖了更多的信息,并给出了一些很好的例子(一定要使用 Chrome 或 Opera 访问,直到更多的浏览器支持这些功能)。

例如,请参阅 HTML5Rocks 代码的这个修改和改进(通过 李奥)版本:

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>

也可以在 译自: 美国《科学》杂志网站(http://JSFiddle.net/TylerH/6n946pea/1/”rel = “ noReferrer”> JSFiddle 上使用(请记住访问基于 WebKit 的浏览器,如 Chrome 或 Opera)

这里可以看到,::contentsection p伪元素是 第一选择 ShadowRoot的内容,ShadowRoot是标记中 div元素的内容,而 那么通过添加 section p进一步指定。

与正常的 CSS 选择器使用相比,这似乎没有必要(例如,为什么不只使用 section p {}?),直到您回想起来,当遍历 ShadowTree时,您通常不能选择 host元素的后代(分布式节点) ,因为它们位于我前面提到的“影子领域”中。

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

您现在应该使用 V1 ::slotted

此外,<content>也不被推崇为有利于 <slot>

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

另见: Web 组件-为什么 < content > 被替换为 < slot >