小文一篇,说说:where:has和:is的特殊性吧
Posted 恪愚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小文一篇,说说:where:has和:is的特殊性吧相关的知识,希望对你有一定的参考价值。
css推出的:where
、:has
和 :is
伪类满足了我对“逻辑化CSS”的简单幻想。
简单说下,假如你有这么一个需求:在响应式页面中,你需要判断头部元素中是否具有某一个图标,以决定 Top 文字的样式(间距、对齐方向等)。
不知道各位以前是怎么实现的。为了“性能考虑”,笔者通常是通过“动态 class”,用 js 操作元素样式。
那时候就想,如果css中就可以去判断元素就好了!但是从张鑫旭大佬那得知,我这种想法是“子元素选择”,就是父元素根据子元素调整,这样可能会带来重绘这样严重的影响。后续还要看浏览器是否会支持这种特性。
没想到,W3C推出了三种相关伪类,而浏览器也在逐渐支持。
言归正传,这三个伪类其实代表了三种特性:
- 父元素选择
:where
:简化常规选择器判断,根据父元素行为判定子元素
比如这样的问题:
.btn span > a:hover,
#header span > a:hover,
#footer span > a:hover
/** 在less、sass这种预选择器中更难受!*/
变成这样的代码:
:where(.btn, #header, #footer) span > a:hover
- 子元素选择 ——
:has
:根据子元素行为判定父元素或其他子元素
box img
aspect-ratio: 21 / 9;
border: 5px solid #3f51b5;
box:has(boxing) img
border: 5px solid #9c27b0;
- 双向选择 ——
:is
box > :is(.boxing)
或是:
box > :is(.class-a, .class-b)
/** 简化自下面的代码 */
box > .class-a,
box > .class-b
既然 :is
和 :where
都有一样的特性(匹配任意一个class),那么他们有区别吗?
首先从上面的语法看是没有区别的,但是他们在优先级上有区别:我们都知道 css 选择器是有优先级的。而:where
的优先级是0!无论其参数重的选择器优先级有多高!
但 :is
的优先级是由参数重的选择器优先级决定的。
这里着重说说:is
选择器吧,我发现了一个有趣的地方。
这是我司商家侧一个功能,这里用了 elementui
第三方库中的 el-radio
组件。
我司脚手架是支持微前端的。在一些组件中,考虑到样式问题,我们用了 scoped
为html模板和css选择器添加随机的属性选择器,以实现css的作用域功能。(Vue特性)
那么,在如上第三方库中,我们会发现,组件内部的元素上并没有 data-v-xxx
这样的随机属性。也就是说,如果我们希望对这个元素进行样式更改,则写在 scoped 范围内就无效:
<style lang="less" scoped>
.ce__form-limit
.el-radio.is-checked
.el-radio__label
color: red;
</style>
因为这时候,Vue在编译后会给这个类名再加一个单独的属性选择器,导致无法和 DOM 中的元素匹配上!
笔者发现,在之前的这种情况中,我司之前的开发者是通过“把这个样式写在全局结构”中,比如在我们组规范的“全局样式层”文件中写入:
.el-radio.is-checked
.el-radio__label
color: red !important;
但这种方式并不很好,笔者就曾经找这些代码找了许久… 你并没发知道后面接手的开发者是否有“耐心”看这些东西,甚至后面可能就多了许多“重复功能代码”。
ummm,包括:deep()
、>>>
也是一样的道理。
:is选择器拯救css结构
但是现在有了 :is
!使用 is 伪类后选择器会遵循父元素的效果,而不是自己单独加一个随机属性!
(可能这和 is “子元素选择”的特性有关,为了知道子元素影响,编译时要先给它打上标记。但是 :has
伪类笔者试的是不行,这样的话这个解释就不通了,为毛同样是子供向一个可以另一个不可以?!)
还是上面的例子,我们再来看下这样的效果:
<style lang="less" scoped>
.ce__form-limit
.el-radio.is-checked
:is(.el-radio__label)
color: red;
</style>
补充一下上面的说法:
1、对React也是一样的;
2、除了第三方库组件,动态生成的DOM也不受此限制;
3、如果对兼容性有大要求的项目,可以用:-webkit-any()
期待后续更多的特性出来,各位也别闲着,一起折腾折腾“老技术”,说不定就搞出来什么名堂了呢~
不说了,才知道旧友来北京了,去拜访一下。预祝各位国庆愉快!
以上是关于小文一篇,说说:where:has和:is的特殊性吧的主要内容,如果未能解决你的问题,请参考以下文章