优先级 ( 权重 )
如果当 CSS 选择器选取元素时,发生“多个选择器选择到同一个元素”的状况,就会根据“权重 Specificity”来判断这个元素套用样式的“优先级”,这篇教学将介绍 CSS 选择器里最重要的观念“权重 Specificity”,还会透过完整的权重示意图呈现 CSS 的权重样貌。
快速导览:
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
认识 CSS 选择器权重
在网页中套用样式时,发生“多个选择器选择到同一个元素”的状况,就会根据“权重 Specificity”来判断这个元素套用样式的“优先级”,然而除了选择器本身具有不同权重,一些规则、特殊宣告或用户浏览器样式...等都会影响权重,下图是 W3C 所规范的 CSS 权重,权重高的会覆盖在权重低的上方,建议在撰写 CSS 之前,脑中都要先浮现这张权重图,才能写出更好管理与维护的 CSS。
延伸阅读:CSS @layer 分层优先级
选择器的权重计算方式
CSS 选择器会按照“A,B,C”的计算方式判断权重,只要出现了对应的选择器,所对应的 A、B、C 数值就会增加 1,各种选择器对应的数值如下表所示:
参考 W3C 官方:Calculating a selector’s specificity
| 选择器 | 权重 | 数字表示 |
|---|---|---|
| ID | A=1 | 1,0,0 |
| Class 类别 | B=1 | 0,1,0 |
| Attribute 属性 | B=1 | 0,1,0 |
| 虚拟类别 | B=1 | 0,1,0 |
| 元素 | C=1 | 0,0,1 |
| 虚拟元素 | C=1 | 0,0,1 |
| 通用选择器 * | 最低 | 0,0,0 |
“A,B,C”的权重大小为“A>B>C”,因此只要“越左侧的数值越大,权重就越高”,套用样式时也就会套用这个选择器的样式,以下方的 CSS 为例,因为 ID 选择器的权重较高,所以会套用 id 选器器的红色,而不会套用元素选择器的蓝色。
/* HTML 使用:<h1 id="title">OXXO.STUDIO</h1> */
#title {color: red;} /* 權重:1,0,0 */
h1 {color: blue;} /* 權重:0,0,1 */
然而,选择器的权重具有“叠加”的特性,这对于具有“结构选择器”特别明显,因为结构选择器会使用“多个选择器组成结构”,结构中每个选择器都有各自权重的数值,叠加的数值越多,权重也就越高,下方 CSS 展示不同结构选择器所叠加的权重 ( 由小到大 ):
| 选择器 | 权重数值 | 说明 |
|---|---|---|
* |
0,0,0 | 通用x1 |
li |
0,0,1 | 元素x1 |
ul li |
0,0,2 | 元素x2 |
ul li span |
0,0,3 | 元素x3 |
h1 + *[rel] |
0,1,1 | 属性x1 |
ul li span.red |
0,1,3 | 类别x1 |
li .red.level |
0,2,1 | 类别x2 |
#oxxo |
1,0,0 | idx1 |
#oxxo::before() |
1,0,1 | idx1、虚拟元素x1 |
#oxxo *:not(nav) li |
1,0,2 | idx1、元素x2 |
.oxxo :is(.ok, #cool) |
1,1,0 | 类别x1,is() 取出最高的权重为 idx1 |
html body table#oxxo tr[name] td |
1,1,5 | idx1、元素x5、属性x1 |
顺序对权重的影响
如果是“相同权重”的选择器,则会按照“执行的顺序”决定权重,后方选择器的会覆盖前方选择器里相同的样式,以下方的 CSS 为例,当顺序不同时,呈现的文字颜色就会不同。
HTML:
<div class="apple"><span name="oxxo">我是什麼顏色呢?</span></div>
下方的 CSS 执行后会出现“蓝色”文字。
div span[name] {color: red;} /* 權重:0,1,2 */
div.apple span {color: blue;} /* 權重:0,1,2,因為在後方所以呈現藍色 */
下方的 CSS 执行后会出现“红色”文字。
div.apple span {color: blue;} /* 權重:0,1,2 */
div span[name] {color: red;} /* 權重:0,1,2,因為在後方所以呈現紅色 */
inline 行内样式的权重
如果 HTML 的元素使用了“行内样式 inline style”,这个元素的权重就会变成“最高”( 类似 1,0,0,0 的概念 ),只有使用宣告“!important”的样式才能覆盖,以下方的 HTML 为例,当 h1 里加入了行内样式,就算使用了 ID 选择器,仍然无法套用 ID 选择器的样式。
<!-- HTML 程式碼 -->
<h1 id="name" style="color:red">OXXO.STUDIO</h1>
<!-- CSS 程式碼 -->
<style>
#name {color: blue;}
<style>
!important 对权重的影响
“!important”在选择器中是一个特别的宣告,只要选择器里的某个“样式”出现了 !important 宣告,该“样式”的权重就会变成“最高”,除非有另外选择器里的样式也使用了 !important,才会再按照相关的规则进行权重计算,写法如下:
選擇器 {color: red!important;} /* 擺在屬性值的後方,分號的前方 */
使用 !important 需注意下列几个重点:
!important并没有特别的权重值 ( 因为是针对样式 ),主要目的在于排解一些选择器里样式宣告发生冲突的状况,常用于处理“覆盖第三方软件包样式”使用。- 使用
!important常会造成样式不易管理或权重错乱的状况,因此一份好的 CSS 样式表,请避免使用!important。
下方的范例同时使用 !important、行内样式和 ID 选择器、元素选择器,属于“不好且容易错乱”的撰写方式,相当不建议使用,最终呈现结果的规则如下:
- 1、h1 被行内样式影响,呈现红色文字。
- 2、ID 选择器使用了
color: blue!important;,改为呈现蓝色文字。- 3、ID 选择器里的其他样式因为没有使用
!important会按照权重规则计算,呈现行内样式的黄色背景。- 4、h1 选择器虽然也使用
color: green!important,但权重较小,就不会套用颜色样式。- 5、最后使用 ID 选择器里
!important的蓝色文字、行内样式的黄色背景。
<!-- HTML 程式碼 -->
<h1 id="name" style="color:red; background:#ff0;">OXXO.STUDIO</h1>
<!-- CSS 程式碼 -->
<style>
#name {
color: blue!important;
background: #f00;
font-size: 50px;
}
h1 {
color: green!important; /* 因為 h1 權重比 #name 小,會套用 #name 裡的樣式 */
}
</style>
小结
CSS 选择器的优先级 ( 权重 ) 是学习 CSS 最重要的观念 ( 没有之一 ),许多初学者和开发者,时常因为搞不清楚权重,而撰写大量又互相覆盖的 CSS,造成管理不易且容易出错,透过这篇教学,相信应该能帮助大家清楚掌握 CSS 选择器的权重用法!
微信扫码关注
抖音扫码关注