2022.12.24 前端周刊

154 阅读5分钟

Chrome团队发布了对新提议的CSS规范——style queries的实验性支持

通过style queries,我们可以通过style而不只是size来实现容器查询。

在了解style queries前,我还推荐您通过该篇文章了解下通过size来实现容器查询的container size queries

什么是style queries

通过style queries我们可以通过css属性或css变量来实现容器查询。

style queries目前只在Chrome Canary中实现了实验性的支持。如果想要测试该功能的话,你需要打开chrome://flags下的“Experimental Web Platform features”开关

如何使用style queries

.parent {
  container-name: parent;
  display: flex;
}

// 指定.child的父节点.parent为flex布局时.child的样式
@container parent style(display: flex) {
  .child {
    // custom style
  }
}

style queries的意义

事实上,style queries所实现的功能,通过目前的css语法也能实现,比如下面这段css:

.parent {
  container-name: parent;
  display: block;
}

.parent.featured {
  display: flex;
}

@container parent style(display: flex) {
  .child {
    // custom style
  }
}

同样可以通过以下方式来实现

.parent {
  display: block;
}

.parent.featured {
  display: flex;
}

.parent.featured .child {
  // custom style
}

那么,style queries的意义是什么呢(我只列出了部分,想看全部请看原文)?

使css具有更好的可读性

通过style queries,可以使css具有更好的可读性并且修改起来更加方便,通过它我们可以更少的使用类名修饰符或HTML data attribute去定义样式的生效状态,而是更加直白的去声明样式的生效条件。

通过style queries可以实现组件级的样式变更。

举个例子,我们现在有两套样式主题,一套简白、一套暗黑。

传统css通过以下方式实现简白主题:

.wrapper-white .icon {
  background-color: #19223e;
}

.wrapper-white .btn {
  background-color: #19223e;
}

.wrapper-white .section {
  background-color: #19223e;
}

通过style queries我们可以这样实现:

.wrapper {
  --theme: white;
  container-name: wrapper;
}

@container wrapper style(--theme: white) {
  .icon {
    background-color: #19223e;
  }
  
  .btn {
    background-color: #19223e;
  }
  
  .section {
    background-color: #19223e;
  }
}

再比如,我们想实现不同布局的几种列表展示方式。

image.png

通过style queries我们可以这样实现:

.avatars-wrapper {
  container-name: avatars;
}

@container avatars style(--appearance: stack) {
  .avatar {
    box-shadow: 0 0 0 2px #fff;
  }

  .avatar + .avatar {
    margin-inline-start: -0.5rem;
  }
}

@container avatars style(--appearance: grid) {
  .avatars-list {
    gap: 0.5rem;
    max-width: 200px;
  }
}

可以和container size queries一起使用

比如下面这段代码:

.parent {
  container-type: inline-size;
  --theme: white;
}

@container (min-width: 400px) and style(--theme: white) {
  /* white style */
}

white style只有在--theme: white和min-width: 400px两个条件同时满足时,才会生效

可以让伪类选择性的生效

比如以下代码,可以让.content下的所有元素:after伪类在指定条件下生效,从而实现旋转效果背景(不同于普通背景色,是有点rotate效果的)的样式。

.content {
  --decorated: true;
}

@container style(--decorated: true) {
  :after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--dec-color, green);
    opacity: 0.1;
    z-index: -1;
    transform: rotate(-1.5deg);
  }
}

效果如下

image.png

更多关于style queries的介绍可以通过原文进一步了解

一个关于css嵌套语法的投票邀请你来参加

嵌套在Sass这种工具来说很常见,它可以避免重复书写选择器从而大大节约开发者的时间,与此同时,可以使代码具有更好的可读性。希望css支持嵌套语法的呼声越来越大,今年夏天CSSWG已经发起了一次关于Option1、Option2和Option3三种嵌套语法的投票。Option3的得票数最高,这一次,在之前的基础上,又提出了Option4和Option5,于是,邀请大家再一次对Option3、Option4和Option5进行投票。关于三个Option的异同之处(主要是异),我摘取了一部分,想看更多的话可以看看原文

相同之处

  1. 三个Option都通过&符号来表示“将选择器放到嵌套外面”,举两个例子:

    第一个🌰:

    .foo {
      & .bar {
        color: blue;
      }
    }
    

    等同于

    .foo .bar {
      color: blue;
    }
    

    第二个🌰:

    .foo {
      .bar & {
        color: blue;
      }
    }
    

    等同于

    .bar .foo {
      color: blue;
    }
    

    对于不习惯使用&符号的用户,该符号也可以省略。那么外层选择器就会被默认为祖先节点。也就是说:

    .foo {
     .bar {
       color: blue;
     }
    }
    

    等同于

    .foo .bar {
      color: blue;
    }
    

    需要注意的是Option3与Option4和Option5不同,对于标签选择器,Option3要求&符号不能省略。 为了方便记忆,你也可以这么理解:“Option3的嵌套语法中,首个字符必须是符号,而非字母”,举个🌰:

    .foo {
     // 对于类选择器,&可以省略
     .bar {
       color: blue;
     }
     // 对于标签选择器,&不可省略
     & div {
       background-color: #fff;
     }
    }
    

不同之处

  1. 基本写法

    非嵌套语法:

    article {
     font-family: avenir;
    }
    article aside {
     font-size: 1rem;
    }
    

    Option3:

    article {
      font-family: avenir;
      & aside {
        font-size: 1rem;
      }
    }
    

    Option4:

    article {
      font-family: avenir;
    } {
      aside {
        font-size: 1rem;
      }
    }
    

    Option5:

    @nest article {
      & {
        font-family: avenir;
      }
      aside {
        font-size: 1rem;
      }
    }
    
  2. 格式化方案

    开发团队总是想尽可能使css代码可读性更强点,更好看点。为了达到这个目的,不同团队可能使用不同的格式化方案,比如使用tabs/spaces,又或者把{}放到同一行/不同行等。在这一点,不同Option有不同的格式化方案。

    非嵌套语法:

      .foo {
        color: red;
      }
      .foo .bar {
        color: blue;
      }
      .foo p {
        color: yellow;
      }
    

    Option3:

      .foo {
        color: red;
        .bar {
          color: blue;
        }
        & p {
          color: yellow;
        }
      }
    

    格式化方案:

    .foo {
      color: red;
      & .bar {
        color: blue;
      }
      & p {
        color: yellow;
      }
    }
    

    Option4:

      .foo {
        color: red;
      } {
        .bar {
          color: blue;
        }
        p {
          color: yellow;
        }
      }
    

    格式化方案:

    .foo {
      color: red; } {
      .bar {
        color: blue;
      }
      p {
        color: yellow;
      }
    }
    

    Option5

    @nest .foo {
      & {
        color: red;
      }
      .bar {
        color: blue;
      }
      p {
        color: yellow;
      }
    }
    

    格式化方案:

    @nest .foo {{
      color: red; }
      .bar {
        color: blue;
      }
      p {
        color: yellow;
      }
    }
    

    还有更多不同之处,大家可以看看原文(小声说我投了Option5,不过目前Option3遥遥领先)