CSS-in-Action:样式优先级

虽然写了不少 CSS代码,有时还是会对一些莫名其妙的样式呈现感到意外,如果你也碰到过这样的情况,这篇总结�也许能帮你解答部分疑问。

我们都知道 CSS 中声明的样式是通过选择器与 DOM 元素匹配的,一个 DOM 元素可以对应一个或多个样式,有时候,如果对应的多个样式存在冲突,浏览器就必须采用一些规则来解决冲突。用 CSS (Cascading Style Sheets,层叠样式表)自己的话来说,这些�规则被统称为“层叠”(cascade)。

层叠由四个概念组成:

  1. 特殊性
  2. 重要性
  3. 来源
  4. 顺序

有了他们四个,天下就没有解决不了的冲突。

特殊性

特殊性是解决多样式冲突的一个重要概念,在 css 中,所有的样式声明都有自己的选择器,而不同的选择器具有不同的特殊性(Specificity)。

我们可以认为特殊性是计算样式重要性的一个权重参数,根据选择器的不同,一共有5种权重:

  1. 内联样式:1000
  2. ID 选择器:100
  3. 类选择器(包括属性选择和伪类):10
  4. 元素和伪元素选择器:1
  5. 结合符和通配符:0

举几个例子

h1 { color: red;} /* 权重 = 1 (元素) */
div h1{color:yellow;} /* 权重 = 2 (元素+元素) */
.emphasized{color: purple;} /* 权重 = 10 (类) */
*.emphasized{color:blue;} /* 权重 = 10 (通配符+类) */
#title{color:orange;}  /* 权重 = 100 (ID) */
div#sidebar a{color:blue;} /* 权重 = 102 (元素+ID+元素)*/

一旦一个选择器的特殊性值被确定,该特殊性值为应用到该选择器所包含的所有样式声明上。

比如

h1{color:red;font-size:32px;}
/**
* 规则 color:red 和规则 font-size:32px 都具备相同的特殊性
* 也就是元素选择器的特殊性 1
*/

用户代理会自动完成对样式声明的分解动作,上面的代码将被用户代理处理为

h1{color:red;}
h1{font-size:32px;}

当某一 DOM元素的样式出现冲突时,浏览器会对比每一条声明的特殊性并采用权重最高者。

关于特殊性,有一点是需要注:0特殊性比无特殊性权重要高,可能这句话理解起来有点抽象。

举个例子

* { color: red;}
h1 {color:black;}
<h1>你猜我是什么<em>颜色</em></h1>

如果没有* {color:red;} 这段声明,整句话都是黑色,因为 em 元素会从其父元素h1中继承样式。但实际情况是通配符样式具有0特殊性,相比完全没有特殊性的继承样式,优先级更高,所以 em 中的颜色二字会采用具有0特殊性的样式 * {color:red;} ,� 从而显示为红色。

重要性

我们可以在样式声明结束分号前插入!important来标志出重要声明,事实上,!important不具备任何特殊性,浏览器会将标志为重要的声明分组放到一起。相比普通组,重要组中的声明总是会胜出。

body h1{ color:red; } /* 特殊性权重  = 2 */
h1{color:orange!important;} /* 特殊性权重 = 1 */
/**
* 但由于第二条规则有!important标志,所以尽管特殊性只有1,仍然胜出
*/

当然了,如果重要组中的声明发生了冲突,还是采用计算特殊性的方式来解决。

h1#title { color:red!important; } /* 特殊性权重  = 101 */
h1.title{color:orange!important;} /* 特殊性权重 = 10 */
/**
* 二条规则都有!important标志,都在重要组中,这时通过比较特殊性决定谁胜出,
* 该例中,第一条规则胜出
*/

来源

在考虑声明重要性的同时,还需要考虑其来源。有的浏览器或者浏览器插件允许用户自己定义样式(称之为读者声明),由此就存在开发者创建的声明与用户自定义声明之间孰轻孰重的问题。

总结一下,根据来源的不同,优先级从高到低依次是:

  1. 读者的重要声明
  2. 开发者的重要声明
  3. 开发者的正常声明
  4. 读者的正常声明
  5. 用户代理声明

用户代理声明也就是浏览器的默认样式,但由于其优先级最低,开发者通常不需要考虑。

顺序

在讨论最后一个影响样式优先级的因素前,我们先总结一下。浏览器在解析样式声明时,首先根据来源和重要性将所有的声明分组排序:

读者的重要声明 -> 开发者的重要声明 -> 开发者的正常声明 -> 读者的正常声明 -> 用户代理声明

然后在各组中分别计算样式声明的特殊性,并按�其权重排序。

这时候,可能大部分冲突都已经解决了,但总有一些顽固分子,他们来源相同、同等重要、特殊性也一样。遇到这样的顽固派,最后的杀手锏就是声明顺序——越后声明的优先级越高。

当然,也有例外的情况,当外部样式声明在内部样式之后,外部样式�会覆盖内部样式中重复的规则。比如下面的代码,页面中的链接样式被外部样式所覆盖,显示为红色而不是蓝色。

h1{color:blue;}
h1{color:red;}

也就是说,上面两条声明,第二条会胜出。

值得一提的是,如果样式表中存在导入的样式,一般认为出现在导入样式表中的声明在前,主样式表中的样式在后。

/* additional.css */
h1{color:blue;}
h1{color:red;}
@import additional.css;

即便 additional.css在主样式表中的h1声明后才被引入,页面中的h1 仍然显示红色。

总结

层叠是层叠样式表中一个非常重要的概念,是冲突声明的排序依据,根据声明的特殊性、重要性、来源和顺序,可以最终确定文档的呈现样式。

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

推荐阅读更多精彩内容