小文一篇,说说: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 组件。

我司脚手架是支持微前端的。在一些组件中,考虑到样式问题,我们用了 scopedhtml模板和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的特殊性吧的主要内容,如果未能解决你的问题,请参考以下文章

小文一篇,说说:where:has和:is的特殊性吧

小文一篇,说说:where:has和:is的特殊性吧

自动化测试小文一篇

来,开始Kotlin之旅

Laravel Eloquent - 返回 Where Has + Where [重复]

Sequelize where has NOT