什么是:: content / :: slotted伪元素,它是如何工作的? [英] What is the ::content/::slotted pseudo-element and how does it work?

查看:95
本文介绍了什么是:: content / :: slotted伪元素,它是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Google来说这是不可能的,因为每篇讨论之前<:code>和:伪元素之后的文章似乎都是使用内容一词。



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

CSS

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

HTML $ b

 < 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/



这很有帮助,但我仍然发现整件事情都不透明。任何额外的见解?

解决方案

:: content 伪元素是在未来的Web Components / Shadow DOM实现中用 :: slotted 替换。同样,这个伪元素所瞄准的元素已经从最近的< content< / code>变成了< code>< slot<版本的 Shadow DOM规范此处可以查看有关此更改的相关讨论。



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






原始答案:






总结:

:: content 本质上是一种深入挖掘 ShadowHost 的风格后代的方式,通常不可用风格,因为您的CSS不知道要查找没有 :: content 的ShadowDOM片段。






至少对 < template> 元素和 Web组件 a> ,特别是 影子代码 ,它处理 ShadowTree s及其两个主要元素, ShadowHost ShadowRoot



注意 - 撰写本文时,五大浏览器中Web组件的支持不到50%(甚至是前缀默认支持)。虽然所有现代浏览器都支持< template> ,但只有最新版本的Chrome和Opera支持ShadowDOM;在您将 about:config dom.webcomponents.enabled )中的必要功能切换为的即可。

使用 ShadowDOM 的目标类似于MVC的 关注点分离 。也就是说,我们希望将我们的内容与我们的演示文稿分开,并允许在我们的代码中封装模板,以使其更易于管理。我们已经在各种编程语言中使用它,但在HTML和CSS中它仍然存在一段时间的问题。此外,在Web应用程序中设置元素样式时,可能会与类名称发生冲突。通常,我们与 LightDOM (一种Light Realm)进行交互,但有时它会是有助于利用封装。进入这种影子领域(Web组件的一部分)是一种通过允许封装来防止上述问题的新方法。在 ShadowTree 中应用于标记的任何样式都不适用于 ShadowTree 之外的标记,即使完全相同使用类或选择器。
$ b ShadowTree (位于 ShadowDOM )有一个来自其中的 LightDOM 的树,和/或当 ShadowTree 被渲染时,结果被转换通过浏览器进入所谓的 组合树 即可。



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

Web Components& CSS的未来 是一个伟大的40分钟的Web组件视频,特别是ShadowDOM,由 ZachSaucier






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



所以,当你需要CSS的特异性时,你可以正常处理选择器的一种方法是,你转到父元素并将其作为选择器的一部分加入。例如:如果 .container {} 不够详细,您可以使用 div .container {} 以使您的选择器工作。



考虑ShadowDOM的重点和封装,你必须认识到你创建的这个新的ShadowTree是一个全新的(离散的)DOM片段。它与您的其他内容不在同一个Light领域中;它在一个阴影领域。那么,CSS如何知道瞄准这个影子领域?通过使用 :: content 伪元素!



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



HTML5Rocks有一系列教程此处 here 这里包含更多信息并提供一些很好的示例(请确保访问Chrome或Opera,直到更多浏览器支持这些功能)。



例如,请参阅此修改和改进(通过 Leo )版本来自HTML5Rocks的代码:

 < template> <风格> h3 {颜色:红色; } 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> <节> < div>我没有加下划线< / div> < p>我在Shadow DOM中加下划线!< / p> < / section>< / div>  



也可在 JSFiddle (请记住在基于WebKit的浏览器中访问,例如Chrome或Opera)



在这里您可以看到 :: content section p 伪元素是 first 选择 ShadowRoot 的内容,这是 div 元素,然后然后通过添加 section p 进一步指定。



与普通的CSS选择器用法相比,这可能看起来没有必要(例如,为什么不使用部分p {} ?),直到你回想起,当遍历 ShadowTree 时,你通常不能选择 host 元素的后代(其中分布式节点),因为它们在前面提到的影子领域中。

This is impossible to Google for because every article talking about the :before and :after pseudo-elements seems to use the word 'content'.

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>

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.

EDIT:

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:

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;
}

Source: 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?

解决方案

The ::content pseudo-element is being replaced in future implementations of Web Components / Shadow DOM with the ::slotted. 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.

Currently browsers still support <content> and ::content.


Original answer:


Summary:

::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.


This answer assumes you are at least somewhat familiar with the <template> element and Web Components, specifically the ShadowDOM, which deals with ShadowTrees and their two main elements, ShadowHost and ShadowRoot.

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.

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.

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.

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.

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 Components & the Future of CSS is a great 40-minute video on Web Components and specifically the ShadowDOM, pointed out to me by ZachSaucier.


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.

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.

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!

The ::content pseudo-element selector acts as the parent element of distributed nodes.

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).

For example, see this modified and improved (by Leo) version of the code from 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>

Also available on JSFiddle (Remember to visit in a WebKit-based browser like Chrome or Opera)

Here you can see that the ::contentsection 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.

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伪元素,它是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆