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


74

对于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伪元素的段落:

选择元素内部的分布式节点。对于不支持本机选择器的浏览器,需要与polyfill-next-selector配对。

::content h1 {
    color: red;
}

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

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


5
规范可能会提供其他见解。
Paulie_D 2014年

1
@Paulie_D刚刚看到了备忘单(在上面添加了一个有问题的链接)-谢谢!但仍不清楚整个概念。什么是分布式节点?
2014年

4
更多阅读-这里
Paulie_D 2014年

2
::content已重命名为::slotted
Oriol,2016年

谢谢Oriol。@jon我已经更新了我的答案以反映这一点。一旦浏览器转移到支持slotslotted,我会代替提到的content::content,可能更新的问题,以及使其对未来的读者仍然有用!
TylerH's

Answers:


109

所述::content伪元素被替换与所述Web组件/阴影DOM的未来实现::slotted伪元素。同样,在最新版本的Shadow DOM规范中,此伪元素所针对的元素已从更改<content<slot> 。您可以在此处查看有关该更改的相关讨论。

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


原始答案:


概要:

::content本质上是一种挖掘的更深的样式和样式的后代的方法ShadowHost,通常无法设置样式的后代,因为CSS不知道是否要寻找ShadowDOM片段::content


该答案假定您至少对<template>元素和Web组件有所了解,尤其是ShadowDOM,它处理ShadowTrees及其两个主要元素,ShadowHost以及ShadowRoot

注意-撰写本文时,五种主要浏览器对Web组件的支持不足50%(甚至是带前缀的默认关闭支持)。尽管所有现代浏览器都支持<template>,但只有Chrome和Opera的最新版本才完全支持ShadowDOM。将about:configdom.webcomponents.enabled)中的必需功能切换为true后,Firefox支持它的部分功能。

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

通常,我们与LightDOM(一种“ Light Realm”)互动,但有时利用封装会有所帮助。跨入此类“影子领域”(Web组件的一部分)是一种通过允许封装来防止上述问题的新方法。即使ShadowTreeShadowTree使用完全相同的类或选择器,应用于您内部标记的任何样式也不会应用于您外部的标记。

ShadowTree(驻留在中ShadowDOM)具有来自其LightDOM内部分布的树时,和/或ShadowTree呈现时,浏览器将结果转换为所谓的组合树

当浏览器呈现您的代码时,内容将被分发并插入到新位置,而不是实际键入的位置。分布式输出就是您所看到的(以及浏览器所看到的),称为composed tree。实际上,最初并不是按现在出现的顺序键入内容,但是您不会知道,浏览器也不会。如果需要的话,“最终结果”和“原始代码”之间的分隔是封装的主要好处之一。

Web组件和CSS的未来是在Web组件一个伟大的40分钟的视频并专门ShadowDOM,通过向我指出ZachSaucier


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

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

考虑到ShadowDOM的作用域(即范围和封装),您必须意识到,您创建的这个ShadowTree是一个全新的(离散的)DOM片段。它与其余内容不在同一个“ Light Realm”中;它在“影子领域”中。那么,CSS如何知道以“影子领域”为目标?通过使用::content伪元素!

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

HTML5Rocks在此处此处此处都有大量的教程,这些教程涵盖了更多信息并给出了一些出色的示例(请确保使用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 pShadowRootdivsection p

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


11
这是一个了不起的答案。非常感谢您抽出宝贵的时间来编写它!
2014年

1
@jon不客气!很高兴您发现它有用。如果您仍在寻找信息,那么还有HTML5Rocks撰写的第3篇教程
TylerH 2014年

2
不建议使用反斜杠转义的换行符,因为它不是ECMAScript
Juan Mendes

4
@JuanMendes从我现在阅读的内容来看,“ \后面的新行不是字符转义序列,而是LineContinuation。新行不会成为字符串的一部分。这只是散布多行上的字符串(例如,为便于代码编辑)[..]“ Source。显然,这根本不是擒纵机构。
TylerH 2014年

1
仅供参考:有关Web Compontents进一步阅读您可以访问幻灯片(“称为Web组件创未来”),这是在接待趋势2014芝诺罗恰(在谷歌开发者专家计划的成员)提出- vimeo.com/97308701
米哈尔Kutra

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.