What is the ::content/::slotted pseudo-element and how does it work?(什么是 ::content/::slotted 伪元素,它是如何工作的?)
问题描述
这对 Google 来说是不可能的,因为每篇关于 :before
和 :after
伪元素的文章似乎都使用了内容"一词.
This is impossible to Google for because every article talking about the :before
and :after
pseudo-elements seems to use the word 'content'.
我在 这篇 CSS-Tricks 文章中听说过它,解释了如何将图像滑块实现为 Web 组件的示例用例.它出现在里面的代码示例是这样的:
I heard about it in this CSS-Tricks article, explaining how to implement an image slider as an example use-case for web components. The code example it appears inside is thus:
CSS
#slides ::content img {
width: 25%;
float: left;
}
HTML
<template>
...
<div class="inner">
<content select="img"></content>
</div>
</template>
似乎指的是这个<content>
标签,它是用来让用户包含Web Components的,但我很想更深入地理解这一点.
It seems to be referring to this <content>
tag, which is used to allow the user to include Web Components, but I would love to understand this more deeply.
进一步阅读后,在上述文章中,我发现了作者的Shadow DOM CSS Cheatsheet"链接,其中包含一段解释 ::content
伪元素是什么的段落:
After reading further, in the aforementioned article, I discovered a link the author's "Shadow DOM CSS Cheatsheet" which includes a passage that explains what the ::content
pseudo-element is:
选择元素内部的分布式节点.需要配对对于不支持的浏览器,使用 polyfill-next-selector本机选择器.
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/
这很有帮助,但我仍然觉得整个事件相当不透明.还有其他见解吗?
This is helpful, but I still find the whole affair rather opaque. Any additional insights?
推荐答案
::content
伪元素在 Web 组件/Shadow DOM 的未来实现中将被替换为 ::开槽
伪元素.同样,此伪元素所针对的元素已从
The ::content
pseudo-element is being replaced in future implementations of Web Components / Shadow DOM with the ::slotted
pseudo-element. Likewise, the element targeted by this pseudo-element has changed from <content
to <slot
> in the latest version of the Shadow DOM specification. You can see related discussion about that change here.
目前浏览器仍支持 <content>
和 ::content
.
Currently browsers still support <content>
and ::content
.
总结:
::content
本质上是一种深入挖掘 ShadowHost
后代并设置样式的方法,这些后代通常无法设置样式,因为您的 CSS 没有知道寻找没有 ::content
的 ShadowDOM 片段.
::content
is essentially a way to dig deeper and style descendants of the ShadowHost
, which normally aren't available to be styled, because your CSS doesn't know to look for the ShadowDOM fragment without ::content
.
此答案假定您至少对 <template>
元素和 Web 组件,特别是 ShadowDOM,它处理 ShadowTree
及其两个主要元素 ShadowHost
和 ShadowRoot
.
This answer assumes you are at least somewhat familiar with the <template>
element and Web Components, specifically the ShadowDOM, which deals with ShadowTree
s and their two main elements, ShadowHost
and ShadowRoot
.
注意 - 在撰写本文时,五种主要浏览器对 Web 组件的支持不到 50%(即使是带前缀的、默认关闭的支持).虽然所有现代浏览器都支持 <template>
,但只有最新版本的 Chrome 和 Opera 完全支持 ShadowDOM;将 about:config
(dom.webcomponents.enabled
) 中的必要功能切换为 true 后,Firefox 支持其中的部分功能.
Note - As of this writing, there is less than 50% support (even prefixed, off-by-default support) for Web Components across the five major browsers. While all modern browsers support <template>
, only recent versions of Chrome and Opera support the ShadowDOM fully; with Firefox supporting parts of it after you toggle the requisite feature in about:config
(dom.webcomponents.enabled
) to true.
使用 ShadowDOM
的目的类似于 MVC 的 分离担忧.也就是说,我们希望将内容与表示分离,并允许在我们的代码中封装模板以帮助使其更易于管理.我们已经在各种编程语言中实现了这一点,但在 HTML 和 CSS 中它仍然是一个问题一段时间.此外,在 Web 应用中设置元素样式时,可能会与类名发生冲突.
The goal of using the ShadowDOM
is similar to MVC's separation of concerns. That is, we want to separate our content from our presentation and allow for encapsulated templates in our code to help make it more manageable. We have this already in various programming languages, but it's remained a problem for some time in HTML and CSS. Further, there can be conflicts with class names when styling elements in web apps.
通常,我们与 LightDOM
(一种Light Realm")进行交互,但有时利用封装会有所帮助.闯入这种影界"(Web Components 的一部分)是一种通过允许封装来防止上述问题的新方法.应用于 ShadowTree
中标记的任何样式都不会应用于 ShadowTree
之外的标记,即使使用完全相同的类或选择器也是如此.
Normally, we interact with the LightDOM
(a sort of "Light Realm"), but sometimes it would be helpful to take advantage of encapsulation. Crossing into this sort of "Shadow Realm" (part of Web Components) is a new method to prevent the problems mentioned above by allowing encapsulation. Any styles applied to markup in your ShadowTree
won't apply to markup outside of your ShadowTree
, even if the exact same classes or selectors are used.
当 ShadowTree
(位于 ShadowDOM
中)有来自 LightDOM
的树分布在其中,和/或当 ShadowTree
被渲染,结果被浏览器转换成所谓的 合成树.
When the ShadowTree
(which lives in the ShadowDOM
) has a tree from the LightDOM
distributed within it, and/or when the ShadowTree
is rendered, the result is converted by the browser into what is called a composed tree.
当浏览器呈现您的代码时,内容将被分发并插入到新的位置而不是实际输入的位置.这个分布式输出就是你看到的(和浏览器看到的),被称为composed tree
.实际上,内容最初并不是按照现在出现的顺序输入的,但是您不会知道这一点,浏览器也不会.最终结果"和最终结果"之间的这种分离.如果您愿意,原始代码"是封装的主要好处之一.
When the browser renders your code, content is being distributed and inserted at new locations other than where it was physically typed. This distributed output is what you see (and what the browser sees), and is called the composed tree
. In reality, the content is not originally typed in the order that it now appears, but you won't know this, and neither will the browser. This separation between "end result" and "original code", if you will, is one of the main benefits of encapsulation.
Web 组件 & 是一个 40 分钟的关于 Web 组件,特别是 ShadowDOM 的精彩视频-saucier">ZachSaucier.
针对您的问题,::content
伪元素适用于所谓的分布式节点.分布式节点是您在 <content></content>
标记中放置的任何内容的另一个术语.内容从原始标记中的位置分发到您在模板中放置 <content>
标记的任何位置.
Specific to your question, the ::content
pseudo element applies to what are called distributed nodes. A distributed node is another term for whatever you put within the <content></content>
tags. The content is distributed from its place in the original markup to wherever you have placed your <content>
tags in the template.
因此,当您需要 CSS 中的特定性时,通常可以处理选择器的一种方法是转到父元素并将其添加为选择器的一部分.例如:如果 .container {}
不够具体,您可以按顺序使用 div .container {}
或 .main .container {}
使您的选择器工作.
So, when you need specificity in CSS, one way you can handle selectors normally is that you go to the parent element and add that in as part of the selector. Ex: if .container {}
is not specific enough, you might use div .container {}
or .main .container {}
in order to make your selector work.
考虑到ShadowDOM 的要点,即作用域和封装,您必须意识到您创建的这个新ShadowTree 是一个全新的(离散的)DOM 片段.不在同一个光界"作为您的其余内容;它在影界"中.那么,CSS 是如何知道以这个影子领域"为目标的呢?通过使用 ::content
伪元素!
Thinking about the point of the ShadowDOM, which is scoping and encapsulation, you have to realize that this new ShadowTree you've created is a completely new (discrete) DOM fragment. It's not in the same "Light Realm" as the rest of your content; it's in a "Shadow Realm". So, how does the CSS know to target this "Shadow Realm"? By using the ::content
pseudo-element!
HTML5Rocks 有很多教程这里, 这里和 here 其中包含更多信息并提供了一些很好的示例(请务必使用 Chrome 或 Opera 访问,直到更多浏览器支持这些功能).p>
例如,查看 HTML5Rocks 中代码的修改和改进(由 Leo 编写)版本:
HTML5Rocks has a great sequence of tutorials here, here, and here which cover more information and give some great examples (be sure to visit with Chrome or Opera until more browsers support these features).
<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)
Also available on JSFiddle (Remember to visit in a WebKit-based browser like Chrome or Opera)
这里可以看到::content
section p
伪元素first选择了ShadowRoot
,它是标记中 div
元素的内容,then 通过添加 section p
.
Here you can see that the ::content
section p
pseudo element is first selecting the content of the ShadowRoot
, which is the contents of the div
element in your markup, and then specifying further by adding section p
.
与正常的 CSS 选择器使用相比,这似乎是不必要的(例如,为什么不只使用 section p {}
?),直到你回想一下,当遍历 ShadowTree
,您通常不能选择 host
元素的后代(分布式节点),因为它们位于Shadow Realm"中.我之前提到过.
This may seem unnecessary when compared to normal CSS selector usage (for example, why not just use section p {}
?), until you recall that, when traversing a ShadowTree
, you cannot normally select descendants of host
elements (which distributed nodes are), because they are in the "Shadow Realm" I mentioned earlier.
这篇关于什么是 ::content/::slotted 伪元素,它是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:什么是 ::content/::slotted 伪元素,它是如何工作的
基础教程推荐
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 直接将值设置为滑块 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01