图解CSS:CSS层叠和继承

CSS中有三个概念是学习CSS必须要掌握的:层叠继承权重。今天我们主要来了解CSS中的层叠和继承,对于CSS权重这一部分将放到CSS的选择器中来介绍,因为这一部分和CSS的选择器耦合的更为紧密。不管是初学者还是有一定工作经验的同学,花点时间阅读这篇文章都是很有必要的,这样有利于你对CSS更清楚的了解和理解。感兴趣的同学请继续往下阅读。

在很多Web开发人员眼中,CSS不是一门程序语言,但它真真切切的是一门计算机语言。主要用来为结构化文档,比如HTML、XML等添加样式,其主要由W3C定义和维护。而CSS是由Cascading Style Sheets三个词的首字母缩写,很多人将其称为层叠样式表或者级联样式表。而我们今天要讲的第一个概念就是CSS中的层叠,也对应的是CSS中的第一个字母C。看到这里,或许你就知道为什么会说层叠是CSS的重要概念之一了。

层叠

层叠是CSS固有的一个东东,它赋予了层叠样式表层叠性。层叠可能是一个很强大的工具,但如果错误的使用它可能会导致样式表的脆弱性,使用Web开发人员在任何时候不得不进行更改时都感到头痛。比如说:

初学CSS的同学,特别是Web其他端的程序员(比如服务端、客户端)在独立编写CSS的时候,经常会碰到这样的一个现象:为什么写的样式不起作用呢?面对这样的场景很多人会采用非常暴力的手段来处理,比如通过添加!important或直接在HTML的元素上添加内联CSS。这就是令很多同学感到疑惑的一点?为什么要这样做呢?其实这和接下来要介绍的层叠(也有很多人称之为级联)有很大的关系。

层叠的定义

因为我们将要深入的学习和讨论CSS层叠是如何工作的相关细节,因此我们有必要的了解W3C规范是如何定义它的:

The cascade takes a unordered list of declared values for a given property on a given element, sorts them by their declaration’s precedence, and outputs a single cascaded value. —— W3C规范

大致意思是:该层叠将获取给定元素上给定属性的声明值的无序列表,按声明的优先级对它们进行排序,并输出单个层叠值

CSS层叠是一种算法,浏览器通过它来决定将哪些CSS样式规则应用到一个元素上。很多人喜欢把它看作是“获胜”的样式,按照CSS中的术语来说,它的权重更高(后面我们会深入介绍)。

为了更好的理解CSS层叠,将CSS声明看作具体的”属性“(attributes)。这些属性可以是声明的各个部分比如说CSS选择器或CSS属性,甚至是CSS声明的位置相关(比如它的原始或源代码中的位置)。

CSS层叠将会根据自己的算法,采用这些属性中的一些,并为每个属性分配一个权重。如果CSS规则在高优先级上获胜(选择器权重高),那么这个样式规则就会获胜,即生效。但是,如果在给定的权重下极然有两个规则冲突,算法将继续”向下层叠”,并且会检查低优先级属性,直到找到一个胜出的规则。

简单的说,当多个相互冲突的CSS声明应用于同一个元素时,CSS层叠算法会根据一定的机制,从最高权重到最低权重的顺序列出:

  • 来源和重要性
  • 选择器权重
  • 出现的顺序
  • 初始和继承属性(默认值)

接下来围绕这几点来进行展开。

来源和重要性

层叠检查的最高加权属性是给定规则的重要性和来源的组合。就CSS规则的来源而言,规则主要来自三个地方:

  • 编写者规则(Author):这是HTML文档声明的CSS。也就是我们前端开发人员编写的,根据文档语言(比如HTML)约定给源文档指定样式表。这也是我们能够控制的唯一来源
  • 用户(User):这是由浏览器的用户定义和控制的。不是每个人都会有一个,但是当人们添加一个时,通常是为了覆盖样式和增加网站的可访问性。比如,用户可以指定一个售有样式表的文件,或者用户代理可能会提供一个用来生成用户样式(或者表现得像这样做了一样)的界面
  • 用户代理(User-Agent):这些是浏览器为元素提供的默认样式。这就是为什么input在不同的浏览器上看起来略有不同,这也是人们喜欢使用CSS重置样式,以确保重写用户代理样式的原因之一

注意,用户可能会修改系统设置(例如,系统配色),这会影响默认样式表。然而,有些用户代理实现让默认样式表中的值不可改变

这三种样式表将在一定范围内重叠,并且它们按照层叠互相影响。

CSS层叠给每个样式规则赋予了权重,应用几条规则时,权重最大的优先。默认情况下,编写者样式表中的规则比用户样式表中的规则权重高。CSS声明的重要性由适当命名的!important语法决定。!important的CSS规则自动将它跳到层叠算法的前面,这也是为什么不鼓励在样式中使用!important的原因之一。覆盖使用!important的样式只能使用其他的!important的规则来完成,如果你的项目足够大,用的!important又足够地多,那么你的CSS就会变得更为脆弱,更难于维护。对于!important的使用,建议你只在其他所有方法都失效的情况之下使用。

那么CSS中层叠算法又是如何判断哪个声明获胜:

CSS层叠在判断哪个声明获胜时考虑这两个属性的组合。每个组合都有一个权重(类似声明的部分权重),权重最高的规则获胜。以下是浏览器考虑的各种来源和重要性的组合,按从最高权重到最低权重的顺序列出:

  • !important的用户代理规则
  • !important的用户规则
  • !important的编写者规则
  • CSS动画@keyframes中的规则(这是较为特殊的一部分,它仍然来自编写者规则,但是由于动画是临时的或短暂的,所以浏览器对它们的权重略高于正常的编写者规则)
  • 编写者规则
  • 用户规则
  • 用户代理规则

当浏览器遇到两个或更多冲突的CSS声明,其中一个在来源和重要性级别获胜时,CSS层叠就会解决这个规则。但是,如果相互冲突的声明具有相同的重要性和来源级别,则层叠将继续考虑选择器的权重。

选择器权重

CSS层叠中的第二个权重是选择器的权重。在这个层中,浏览器查看CSS声明中使用的选择器。作为前端开发人员,我们只能控制编写者样式规则。因为我们无法对来源的规则做太多的更改。但是,你会发现,只要在代码中不使用!important,对于CSS层叠中的选择器权重这一层,还是有较多的方式可以控制。

对于一个选择器的权重,将会按下面这样的规则进行计算:

  • 如果声明来自一个行内样式(style属性)而不是一条选择器样式规则,算1,否则就是0=a)。HTML中,一个元素的style属性值是样式规则,这些属性没有选择器,所以a=1, b = 0, c = 0, d = 0,即1, 0, 0, 0
  • 计算选择器中ID属性的数量 (= b)
  • 计算选择器中其它属性和伪类的数量 (= c)
  • 计算选择器中元素名和伪元素的数量 (= d)

4个数连起来a-b-c-d(在一个基数很大的数字系统中)表示特殊性,比如下面这样的示例:

*             {}  /* a=0 b=0 c=0 d=0 -> 选择器权重 = 0,0,0,0 */
li            {}  /* a=0 b=0 c=0 d=1 -> 选择器权重 = 0,0,0,1 */
li:first-lin
剩余80%内容付费后可查看
* 请输入阅读码(忘记阅读码?

如需转载,烦请注明出处:https://www.w3cplus.com/css/Illustrated-CSS-details-and-cases-chr2-cascade-and-inherit.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部