Web_Components 系列(九)—— Shadow Host 的 CSS 选择器

简介: 在上一节我们了解了如何给自定义组件设置样式,当时是将自定义标签的样式设置在主 DOM 中的:

8.png


前言


在上一节我们了解了如何给自定义组件设置样式,当时是将自定义标签的样式设置在主 DOM 中的:


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


虽然实现了样式设置的目的,但是却存在一个弊端:自定义标签的样式被写死了,不够灵活。


如果能够在自定义组件内部控制自定义标签的样式,那样的话会相对灵活,而且也算是实现了”封装、相互隔离“的组件原则。今天,我们就来学习一下如何在自定义组件内部实现自定义标签的样式控制。


在正文开始之前,我们再复习一下 Shadow DOM 的整体结构:


7.png


Shadow DOM 的 CSS 选择器


今天的重点是认识与 Shadow DOM 相关的几个选择器。


:host 伪类选择器


选取内部使用该部分 CSS 的 Shadow host 元素,其实也就是自定义标签元素。用法如下:


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


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


比如:


6.png


另外,可以使用 :host 子选择器 的形式来给 Shadow Host 的子元素设置样式,比如:


5.png


:host 伪类选择器的兼容性如下:


4.png


:host()伪类函数


: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) 只会选择类名为 my-card 的自定义元素, 且它后面也可以跟子选择器来选择自己跟节点下的子元素。


需要注意的是::host() 的参数是必传的,否则选择器函数失效,比如:


3.png


:host() 伪类函数的兼容性如下:


2.png


:host-context()伪类函数


用来选择特定祖先内部的自定义元素,祖先元素选择器通过参数传入。比如以下代码:


<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) 只会对 id 为 container 元素下的自定义元素生效,效果如下:


1.png


注意:这里的参数也是必传的,否则整个选择器函数不生效。


其兼容性如下:


0.png


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


看完上面的介绍后,不少人可能会有这样一个疑惑::host(.my-card){} 不是可以直接用 :host.my-card{} 代替?


答案是不可以!!!,因为::host.my-card  实质上的意思是找 .my-card (Shadow root)的 :host(Shadow Host) ,这 Shadow DOM 的从结构上来说就已经互相矛盾了。


总结


以上就是关于 Shadow Host 的 CSS 选择器内容,总结一下:


  • :host 范围最大,匹配所有的自定义元素实例;
  • :host() 只选择自身包含特定选择器的自定义元素;
  • :host-context() 选择拥有特定选择器父元素的自定义元素。


~ 本文完,感谢阅读!


学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!




相关文章
|
2月前
|
前端开发
CSS:高级选择器
CSS:高级选择器
44 1
|
2月前
|
前端开发 JavaScript
CSS:基础选择器
CSS:基础选择器
49 1
|
2月前
|
前端开发
【前端web入门第四天】02 CSS三大特性+背景图
本文详细介绍了CSS的三大特性:继承性、层叠性和优先级,并深入讲解了背景图的相关属性,包括背景属性、背景图的平铺方式、位置设定、缩放、固定以及复合属性。其中,继承性指子元素自动继承父元素的文字控制属性;层叠性指相同属性后定义覆盖前定义,不同属性可叠加;优先级涉及选择器权重,包括行内样式、ID选择器等。背景图部分则通过具体示例展示了如何设置背景图像的位置、大小及固定方式等。
259 91
|
27天前
|
前端开发 JavaScript UED
深入理解与应用 CSS 伪类选择器
【10月更文挑战第23天】通过以上对 CSS 伪类选择器的深入探讨,我们可以更好地理解和应用它们,为网页设计和开发带来更丰富、更灵活的样式效果。同时,要注意在实际应用中根据具体情况合理选择和使用伪类选择器,以达到最佳的设计效果和用户体验。
33 2
|
1月前
|
存储 前端开发 安全
详解CSS之Web 字体
详解CSS之Web 字体
27 4
|
2月前
|
前端开发
【前端web入门第三天】02 CSS字体和文本
本文详细介绍了CSS中字体和文本的相关属性。字体部分涵盖字体大小、粗细、样式、行高、字体族及`font`复合属性,通过具体示例展示了如何设置和使用这些属性。文本部分则讲解了文本缩进、对齐方式、修饰线及文字颜色等属性,并提供了实用的代码示例。此外,还简要介绍了调试工具中的一些细节,如错误属性标识和属性生效状态的控制。
68 28
|
2月前
|
前端开发 JavaScript 容器
谁动了我的选择器?深入理解CSS选择器优先级
该文章详细解释了CSS选择器的工作原理,包括不同种类选择器的权重计算规则,并通过实例说明了如何解决样式冲突问题,确保所需的样式能够正确应用到目标元素上。
|
2月前
|
缓存 安全 应用服务中间件
Web安全-HTTP Host头攻击
Web安全-HTTP Host头攻击
140 7
|
2月前
|
前端开发
前端基础(四)_CSS层叠样式表_什么是css_css样式的引入方式_样式表的优先级_样式选择器
本文详细介绍了CSS(层叠样式表)的基本概念、语法规则、引入方式、样式表的优先级和样式选择器。文章解释了CSS的作用,展示了如何在HTML中通过行内样式、内部样式和外部样式引入CSS,讨论了不同CSS选择器的优先级和如何确定最终的样式应用。此外,还强调了使用`!important`规则时的优先级高于行内样式。
89 1
|
2月前
|
缓存 安全 应用服务中间件
Web安全-HTTP Host头攻击
Web安全-HTTP Host头攻击
174 3
下一篇
无影云桌面