领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

一文读懂CSS优先级规则,教你如何优雅重置样式

nixiaole 2024-12-01 02:02:32 知识剖析 11 ℃

开篇

通常带着一个问题来学习知识会有事半功倍的效果,因此文章开头,我们先抛出个小问题来考考大家

// html如下:
<div class="wrap">
    <span class="text">你好,我是前端扫盲</span>
</div>

/* css样式如下:*/ 
span.text:not(.foo) {
    color: blue;
}
div.wrap>.text {
    color: red;
}

问,span标签中的文本最终会渲染成什么颜色?

1、blue 蓝色,2、red 红色。快去留言作答吧...


CSS 选择器优先级计算

CSS的选择器其实大类的话可以分为三类,即id选择器、class选择器、标签(伪元素:before)选择器。而选择器之间又可以配合通配符(*)、关系选择符(+, >, ~, ' ', ||)、伪类(:hover)组合使用,如:


button.btn:hover{} // 标签选择器 class选择器 伪类选择器
#app > main{} // id选择器 选择符 标签选择器

其中CSS优先级又可以分为6个等级,我们分别用0-6来标识,数字越大优先级越大且优先级等级是无法跨越的(后面会有解释)

0级:通配选择器(*)、选择符(+, >, ~, ' ', ||)、逻辑伪类(:not()等)

1级:标签选择器

2级:class选择器、属性选择器(input[type="radio"]等)、伪类(:hover、:active等)

3级:id选择器

4级:style标签内联样式

5级:!important 顶级优先级(使用 !important 是一个坏习惯,应该尽量避免,学习文本后就知道如何代替!important )

注(:not())对优先级没有影响。但是,在 :not() 内部声明的选择器会影响优先级

基于上面等级我们将每个等级用一个数值来描述优先级别。具体如下,在一段CSS语句中,

每出现一个0级选择器优先值+0

每出现一个1级选择器优先值+1

每出现一个2级选择器优先值+10

每出现一个3级选择器优先值+100

每出现一个4级选择器优先值+1000

每出现一个5级选择器优先值+10000

通过以上规则,我们就可以对每一段css语句算出它的优先级值,值越大优先级越高,以下我们简单列举几个示例来算他们的优先值:

现在我们再来看看文章开头抛出的问题,问span标签中的文本最终会渲染成什么颜色

// html如下:
<div class="wrap">
    <span class="text">你好,我是前端扫盲</span>
</div>

/* css样式如下:*/ 
span.text:not(.foo) {
    color: blue;
}
div.wrap>.text {
    color: red;
}

现在我们通过优先级计数值方法来算下两个css语句的优先级值:

div.wrap>.text 优先级值为:1个1级标签选择器(div)+ 1个2级类选择器(.wrap)+ 1个0级选择器(>)+ 1个2级类选择器 (.text)= 1 + 10 +0 + 10 = 21

span.text:not(.foo) 优先级值为:1个1级标签选择器(span)+ 1个2级类选择器(.text)+ 1个0级逻辑伪类选择器(:not)+ 1个2级类选择器(.foo)= 1 + 10 +0 +10 = 21

通过计算两个的优先级值都是21,那该咋渲染呢,其实css渲染还有另外一个规则,就是——“后来居上”,当有优先值一样的时候,那么定义在后面的样式会覆盖前面的样式。因此上述问题最终文本会渲染成red红色。这个规则是相对整个页面文档而言,而不仅仅是对一个css文件中。

(上面提到优先级等级是无法跨越的的意思是,我们不能通过设置11个1级选择器来重置一个2级选择器的样式,因为现实中我们极少会出现连续10个标签选择器来定义一个样式,因此这边定义的2级选择器优先值10是够用 的,10只是代表一个等级,你也可以用abcde来定义上述几个等级,所以不管几个1级选择器也无法覆盖1个2级选择器,ie上连续256个标签选择器会覆盖1个二级选择,应该算是一个bug,这里特殊情况就不做深研)

提升css优先级小技巧

在实际开发中难免会遇到需要重置样式的需求,比如.box(color: #999),现在需要变成color: #eee,通常通过嵌套方式.parent .box{ color: #eee }来重置,但这种方法过于依赖父级类名,耦合性过高。

推荐方法:

1、新增一个class,通过两个class来说增加优先级 .box.bar{ }

2、重复自身class,通过.box.box{ }来增加优先级

3、设置一个必然存在属性来增加优先级,.box[class]{ }

以上方法可根据实际情况选择适合方案来解决优先级问题。

结束语

好了,现在我们可以通过计算css语句的优先级值来判断哪个优先级更高,但是所有的知识都应该建立在规范的开发上面,一个糟糕的CSS书写习惯,学再好的知识也避免不了样式冲突的问题。

参考文献:

1、https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity

2、张鑫旭《css选择器世界》第二章

Tags:

最近发表
标签列表