@layer

Baseline 已广泛支持

此特性已经十分成熟,可在许多设备和浏览器版本上使用。自 2022 年 3 月起,它已在各浏览器中可用。

@layer CSS @规则用于声明级联层,也可用于定义多个级联层时的优先级顺序。

试一试

@layer module, state;

@layer state {
  .alert {
    background-color: brown;
  }
  p {
    border: medium solid limegreen;
  }
}

@layer module {
  .alert {
    border: medium solid violet;
    background-color: yellow;
    color: white;
  }
}
<p class="alert">Beware of the zombies</p>

语法

css
/* statement at-rules */
@layer layer-name;
@layer layer-name, layer-name, layer-name;

/* block at-rules */
@layer {rules}
@layer layer-name {rules}

其中

layer-name

是级联层的名称。

rules

是级联层中的 CSS 规则集。

描述

级联层内的规则一起级联,从而让 Web 开发人员对级联有更多的控制。未在层中定义的样式总是会覆盖在命名层和匿名层中声明的样式。

下图显示了层优先级,其中层按 1, 2, ..., N 的顺序声明。

Diagram showing cascade layer priorities

如上图所示,重要声明(带有 !important 标志的声明)优先于普通声明(没有 !important 标志的常规声明)。重要规则之间的优先级顺序与普通规则相反。过渡具有最高优先级。接下来按从高到低的优先级顺序是重要的用户代理声明、重要用户声明和重要作者声明;按此顺序。用户可以使用浏览器偏好设置、操作系统偏好设置或浏览器扩展来指定样式。其重要声明优先于作者(或Web开发人员编写的)重要声明。

在作者样式中,CSS 层内的所有重要声明都优先于在层外声明的任何重要声明,而 CSS 层内的所有普通声明的优先级都低于在层外声明的声明。声明顺序很重要。第一个声明的层获得最低优先级,最后一个声明的层获得最高优先级。但是,当使用!important 标志时,优先级会反转。

@layer @规则可以通过以下三种方式之一创建级联层。

第一种方法是使用 @layer 块 @规则创建一个命名级联层,其中包含该层的 CSS 规则,如下所示:

css
@layer utilities {
  .padding-sm {
    padding: 0.5rem;
  }

  .padding-lg {
    padding: 0.8rem;
  }
}

第二种方法是使用 @layer 语句 @规则创建一个或多个逗号分隔的命名级联层,而不分配任何样式。这可以是一个单独的层,如下所示:

css
@layer utilities;

可以一次定义多个层,如下所示:

css
@layer theme, layout, utilities;

这很有用,因为层声明的初始顺序指示哪个层具有优先权。与声明一样,如果声明出现在多个层中,则列表中最后一个层将获胜。因此,对于前面的示例,如果在 themeutilities 中找到冲突的规则,则 utilities 中的规则将获胜并被应用。

utilities 中的规则将被应用,即使它的特异性低于 theme 中的规则。这是因为一旦建立了层顺序,特异性和出现顺序就会被忽略。这使得可以使用更简单的 CSS 选择器,因为您不必确保选择器具有足够高的特异性来覆盖冲突的规则;您只需确保它出现在后面的层中。

注意:声明层名称并设置其顺序后,您可以通过重新声明名称将 CSS 规则添加到层中。然后,样式将附加到层中,并且层顺序不会更改。

第三种方法是使用不包含层名称的 @layer 块 @规则创建匿名层。例如:

css
@layer {
  p {
    margin-block: 1rem;
  }
}

这会创建一个匿名级联层。此层的功能与命名层相同;但是,以后不能为其分配规则。匿名层的优先级顺序是层(命名或未命名)声明的顺序,并且低于在层外声明的样式。

创建级联层的另一种方法是使用 @import。在这种情况下,规则将位于导入的样式表中。请记住,@import @规则必须位于所有其他类型的规则之前,除了 @charset@layer 规则。

css
@import "theme.css" layer(utilities);

嵌套层

层可以嵌套。例如:

css
@layer framework {
  @layer layout {
  }
}

要将规则附加到 framework 内的 layout 层,请将这两个名称用 . 连接起来。

css
@layer framework.layout {
  p {
    margin-block: 1rem;
  }
}

正式语法

@layer = 
@layer <layer-name>? { <rule-list> } |
@layer <layer-name># ;

<layer-name> =
<ident> [ '.' <ident> ]*

示例

基本示例

在以下示例中,创建了两个 CSS 规则。一个用于任何层之外的 <p> 元素,另一个用于名为 type 的层中用于 .box p

没有层的情况下,选择器 .box p 将具有最高的特异性,因此文本 Hello, world! 将显示为绿色。由于 type 层位于用于保存非层内容的匿名层之前,因此文本将显示为紫色。

另请注意顺序。即使我们首先声明非分层样式,它仍然在分层样式之后应用。

HTML

html
<div class="box">
  <p>Hello, world!</p>
</div>

CSS

css
p {
  color: rebeccapurple;
}

@layer type {
  .box p {
    font-weight: bold;
    font-size: 1.3em;
    color: green;
  }
}

结果

将规则分配给现有层

在以下示例中,创建了两个没有应用规则的层,然后将 CSS 规则应用于这两个层。base 层定义了 colorborderfont-sizepaddingspecial 层定义了不同的颜色。由于在定义层时 special 层最后出现,因此它提供的颜色被使用,文本使用 rebeccapurple 显示。来自 base 的所有其他规则仍然适用。

HTML

html
<div class="item">
  I am displayed in <code>color: rebeccapurple</code> because the
  <code>special</code> layer comes after the <code>base</code> layer. My green
  border, font-size, and padding come from the <code>base</code> layer.
</div>

CSS

css
@layer base, special;

@layer special {
  .item {
    color: rebeccapurple;
  }
}

@layer base {
  .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
  }
}

结果

规范

规范
CSS 级联与继承第五级
# 分层

浏览器兼容性

另见