• 小文一篇,说说: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 选择器吧,我发现了一个有趣的地方。
    微店pc-卖家-优惠套餐设置端

    这是我司商家侧一个功能,这里用了 elementui 第三方库中的 el-radio 组件。

    我司脚手架是支持微前端的。在一些组件中,考虑到样式问题,我们用了 scoped 为html模板和css选择器添加随机的属性选择器,以实现css的作用域功能。(Vue特性)
    图-1

    那么,在如上第三方库中,我们会发现,组件内部的元素上并没有 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>
    

    图-2

    补充一下上面的说法:
    1、对React也是一样的;
    2、除了第三方库组件,动态生成的DOM也不受此限制;
    3、如果对兼容性有大要求的项目,可以用:-webkit-any()


    期待后续更多的特性出来,各位也别闲着,一起折腾折腾“老技术”,说不定就搞出来什么名堂了呢~

    不说了,才知道旧友来北京了,去拜访一下。预祝各位国庆愉快!

  • 相关阅读:
    华为机试 - 最长的指定瑕疵度的元音子串
    Spring Boot之AJAX异步发送帖子
    正点原子嵌入式linux驱动开发——TF-A移植
    【FAQ】关于华为地图服务定位存在偏差的原因及解决办法
    网络管理工作多年遇到故障依然没有解决思路?做完这两步你就懂了
    强烈推荐十几款IDEA开发必备的插件
    Python无废话-办公自动化Excel图表制作
    golang中fallthrough简介及用法
    【面试题】 面试官:你个老六,连继承都不会...
    C#中的LINQ(Language-Integrated Query)
  • 原文地址:https://blog.csdn.net/qq_43624878/article/details/127045426