Web_Components 系列(九)—— Shadow Host 的 CSS 選擇器

css選擇器.001

前言

在上一節(jié)我們了解了如何給自定義組件設(shè)置樣式,當(dāng)時(shí)是將自定義標(biāo)簽的樣式設(shè)置在主 DOM 中的:

<style>
    my-card {
        display: block;
        margin: 20px;
        width: 200px;
        height: 200px;
        border: 3px solid #000;
    }
</style>
<my-card></my-card>

雖然實(shí)現(xiàn)了樣式設(shè)置的目的,但是卻存在一個(gè)弊端:自定義標(biāo)簽的樣式被寫(xiě)死了,不夠靈活。

如果能夠在自定義組件內(nèi)部控制自定義標(biāo)簽的樣式,那樣的話會(huì)相對(duì)靈活,而且也算是實(shí)現(xiàn)了”封裝、相互隔離“的組件原則。今天,我們就來(lái)學(xué)習(xí)一下如何在自定義組件內(nèi)部實(shí)現(xiàn)自定義標(biāo)簽的樣式控制。

在正文開(kāi)始之前,我們?cè)購(gòu)?fù)習(xí)一下 Shadow DOM 的整體結(jié)構(gòu):

image-20220209182955624

Shadow DOM 的 CSS 選擇器

今天的重點(diǎn)是認(rèn)識(shí)與 Shadow DOM 相關(guān)的幾個(gè)選擇器。

:host 偽類選擇器

選取內(nèi)部使用該部分 CSS 的 Shadow host 元素,其實(shí)也就是自定義標(biāo)簽元素。用法如下:

:host {
    display: block;
    margin: 20px;
    width: 200px;
    height: 200px;
    border: 3px solid #000;
}

注意::host 選擇器只在 Shadow DOM 中使用才有效果。

比如:

image-20220216185103096

另外,可以使用 :host 子選擇器 的形式來(lái)給 Shadow Host 的子元素設(shè)置樣式,比如:

image-20220216185355256

:host 偽類選擇器的兼容性如下:

image-20220216191419476

:host()偽類函數(shù)

:host() 的作用是獲取給定選擇器的 Shadow Host。比如下面的代碼:

<my-card class="my-card"></my-card>
<my-card></my-card>

<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});
            let styleEle = document.createElement("style");
            styleEle.textContent = `
                :host(.my-card){
                    display: block;
                    margin: 20px;
                    width: 200px;
                    height: 200px;
                    border: 3px solid #000;
                }
                :host .card-header{
                    border: 2px solid red;
                    padding:10px;
                    background-color: yellow;
                    font-size: 16px;
                    font-weight: bold;
                }
            `;
            this.shadow.appendChild(styleEle);


            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }

    window.customElements.define("my-card", MyCard);

</script>

:host(.my-card) 只會(huì)選擇類名為 my-card 的自定義元素, 且它后面也可以跟子選擇器來(lái)選擇自己跟節(jié)點(diǎn)下的子元素。

需要注意的是::host() 的參數(shù)是必傳的,否則選擇器函數(shù)失效,比如:

image-20220216192613676

:host() 偽類函數(shù)的兼容性如下:

image-20220216191512610

:host-context()偽類函數(shù)

用來(lái)選擇特定祖先內(nèi)部的自定義元素,祖先元素選擇器通過(guò)參數(shù)傳入。比如以下代碼:

<div id="container">
    <my-card></my-card>
</div>
<my-card></my-card>
<script>
    class MyCard extends HTMLElement {
        constructor () {
            super();
            this.shadow = this.attachShadow({mode: "open"});
            let styleEle = document.createElement("style");
            styleEle.textContent = `
                :host-context(#container){
                    display: block;
                    margin: 20px;
                    width: 200px;
                    height: 200px;
                    border: 3px solid #000;
                }
                :host .card-header{
                    border: 2px solid red;
                    padding:10px;
                    background-color: yellow;
                    font-size: 16px;
                    font-weight: bold;
                }
            `;
            this.shadow.appendChild(styleEle);


            let headerEle = document.createElement("div");
            headerEle.className = "card-header";
            headerEle.innerText = "My Card";
            this.shadow.appendChild(headerEle);
        }
    }

    window.customElements.define("my-card", MyCard);

</script>

:host-context(#container) 只會(huì)對(duì) id 為 container 元素下的自定義元素生效,效果如下:

image-20220216193941726

注意:這里的參數(shù)也是必傳的,否則整個(gè)選擇器函數(shù)不生效。

其兼容性如下:

image-20220216200336292

:host:host()共存的必要性

看完上面的介紹后,不少人可能會(huì)有這樣一個(gè)疑惑::host(.my-card){} 不是可以直接用 :host.my-card{} 代替?

答案是不可以?。?!,因?yàn)椋?code>:host.my-card 實(shí)質(zhì)上的意思是找 .my-card (Shadow root)的 :host(Shadow Host) ,這 Shadow DOM 的從結(jié)構(gòu)上來(lái)說(shuō)就已經(jīng)互相矛盾了。

總結(jié)

以上就是關(guān)于 Shadow Host 的 CSS 選擇器內(nèi)容,總結(jié)一下:

  • :host 范圍最大,匹配所有的自定義元素實(shí)例;
  • :host() 只選擇自身包含特定選擇器的自定義元素;
  • :host-context() 選擇擁有特定選擇器父元素的自定義元素。

~

~ 本文完,感謝閱讀!

~

學(xué)習(xí)有趣的知識(shí),結(jié)識(shí)有趣的朋友,塑造有趣的靈魂!

大家好,我是〖編程三昧〗的作者 隱逸王,我的公眾號(hào)是『編程三昧』,歡迎關(guān)注,希望大家多多指教!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容