[英]What is the ::content/::slotted pseudo-element and how does it work?
這對谷歌來說是不可能的,因為每篇談論: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/
這很有幫助,但我仍然發現整個事件相當不透明。 任何額外的見解?
::content
偽元素在 Web 組件/Shadow DOM 的未來實現中被替換為::slotted
偽元素。 同樣,此偽元素所針對的元素在最新版本的Shadow DOM 規范中已從<content
更改為<slot
> 。 您可以在此處查看有關該更改的相關討論。
目前瀏覽器仍然支持<content>
和::content
。
概括:
::content
本質上是一種深入挖掘和設置ShadowHost
后代樣式的方法,這些后代通常無法設置樣式,因為您的 CSS 不知道在沒有::content
的情況下查找 ShadowDOM 片段。
這個答案假設您至少對<template>
元素和Web Components有所熟悉,特別是ShadowDOM ,它處理ShadowTree
及其兩個主要元素ShadowHost
和ShadowRoot
。
注意- 在撰寫本文時,五種主要瀏覽器對 Web 組件的支持不到 50%(即使是帶前綴的、默認關閉的支持)。 雖然所有現代瀏覽器都支持<template>
,但只有最新版本的 Chrome 和 Opera 完全支持 ShadowDOM; 在將about:config
( dom.webcomponents.enabled
) 中的必要功能切換為true后,Firefox 支持其中的部分功能。
使用ShadowDOM
的目標類似於 MVC 的關注點分離。 也就是說,我們希望將內容與表示分離,並允許在我們的代碼中封裝模板以幫助使其更易於管理。 我們已經在各種編程語言中實現了這一點,但在 HTML 和 CSS 中它仍然是一個問題一段時間。 此外,在 Web 應用程序中設置元素樣式時,可能會與類名發生沖突。
通常,我們與LightDOM
(一種“Light Realm”)進行交互,但有時利用封裝會有所幫助。 進入這種“Shadow Realm”(Web Components 的一部分)是一種通過允許封裝來防止上述問題的新方法。 任何應用於ShadowTree
ShadowTree
的標記,即使使用完全相同的類或選擇器也是如此。
當ShadowTree
(位於ShadowDOM
中)有來自LightDOM
的樹分布在其中時,和/或當ShadowTree
被渲染時,瀏覽器會將結果轉換為所謂的組合樹。
當瀏覽器呈現您的代碼時,內容將被分發並插入到新位置,而不是實際鍵入的位置。 這個分布式輸出就是你看到的(和瀏覽器看到的),被稱為composed tree
。 實際上,內容最初並不是按照現在出現的順序輸入的,但是您不會知道這一點,瀏覽器也不會。 如果願意的話,“最終結果”和“原始代碼”之間的這種分離是封裝的主要好處之一。
Web Components & the Future of CSS是一個 40 分鍾的關於 Web 組件的精彩視頻,特別是關於 ShadowDOM,由ZachSaucier向我指出。
具體到您的問題, ::content
偽元素適用於所謂的分布式節點。 分布式節點是您放置在<content></content>
標記中的任何內容的另一個術語。 內容從其在原始標記中的位置分發到您在模板中放置<content>
標記的任何位置。
因此,當您需要 CSS 中的特定性時,通常可以處理選擇器的一種方法是轉到父元素並將其添加為選擇器的一部分。 例如:如果.container {}
不夠具體,您可以使用div .container {}
或.main .container {}
來使您的選擇器工作。
考慮到 ShadowDOM 的意義,即作用域和封裝,您必須意識到您創建的這個新 ShadowTree 是一個全新的(離散的)DOM 片段。 它與您的其他內容不在同一個“光域”中; 它在“影界”中。 那么,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)
在這里您可以看到::content
section p
偽元素首先選擇ShadowRoot
的內容,即標記中div
元素的內容,然后通過添加section p
進一步指定。
與正常的 CSS 選擇器使用相比,這似乎是不必要的(例如,為什么不只使用section p {}
?),直到您回想一下,在遍歷ShadowTree
時,您通常不能選擇host
元素的后代(哪些分布式節點是) ,因為他們在我之前提到的“影界”之中。
太糟糕了! 不幸的是::content
是v0 ,並且已被棄用。
您現在應該使用v1 ::slotted
。
此外, <content>
已被棄用,取而代之的是<slot>
。
請參閱: https ://hayato.io/2016/shadowdomv1/
有一個很長的答案解釋 :slotted on StackOverflow。
自 2020 年 5 月發布以來,已獲得 38 票贊成
請參閱: ::slotted CSS 選擇器用於 shadowDOM 插槽中的嵌套子項
我的建議是,刪除這個 SO 問題,這樣新的搜索就不會出現在 Web Components V0 答案的非常老的問題中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.