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

2023-11-05

css选择器.001

前言

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

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

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

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

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

image-20220209182955624

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

比如:

image-20220216185103096

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

image-20220216185355256

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

image-20220216191419476

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

image-20220216192613676

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

image-20220216191512610

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

image-20220216193941726

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

其兼容性如下:

image-20220216200336292

: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() 选择拥有特定选择器父元素的自定义元素。
~
本文完,感谢阅读!

~

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Web_Components 系列(九)—— Shadow Host 的 CSS 选择器 的相关文章

  • 如何按单个整数字段对 JSON 进行排序? [复制]

    这个问题在这里已经有答案了 我有以下 JSON title title order 0 order 9 order 2 JSON 包含很多字段 我如何根据字段对它们进行排序order field 我一直在寻找 Nodejs 中内置的东西 但
  • JQuery 可排序嵌套可排序 div

    这个问题与这个有关Nest jQuery UI 可排序 https stackoverflow com questions 19129476 nest jquery ui sortables 但我无法解决我的问题 问题是 我有一个包含项目的
  • 如何在WebBrowser控件中注入Javascript?

    我试过这个 string newScript textBox1 Text HtmlElement head browserCtrl Document GetElementsByTagName head 0 HtmlElement scrip
  • Hydrate with RTK Query 确实会抛出错误

    我有一个非常简单的组件来显示来自本地 API 的数据 使用 Nextjs API 路由制作 我使用 RTK 查询来获取数据 const api createApi reducerPath data baseQuery fetchBaseQu
  • 设置股票数据 Highcharts xAxis 的格式

    我已经浏览了需要为 xAxis 属性设置的 Highcharts 选项来格式化时间标签 但没有运气了解这对于这种情况到底是如何工作的 我在白天 盘中 检索了股票的动态数据 我需要显示这些数据 因为检索的数据每天从 9 30 开始到 17 0
  • 在 Apache 服务器上将特定的 .htm 页面处理为 .php [重复]

    这个问题在这里已经有答案了 我正在为 Apache 服务器编程 并且只需要将一个特定的 html 页面 例如 first htm 作为 PHP 脚本进行处理 可以设置吗 SetHandler http httpd apache org do
  • 测量填写部分的时间 - 谷歌表单

    我正在尝试使用谷歌表单进行研究调查问卷 对于某些部分 我想自动测量用户填写所需的时间 谷歌表单中没有这样的选项 我尝试复制表单源 并用 javascript 填充时间 但它不起作用 跨源问题 未能成功托管复制的表单 如何做到 我如何衡量回答
  • 两个日期之间间隔 15 分钟 javascript

    问题 我需要将两个日期 时间戳之间的所有 15 分钟时隙 日期格式 2016 08 10 16 00 00 创建为 HH mm 格式的数组 其中分钟限制为 00 15 30 45 示例 中午 12 30 到下午 2 30 将 gt 12 3
  • 我将 X Y Z 坐标转换为屏幕 X Y 坐标有什么问题吗?

    我正在制作 3D 空间中弹跳的球体的 HTML5 Canvas 演示 这非常简单 每个球都有 X Y 和 Z 坐标 然后 这些坐标将转换为我在此处阅读的屏幕 X 和 Y 坐标 http answers google com answers
  • 替换打字稿中字符串中字符的所有实例?

    我正在尝试用 x 字符替换电子邮件中的所有句号 例如 电子邮件受保护 cdn cgi l email protection 将变为 myxemail emailxcom 电子邮件设置为字符串 我的问题是它不只是替换句号 而是替换每个字符 所
  • 需要根据用户选择有条件地渲染具有 X 行数的部分

    我有一个反应组件 其中包含一个下拉列表 其中的选项包括none 1 5 and 13 根据用户选择的数字 我需要渲染一个部分 其中包括许多行 每个行都有字段名称和下拉列表 如果用户不选择任何一个 我需要整个附加配置部分消失 新部分中的每个下
  • iframe 位置居中

    所以我找到了这段用于将内容放在中心的代码 但我的问题是它是为容器制作的 你知道如何为 iframe 制作它吗 或者你知道另一个代码吗 代码 center margin auto width 60 border 3px solid 73AD2
  • Skrollr 添加空白

    我已经尝试了一切 我在谷歌上阅读了 4 5 页试图找到适合我的修复程序 已经筋疲力尽了 即使我使用 skrollr 示例 我的问题仍然存在 不是说他们做错了什么 我知道我只是没有正确理解它 因此 我上传了一个演示 仅在移动设备上展示这个尴尬
  • 如何使用 HTML5 Javascript Canvas 获取三个碰撞形状的交集并删除不碰撞的部分?

    我最近专门针对 KonvaJs 发布了类似的问题here https stackoverflow com questions 64603077 how can i get the intersection of three shapes c
  • 在 Selenium WebDriver 上如何从 Span 标签获取文本

    在 Selenium Webdriver 上 如何从 span 标记检索文本并打印 我需要提取文本UPS Overnight Free HTML代码如下 div id customSelect 3 class select wrapper
  • 如何在 JSP 编辑器中激活 javascript 的语法着色 - Eclipse

    在某些情况下 javascript 确实必须位于 JSP 页面中 而不是位于单独的文件中 有些框架还使用Javascript做一些事情 以便用户将其包含到JSP标签中 这样JS就不会出现在
  • 在 Javascript 中创建数组

    我对 javascript 不太熟悉 并且在用 javascript 制作 2d 或者也许我可能需要 3d 数组时遇到了一些麻烦 我目前需要收集 2 条信息 一个 ID 和一个值 因此我创建了以下内容 var myArray var id
  • 右列固定的 Div 表

    我最近接手了一个非营利网站作为一个项目 我正在使用一个现有的网站 所以我必须使用很多已经编程的东西 所以我所要做的就是创建设计 I made a diagram of basically what I can t figure out ho
  • 如何设置javascript对象数组中所有对象的特定属性值(lodash)

    我有以下对象数组 var arr id a1 guid sdfsfd value abc status active id a2 guid sdfsfd value def status inactive id a2 guid sdfsfd
  • 快速响应的交互式图表/图形:SVG、Canvas 还是其他?

    我正在尝试选择正确的技术来更新一个项目 该项目基本上在可缩放 可平移的图表中渲染数千个点 当前使用 Protovis 的实现性能不佳 在这里查看 http www planethunters org classify http www pl

随机推荐

  • linux下C语言修改文件权限

    头文件
  • Java 统计文本文件中字符数量

    设有一个文本文件word01 txt 内容如下 after a minute or two and said to his friend he opened them again a minute or two and said to fr
  • 【数据结构——树】Trie树的两种实现方式:二叉树(左孩子右兄弟)与二十六叉树

    输入 输入的第一行为一个正整数n 表示词典的大小 其后n行 每一行一个单词 不保证是英文单词 也有可能是火星文单词哦 单词由不超过10个的小写英文字母组成 可能存在相同的单词 此时应将其视作不同的单词 接下来的一行为一个正整数m 表示询问的
  • c++实现哈夫曼huffman压缩文本

    哈夫曼压缩原理就是构建二叉树 出现频率高的字母用更少的位数来表示 实现压缩的效果 比如字符串abcbbc 构建哈夫曼树 这样构建出编码表b gt 0 a gt 10 c gt 11 原本6个字符要48位来表示 现在只需要9位来表示即可 1
  • FairyGui简单介绍

    1 什么是FairyGui 跨平台UI编辑器 支持多种项目 如Unity Cocos2dx CryEngine HavokVision Starling Egret LayaAir Haxe Pixi LibGDX and More 2 a
  • 视频号的播放量和互动率、完播率密不可分

    如何提高视频号播放量 视频号是推荐机制 分两种 社交推荐 朋友给你点赞 我未关注也可能刷到你 和平台推荐 提高系统推荐的两个指标和一个逻辑 两个指标 互动率和完播率 1 互动率 互动率是指互动次数占总播放量的比重 包含 点赞率 评论率 转发
  • 算法 - 递归实现汉诺塔(The Tower of Hanoi)

    目录 引言 分析 分析两片汉诺塔的迁移过程 分析三片汉诺塔的迁移过程 代码实现 递归出口 递归过程 完整程序代码 运行结果 参考资料 引言 今天接触到了一个非常有意思的游戏 名字叫做汉诺塔 Tower of Hanoi 小时候没有玩过这个益
  • web爬虫学习(四)——手机APP爬取

    思路如下 STEP1 为我们的爬虫找到入口 笔者是一个痴迷于挖掘数据中的价值的学习人 希望在平日的工作学习中 挖掘数据的价值 找寻数据的秘密 笔者认为 数据的价值不仅仅只体现在企业中 个人也可以体会到数据的魅力 用技术力量探索行为密码 让大
  • TFTP常用命令

    一 上传到指定文件夹 tftp p l file target ip 这里的file可以是一个目录 如 C User Administrator Documents 二 下载到当前目录 tftp g r file source ip 这里的
  • webug 4.0 第十关 存储型xss

    感谢webug团队一直以来的更新维护 webug是什么 WeBug名称定义为 我们的漏洞 靶场环境基础环境是基于PHP mysql制作搭建而成 中级环境与高级环境分别都是由互联网漏洞事件而收集的漏洞存在的操作环境 部分漏洞是基于Window
  • 将在数组中的对象的 key,做替换

    固定更换个别 key key1 映射 stroke value 替代值不变 比如 value 的 stroke const arrayOfObj key1 value1 key2 value2 key1 value1 key2 value2
  • 什么是CSS权重值?CSS权重值的优先级是什么?

    什么是CSS的权重值 1 权重决定了你css规则怎样被浏览器解析直到生效 css权重关系到你的css规则是怎样显示的 2 当很多的规则被应用到某一个元素上时 权重是一个决定哪种规则生效 或者是优先级的过程 3 每个选择器都有自己的权重 你的
  • 华为OD机试 - 矩阵最大值(Python)

    题目描述 给定一个仅包含0和1的N N二维矩阵 请计算二维矩阵的最大值 计算规则如下 1 每行元素按下标顺序组成一个二进制数 下标越大越排在低位 二进制数的值就是该行的值 矩阵各行值之和为矩阵的值 2 允许通过向左或向右整体循环移动每行元素
  • python selenium从新浪财经网抓取一家公司的高管任职信息写入excel表格

    网址 http vip stock finance sina com cn corp go php vCI CorpManager stockid 600900 phtml 在页面按f12打开开发者工具 在table标签上右键复制xpath
  • SpringMvc学习-4-Spring MVC 拦截器

    SPring MVC JSON数据交互 Spring提供了一个HttpMessageConverter
  • excel多元线性拟合_急,如何用excel拟合多元函数

    数据如下 公式lny lnA aT blnK clnL D 其中AD是固定值 y是生产总值 T是时间 K是固定资产投资 L是就业 求用excel拟合方程求出abc 多谢了 急等各位大侠 生产总值 固定资产投资 时间 就业 522 28 11
  • 胡言乱语

    1 2013 4 10 又梦见你们苍苍的容颜 心里满满的自责 我早该长大了 不应该心存侥幸的在抗拒 让你们承受的太多了 愧疚难当
  • 最新CTR预测服务的GPU优化实践

    CTR模型在互联网的搜索 推荐 广告等场景有着广泛的应用 近年来 随着深度神经网络的引入 CTR模型的推理对硬件算力的要求逐渐增加 本文介绍了美团在CTR模型优化的实践 通过分析模型结构特点 结合GPU硬件架构 我们设计了一系列流程对模型进
  • 目标检测标签文件txt转成xml

    最近在用ppyolo训练好的模型对新采集的数据进行标记 再人工微调 减少从头打标签的时间 但是推理保存的结果都是txt格式的 想要在labelimg中可视化 那就需要将txt转换成xml 以下代码即可完成这一功能 coding UTF 8
  • Web_Components 系列(九)—— Shadow Host 的 CSS 选择器

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