一文彻底理解CSS的优先级和继承

CSS的进入门槛非常低,主要是由于其清晰和易于理解语法,即使你没有任何CSS经验,也可以在短短几个小时内学习一个简单的基于CSS的网站。

但是,表面上的简单性是骗人的。你花了几个小时制作了一个网页,可能在Safari上看起来很棒,但是你并没有去适配Internet Explorer,那么有可能会让你非常的崩溃。兼容性问题是CSS的遇到的最多的问题。要解决兼容性问题,真的需要积累很多的经验,依赖正确的css使用方式。

要想能够正确的使用CSS,精通CSS,理解一些概念是非常有必要的。

Specificity和Inheritance是这些概念中最重要的两个。

“级联”的概念是CSS的核心。它最终决定哪些属性如何应用到特定元素。级联有三个主要概念:importance、specificity和source order。这三者共同确定了要分配给元素的属性的权重。

浏览器通过优先级来判断哪一些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。

importance、specificity和source order共同决定了css的优先级。

importance (重要性)

样式有如下的来源:

用户代理:比如浏览器默认的样式.
用户:比如用户浏览器自己的设定的样式
作者(开发者):页面提供的CSS,可能是内嵌样式,可能是引用样式。

上面的顺序,也是浏览器处理不同来源样式的顺序,后面的优先级更高。

!important 在样式中需要考虑的一个重要声明。这个声明用于平衡用户和作者样式之间的优先级。虽然作者的样式优先级比用户高,但是,如果用户的样式规则里面有 !important,即使作者的规则里面有!important 也会被用户的规则覆盖掉。

知道了这些规则后,我们来看下最终的优先级顺序,下面是按照优先级升序排列:

用户代理声明的
用户声明的
作者声明的
作者使用!important的
用户使用!important声明的

Specificity(具性)

我个人翻译成了具性,个人理解的是更具体更细节的指定某个元素。

前面说过每个CSS规则都一个权重值,这个权重决定了在应用css属性遇到冲突的时候哪个规则生效。

在评估一个规则的权重时,一个更具体的规则比一个更大范围的规则优先级更高。

如果两个样式具有相同的权重、来源和具性,则只最后出现的规则生效。

2.1 如何计算具性

有一系列方式计算选择器的具性。

最快的计算方式如下:

元素和伪元素(像:before,:after)增加1;
属性(比如[type="text"]),类,伪类(:link 或者 :hover)增加10;
ID增加100;
内联样式增加1000;

用上面的方式计算下下面的选择器的具性:

p.note 1 类 + 1 元素 = 11
#sidebar p[lang="en"] 1 ID + 1 属性 + 1 元素 = 111
body #main .post ul li:last-child 1 ID + 1 类 + 1 伪类 + 3 元素 = 123

W3C的标准中也有一个类似的计算方式,以a=0, b=0, c=0, d=0为初始值,以如下情况换为数字:
如果是内联样式:a = 1;
b = ID的个数;
c = 选择器,类和伪类的个数和;
d = 元素名称的个数+ 伪元素的个数

根据上述算法,让我们看一个计算具性值的例子:

<p style="color:#000000;"> a=1, b=0, c=0, d=0 → 1000
footer nav li:last-child a=0, b=0, c=1, d=3 → 0013
#sidebar input:not([type="submit"]) a=0, b=1, c=1, d=1 → 0111

:not 否定伪类在优先级计算中不会被看作是伪类. 事实上, 在计算选择器数量时还是会把其中的选择器当做普通选择器进行计数.

如果使用@import引用CSS,引用的CSS要早于你的CSS,如果遇到两个选择器有相同的具性值,那么后面的将覆盖前面的。

2.2 让具性值为你工作

如果没有考虑清楚具性值是什么的话,可能会导致你的样式表既冗余又复杂。

遵循下面的准则可以避免大部分问题:

使用普通的选择器,逐渐的增加具性值;
使用高级选择器并不代表使用复杂的选择器;
更多的依赖具性值,而不是依赖选择器的顺序,这样的样式表更容易修改和维护;

重构CSS选择器要比简单的修改CSS属性要简单的多。

3.继承

继承是将属性值从父元素传播到其子元素的一种方式。

默认情况下,某些CSS属性由元素的子元素继承。例如,如果将body设置为特定字体,则该字体将由其他元素继承,如标题和段落,而无需特别指定。这就是继承的魔力。

CSS规范指定每个属性是否默认继承。不是所有的属性都是继承的,但是可以通过inherit强制继承它们。

3.1面向对象程序的继承

尽管超出了本文的范围,CSS继承不应与面向对象编程(OOP)继承相混淆。这里是维基百科OOP继承的定义,它清楚地说明我们说的是不同的事情:

在面向对象编程(OOP)中,继承是使用已经定义的类来形成新类(…)的一种方式。继承被用来帮助重用现有代码。新类(…)继承已存在的类的属性和行为。…

3.2 如何继承功能

当一个元素从它的父节点继承一个值时,它继承的是计算值。这意味着什么?每个CSS属性在确定其值时经历四步。以下是W3C规范的摘录:

属性的最终值要经历四步计算:

通过规范指定值(指定值),然后再被解析为用于继承的值(计算值),然后如果有必要的话在转换为绝对值(使用值),最后根据本地环境转换为实际值(实际值)

如下所示:

指定值:用户代理决定了属性值是来自样式表,继承的,还是初始值

计算值:指定值会被解析为计算值。计算值不依赖文档是否已平铺完。

使用值:文档平铺完成之后,由计算值转换为使用值。

实际值:最终用于渲染的值,把使用值转换为真正被渲染是使用的值。

如果你看CSS属性规范的时候,你会看到,它定义的初始值,继承状态,和计算值。比如background-color规范规范如下:

Name: background-color
Value: <color>
Initial: transparent
Applies to: all elements
Inherited: no
Percentages: N/A
Media: visual Computed
value: the computed color(s)

一个元素从其父元素继承的是计算值。即使在样式表中没有指定,属性值也可以被继承:此时继承的是初始值。所以即使父元素没有指定属性值也可以继承。

本文翻译并参考了如下两篇文章:
CSS Specificity And Inheritance
CSS优先级

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343