2

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

 2 years ago
source link: https://xie.infoq.cn/article/ebd09cc815e479a03e04fc494
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

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

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

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

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 中使用才有效果。

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

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

: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() 的参数是必传的,否则选择器函数失效,比如:

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

: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 元素下的自定义元素生效,效果如下:

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

其兼容性如下:

: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() 选择拥有特定选择器父元素的自定义元素。

~ 本文完,感谢阅读!

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

大家好,我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!


Recommend

  • 54
    • www.w3cplus.com 5 years ago
    • Cache

    初探CSS 选择器Level 4

    在开始聊CSS选择器Level 4( Selectors Level 4 )之前,先要明确一个简单的概念。时至今日,在CSS的世界之中再不会有大版本的称谓,比如以前大家熟悉的CSS2.1、CSS3。现在的CSS都只会...

  • 33
    • www.cnblogs.com 4 years ago
    • Cache

    css常用选择器

    上次给大家简单介绍了html与css的基本组成部分,这一期给大家介绍下css的选择器吧! 先给大家讲几种比较常用的吧。第一种基础选择器,类选择器,它的书写方式为.加上类名,类名是自定义的,写类名最好是见名知意,给大家举一个例子吧...

  • 9
    • www.zhangxinxu.com 3 years ago
    • Cache

    关于《CSS选择器世界》这本书

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9002 本文可全文转载,无需授权。 一、只缘身在此山中 小时候,...

  • 11
    • www.zhangxinxu.com 3 years ago
    • Cache

    简单聊聊CSS选择器中的正则表达式

    by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5542 本文全文转载需购买版权(500¥),摘要引流则免费,具体

  • 3
    • www.zoo.team 3 years ago
    • Cache

    深入解析 CSS 选择器

    文章目录 深入解析 CSS 选择器二、CSS 选择器的分类三、不同种类选择器的用法属性选择器伪类选择器伪元素选择器

  • 6
    • toweave.github.io 3 years ago
    • Cache

    CSS Selector 选择器

    CSS Selector 选择器Tuesday, April 2nd 2019, 10:15:53 am ( ISO 8601 )了解并且熟用 CSS3 为我们提供的强大并且优雅的选择器,就可以简化我们的代码。 ** 一、基本选择器 ** A. 通配选择器 「*」

  • 7

    2 年前20 分钟 读完 (大约 2928 个字) 50次访问【译】一张图搞定CSS选择器知识

  • 5
    • www.zhangxinxu.com 3 years ago
    • Cache

    如何在CSS中实现父选择器效果?

    by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5559 本文全文转载需购买版权(500¥),摘要引流则免费,具体

  • 13
    • kai666666.com 3 years ago
    • Cache

    《CSS选择器世界》读书笔记

    你敢相信吗,CSS选择器都可以写一本书!张鑫旭大佬的这本书绝对值得一读! CSS选择器可分为4类:选择器(如body{})、选择符(如相邻兄弟关系选择符+)、伪类(如:hover)和伪元素(如::before)。 CSS只有一个全局作用域,但是Shadow DOM...

  • 4
    • segmentfault.com 2 years ago
    • Cache

    [Web Components]2. 使用shadow dom

    [Web Components]2. 使用shadow dom发布于 58 分钟前1. 为什么用 shadow dom使用shadom dom可以让组件与其他组件、组件与dom树进行隔离,实现封装。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK