# css2022 新特性

返回:css 系统学习

# 2022新增特性

# 容器查询(Container Queries)

TIP

容器查询@container类似于媒体查询@media,区别在于查询所依据的对象不同。

媒体查询依据的是浏览器的视窗大小
容器查询依据的是元素的父元素或者祖先元素的大小。

有关容器查询的属性一共有三个,分别是container-type、container-name、container

  • container-type:标识一个作为被查询的容器,取值范围为size、inline-size、block-size、style、state
  • container-name:被查询的容器的名字
  • container:container-type和container-name的简写

首先需要使用container-type或者container属性指定一个元素作为被查询的容器。然后使用@container进行容器查询。

<template>
    <div id="app">
      <div>
          <button @click="add" id="add">+</button>
          <button @click="sub" id="sub">-</button>
        </div>
        <div class="demo">
          <a>我的背景色会随着demo元素的宽度而变化</a>
        </div>
    </div>
</template>

<style>
.demo {
  width: 200px;
  height: 200px;
  background: red;
  container: inline-size; /*指定查询的属性 */
}

@container (inline-size > 300px) {
  a {
    background: green;
  }
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

当demo的宽度为200px时,背景色为红色,当增大到400px时,a标签内文字的背景色变为绿色

# 颜色函数(Color Functions)

TIP

CSS Color Module Level 5[4]新增了两个有关颜色的函数:color-mix()color-contrast() ,并且扩展了之前存在的其他颜色函数(例如rgb(0,0,0)、hsl(177deg,80%,90%)、hwb()等)的相关语法。

# color-mix()

它接收3个参数,第一个参数为指定的插值方法,第二个和第三个参数为需要混合的颜色值。

color: color-mix(in lch, purple 50%, plum 50%)
color: color-mix(in lch, purple 50%, plum)
1
2

# color-contrast

color-contrast(wheat vs tan, sienna, #d2691e, darkgreen, maroon to AA-large)
1

上述代码将wheat与tan、sienna、#d2691e、darkgreen、maroon进行对比度的比较,输出第一个超出AA-large(常量3)的颜色。

wheat (#f5deb3), the background, has relative luminance 0.749
tan (#d2b48c) has relative luminance 0.482 and contrast ratio 1.501
sienna (#a0522d) has relative luminance 0.137 and contrast ratio 4.273
#d2691e has relative luminance 0.305 and contrast ratio 2.249
darkgreen (#006400) has relative luminance 0.091 and contrast ratio 5.662
1
2
3
4
5

darkgreen是对比度最高的颜色,但是我们有to AA-large的限制,所以会输出sienna,因为sienna是第一个超出AA-large(常量3)的。

# 伪类选择器:has()

TIP

:has()选择器也可以叫做父类选择器,它接受一个选择器组作为参数。有了它,我们可以给有匹配子元素的父类应用一些样式

a:has(span) /* 只会匹配包含 span 子元素的 a 元素:*/
1

# accent-color

# 媒体查询(Media Query Ranges)

TIP

媒体查询不是一个新概念,这次在语法上进行了优化。原来通过max-width和min-width来实现的现在可以通过数学运算符>=、<=来实现。
相比与原来的写法,新的语法更容易理解一些。
比如要实现750px以下屏幕的样式,原来需要应用@media (max-width: 750px),现在可以直接写成@media (width <= 750px)

同样,数学运算符的写法也适用于上面介绍的容器查询@container中。

@media (max-width: 750px) {}
@media (min-width: 750px) {}
@media (min-width: 375px) and (max-width: 750px) {}
/* 新写法 */
@media (width <= 750px) {}
@media (width >= 750px) {}
@media (375px <= width <= 750px) {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 级联层(Cascade Layers)

@layer utilities {
  /* 创建一个名为 utilities 的级联层 */
}
1
2
3

# 通过 @layer 级联层管理样式优先级

  • @layer 级联层最大的功能,就是用于控制不同样式之间的优先级
<div></div>
1
div {
  width: 200px;
  height: 200px;
}
@layer A {
  div {
    background: blue;
  }
}
@layer B {
  div {
    background: green;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

由于 @layer B 的顺序排在 @layer A 之后,所以 @layer B 内的所有样式优先级都会比 @layer A 高,最终 div 的颜色为 green

或者如下写法(同时命名多个 @layer 层,其后再补充其中的样式规则)

@layer B, C, A;
div {
  width: 200px;
  height: 200px;
}
@layer A {
  div {
    background: blue;
  }
}
@layer B {
  div {
    background: green;
  }
}
@layer C {
  div {
    background: orange;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

我们首先定义了 @layer B, C, A 三个 @layer 级联层。而后再后面的 CSS 代码中补充了每个级联层的 CSS 代码,但是样式的优先级为:

A > C > B

因此,最终的 div 的颜色值为 @layer A 中定义的颜色,为 blue

# @layer 级联层的三种定义引入方式

  • 直接创建一个块级的 @layer 规则,其中包含作用于该层内部的 CSS 规则:
@layer utilities {
  p {
    padding: 0.5rem;
  }
}
1
2
3
4
5
  • 一个级联层可以通过 @import 来创建,规则存在于被引入的样式表内:
@import (utilities.css) layer(utilities);
1
  • 创建带命名的级联层,但不指定任何样式。样式随后可在 CSS 内任意位置添加:
@layer utilities;
// ...
// ...
@layer utilities {
  p {
    color: red;
  }
}
1
2
3
4
5
6
7
8

# 非 @layer 包裹层与 @layer 层内样式优先级

@layer A {
  a {
    color: red;
  }
}
@layer B {
  a {
    color: orange;
  }
}
@layer C {
  a {
    color: yellow;
  }
}
a {
  color: green;
} /* 未被 @layer 包裹的样式 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

非 @layer 包裹的样式,拥有比 @layer 包裹样式更高的优先级,因此,上述规则的排序是:

未被 @layer 包裹的样式 > @layer C > @layer B > @layer A

# 匿名层与嵌套层

# 匿名层

允许创建一个不带名字的 @layer:

@layer {
  p {
    margin: 1rem;
  }
}
1
2
3
4
5

匿名层的两个重要特性:

  • 创建后无法向其再添加规则
  • 该层和其他命名层功能一致,优先级也遵循后定义的匿名层,比其他已定义的 @layer 层,优先级更高
div {
  width: 200px;
  height: 200px;
}
@layer {
  div {
    background: pink;
  }
}
@layer B, C, A;
@layer A {
  div {
    background: blue;
  }
}
@layer B {
  div {
    background: green;
  }
}
@layer C {
  div {
    background: orange;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

我们首先定义了一个匿名层,指定了 div 的颜色为 pink,而后又定义了 @layer B, C, A。这里优先级顺序为:

A > C > B > 匿名层

最终的颜色为 @layer A 内的颜色值 -- blue

我们将匿名层放在最后的话

div {
  width: 200px;
  height: 200px;
}
@layer B, C, A;
@layer A {
  div {
    background: blue;
  }
}
@layer B {
  div {
    background: green;
  }
}
@layer C {
  div {
    background: orange;
  }
}
@layer {
  div {
    background: pink;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

样式的优先级顺序为:

匿名层 > A > C > B

最终的颜色为匿名层内的颜色值 -- pink

# 嵌套层

嵌套层的意思就是在 @layer 内部,我们可以再嵌套使用 @layer 级联层

@layer A {
  @layer B {
    ...;
  }
}
1
2
3
4
5

上述代码等价于:

@layer A.B {
  ...;
}
1
2
3
div {
  width: 200px;
  height: 200px;
}
@layer A {
  div {
    background: blue;
  }

  @layer B {
    div {
      background: red;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

如果没有 @layer A 这一层包裹,其实就是上述说的 @layer 层与非 @layer 层的优先级比较,这里,非 @layer 层(我们可以理解为更高级别的一层 @layer)的优先级更高

# 多层嵌套层的优先级关系

div {
  width: 200px;
  height: 200px;
}
@layer A {
  div {
    background: blue;
  }
  @layer B {
    div {
      background: red;
    }
  }
}
@layer C {
  div {
    background: yellow;
  }
  @layer D {
    div {
      background: green;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

@layer C > @layer C.D > @layer A > @layer A.B

# !important 对 CSS @layer 的影响

!important 规则的优先级还是凌驾于非 !important 规则之上的

# 非 @layer 包含块 !important 与 @layer 包含块 !important

div {
  width: 200px;
  height: 200px;
  background: black !important;
}
@layer A {
  div {
    background: blue;
  }
  @layer B {
    div {
      background: red;
    }
  }
}
@layer C {
  div {
    background: yellow;
  }
  @layer D {
    div {
      background: green !important;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

按照上述我能描述的规则来看,非 @layer 包含块的优先级高于 @layer 包含块,那么正常而言,我们不难猜测,这里 background: black!important 的优先级应该要比 background: green!important 高,最终 <div> 应该展示黑色

实际上,这里最终 <div> 的颜色还是 green

!important

非常重要的特性,在比较正常(非 !important)规则时,越是级联(排序较后的 @layer 规则),优先级越低;反之,在比较 !important 规则时,越是级联靠后的(排序较后的 @layer 规则),优先级越高。