CSS新特性@layer(层叠样式表)

更新日期: 2022-03-16阅读: 1.1k标签: 特性

过往 css 优先级中存在的问题

如果我们的页面上存在非常多的样式,譬如有我们开发页面的时候的自定义样式,也有引入的组件库样式。这时候样式将会非常混乱难以管理

当我们想覆盖一些本身非我们书写的样式时候,往往不得不通过使用优先级权重更高的样式名,去覆盖那些样式。

同时,当样式优先级感到难以控制时,开发者习惯滥用 !important 去解决,这又循环导致了后续更混乱的样式结构。

基于让 CSS 得到更好的控制和管理的背景,CSS @layer 应运而生。


何为 CSS @layer?

CSS Cascade Layers,也叫做CSS级联层,是Cascading and Inheritance Level5 规范中新增了一个新的 CSS 特性。

@layer声明了一个 级联层, 同一层内的规则将级联在一起, 这给予了开发者对层叠机制的更多控制。语法也非常简单,看这样一个例子:

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

这样,我们就创建一个名为 utilities 的 @layer 级联层。


@layer语法

@layer规则可以通过三种方式其一来创建级联层。第一种方法如上方代码所示,它创建了一个块级的@规则,其中包含作用于该层内部的CSS规则。

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

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

一个级联层同样可以通过 @import 来创建,规则存在于被引入的样式表内:

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

你也可以创建带命名的级联层,但不指定任何样式。例如,单一的命名层:

@layer utilities

或者,多个命名层也可以被同时定义。例如:

@layer theme, layout, utilities

这一做法很有用,因为层最初被指定的顺序决定了它是否有父级层。对于声明而言,如果同一声明在多个级联层中被指定,最后一层中的将优先于其他层。因此,在上面的例子中,如果 theme 层和 utilities 层中存在冲突的规则,那么 utilities 层中的将优先被应用。

即使 utilities 层中规则的 优先级低于 theme 层中的,该规则仍会被应用。一旦级联层顺序建立之后,优先级和出现顺序都会被忽略。这将使创建CSS选择器变得更加简单,因为你不需要确保每一个选择器都有足够高的优先级来覆盖其他冲突的规则,你只需要确保它们出现在一个顺序更靠后的级联层中。

:在已经声明级联层的名字后,它们的顺序随即被确立,你可以重复声明某级联层的名字来向其添加CSS规则。这些样式将被附加到该层的末尾,且级联层之间的顺序不会改变。

其他不属于任何一级联层的样式将被集中到同一匿名层,并置于所有层的前部,这意味着任何级联层内定义的规则都将覆盖外部声明的规则。

嵌套层

级联层允许嵌套,例如:

@layer framework {
  @layer layout {

  }
}

向 layout 层内部的 framework 层附加规则,只需用 . 连接这两层。

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

匿名层

如果创建了一个级联层但并未指定名字,例如:

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

那么则称为创建了一个匿名层。除创建后无法向其添加规则外,该层和其他命名层功能一致。

标准语法

@layer [ <layer-name># | <layer-name>?  {
  <stylesheet>
} ]


@layer如何使用

创建级联层

级联层可以通过多种方式声明:

1、使用@layer 块规则,并立即为其分配样式:

@layer reset {
  * { /* Poor Man's Reset */
    margin: 0;
    padding: 0;
  }
}

2、使用规则@layer 语句,没有指定任何样式:

@layer reset;

3、将@import 与layer关键字或layer()函数一起使用

@import(reset.css) layer(reset);

以上每一个都创建了一个名为 的级联层reset。

管理级联层

级联层会按它们声明的顺序排序。

在下面的例子中,我们建立四个级联层:reset,base,theme,和utilities。

@layer reset { /* 创建级联层 “reset” */
  * {
    margin: 0;
    padding: 0;
  }
}

@layer base { /* 创建级联层 “base” */
  …
}

@layer theme { /* 创建级联层 “theme” */
  …
}

@layer utilities { /* 创建级联层 “utilities” */
  …
}

按照它们的声明顺序,层顺序变为:

reset
base
theme
utilities

重复使用级联层名称时,样式将附加到现有级联层。级联层的顺序保持不变,因为只有第一次的出现已经确定顺序:

@layer reset { /* 创建第一个级联层 “reset” */
  …
}

@layer base { /* 创建第二个级联层 “base” */
  …
}

@layer theme { /* 创建第三个级联层 “theme” */
  …
}

@layer utilities { /* 创建第四个级联层 “utilities” */
  …
}

@layer base { /* 会将样式添加至级联层“base” */
  …
}

重新使用级联层名称时层顺序保持不变的使@layer 语法变得更加方便和严谨。使用它,可以预先建立图层顺序,然后将所有 CSS 附加到它:

@layer reset;     /* 创建第一个级联层 “reset” */
@layer base;      /* 创建第二个级联层 “base” */
@layer theme;     /* 创建第三个级联层“theme” */
@layer utilities; /* 创建第四个级联层 “utilities” */

@layer reset { /* 添加样式至级联层 “reset” */
  …
}

@layer theme { /* 添加样式至级联层  “theme” */
  …
}

@layer base { /* 添加样式至级联层  “base” */
  …
}

@layer theme { /* 添加样式至级联层  “theme” */
  …
}

当然你可以用更短的语法来声明级联层,

@layer reset, base, theme, utilities;

从上面可以看出,多个级联层被声明时,最后一个级联层的声明会获胜。像这样,

@import(reset.css) layer(reset); /* 第一个级联层 */

@layer base { /* 第二个级联层 */
  form input {
    font-size: inherit; 
  }
}

@layer theme { /*第三个级联层 */
  input {
    font-size: 2rem;
  }
}

按以往CSS级联来进行分析的话,form input(多层级)的优先级会大于input,但是由于级联层所起的作用,@layer theme的input会取胜。

级联层嵌套

级联层支持嵌套使用,如下:

@layer base { /* 第一个级联层*/
  p { max-width: 70ch; }
}

@layer framework { /* 第二个级联层 */
  @layer base { /* 第二级联层的嵌套子级联层1 */
    p { margin-block: 0.75em; }
  }

  @layer theme { /* 第二级联层的嵌套子级联层2 */
    p { color: #222; }
  }
}

在这个例子中有两个级联外层:

base
framework
该framework层本身也包含两层:
base
theme

如果要将样式附加到嵌套级联层,需要使用以下全名来引用它,

@layer framework {
  @layer default {
     p { margin-block: 0.75em; }
  }

  @layer theme {
    p { color: #222; }
  }
}

@layer framework.theme {
  /* 这些样式会被添加到@layer framework层里面的theme层 */
  blockquote { color: rebeccapurple; }
}

@media与@layer

@media (min-width: 30em) {
  @layer layout {
    .title { font-size: x-large; }
  }
}

@media (prefers-color-scheme: dark) {
  @layer theme {
    .title { color: white; }
  }
}

如果第一个@media (min-width: 30em)匹配(基于视口尺寸),则layout级联层层将在图层顺序中排在第一位。如果只有@media (prefers-color-scheme: dark)匹配,theme则将是第一层。

如果两者匹配,则图层顺序将为layout, theme。如果没有匹配,则不定义层。


结语

随着 Cascade Layers 的出现,我们的开发人员将拥有更多的工具来控制 Cascade。Cascade Layers 的真正力量来自它在 Cascade 中的独特位置:Style 属性(Style Attribute)和 CSS 选择器权重(Specificity)之间。因此,我们不需要担心其他层中使用的 CSS 的选择器特异性,也不需要担心我们将 CSS 加载到这些层中的顺序。


链接: https://fly63.com/article/detial/11265

CSS新特性contain,控制页面的重绘与重排

contain 属性允许我们指定特定的 DOM 元素和它的子元素,让它们能够独立于整个 DOM 树结构之外。目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。

Html5、Css3、ES6的新特性

Html5的新特性语义化标签:有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重。表单新特性,多媒体视频(video)和音频(audio)

ES6新特性--var、let、const

var不存在块级作用域,具有变量提升机制。 let和const存在块级作用域,不存在变量提升。在同一作用域内只能声明一次。const在声明时需要赋值且无法修改,但如果常量是对象,则对象的属性可以修改。

Js即将到来的3个新特性

Optional Chaining(可选链式调用);Nullish coalescing(空值合并);Pipeline operator(管道运算符)通过三个函数对字符串进行处理;

Angular 8的新特性介绍

在今天早些时候Angular团队发布了8.0.0稳定版。其实早在NgConf 2019大会上,演讲者就已经提及了从工具到差分加载的许多内容以及更多令人敬畏的功能。下面是我对8.0.0一些新功能的简单介绍,希望可以帮助大家快速了解新版本

使用 React 要懂的 Js特性

与我使用的其他框架相比,我最喜欢 React 的原因之一就是它对 JavaScript 的暴露程度。没有模板DSL( JSX 编译为合理的 JavaScript),组件 API 只是通过添加 React Hooks 变得更简单,并且该框架为解决的核心 UI 问题提供非常少的抽象概念

ES2019 新特性汇总

最近 ECMAScript2019,最新提案完成:tc39 Finished Proposals,我这里也是按照官方介绍的顺序进行整理,如有疑问,可以查看官方介绍啦~另外之前也整理了 《ES6/ES7/ES8/ES9系列》,可以一起看哈。

Js的用途和特性

JavaScript 最初的目的是为了“赋予网页生命”。这种编程语言我们称之为脚本。它们可以写在 HTML 中,在页面加载的时候会自动执行。脚本作为纯文本存在和执行。它们不需要特殊的准备或编译即可运行。

十个超级实用的 JS 特性

你可能刚上手 JavaScript,或者只是曾经偶尔用过。不管怎样,JavaScript 改变了很多,有些特性非常值得一用。 这篇文章介绍了一些特性,在我看来,一个严肃的 JavaScript 开发者每天都多多少少会用到这些特性

解密HTTP/2与HTTP/3 的新特性

HTTP/2 相比于 HTTP/1.1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何优雅降级应该是国内还不普遍使用的原因之一。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!