深入理解CSS选择器优先级
题外话
今天把 《CSS REFACTORING》(中文名叫《CSS重构:样式表性能调优》)电子书粗略的浏览了一遍,这本书很薄,150页左右,首先是介绍了什么是重构并举了两个简单的重构例子,然后介绍了CSS的选择器优先级,再然后介绍了CSS的最佳实践, 再然后就介绍如何重置浏览器的默认样式,最后比较虚的、纯理论的介绍了CSS重构的策略,然后就没有然后了。这书整体内容很简单,但是,其中对于 CSS选择器优先级计算
作了比较深入的讲解。
什么是选择器优先级(Specificity)
直接复制了MDN对优先级的定义 上的解释:
浏览器通过优先级来判断哪一些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。
这句话也是很抽象,暂且先不管它了。但是我们可以先看一个例子:
- HTML:
<div id="content" class="content">
我是什么颜色
</div>
- CSS:
#content {
color: #f00;
}
.content {
color: #0f0;
}
那最后文字是什么颜色呢?答案很简单:红色。这就涉及到了优先级问题,同一块内容,我们同时用了 ID选择器
和 类选择器
,因为 ID选择器
优先级大于 类选择器
, 所以最终显示为红色。
优先级的计算规则
相信每位写过CSS的朋友都知道,CSS选择器的优先级关系是:
内联 > ID选择器 > 类选择器 > 标签选择器。
但是,浏览器具体的优先级算法是怎样的?可能还有些人不知道 。《CSS REFACTORING》 中提到了算法的过程 。
A specificity is determined by plugging numbers into (a, b, c, d):
- If the styles are applied via the style attribute, a=1; otherwise, a=0.
- b is equal to the number of ID selectors present.
- c is equal to the number of class selectors, attribute selectors, and pseudoclasses present.
- d is equal to the number of type selectors and pseudoelements present.
翻译过来就是
优先级是由 A
、B
、C
、D
的值来决定的,其中它们的值计算规则如下:
- 如果存在内联样式,那么
A = 1
, 否则A = 0
; B
的值等于ID选择器
出现的次数;C
的值等于类选择器
和属性选择器
和伪类
出现的总次数;D
的值等于标签选择器
和伪元素
出现的总次数 。
这样子直接看好像也还是很明白 ,那先上个例子:
#nav-global > ul > li > a.nav-link
套用上面的算法,依次求出 A
B
C
D
的值:
- 因为没有内联样式 ,所以
A = 0
; - ID选择器总共出现了1次,
B = 1
; - 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出现0次,所以
C = (1 + 0 + 0) = 1
; - 标签选择器出现了3次, 伪元素出现了0次,所以
D = (3 + 0) = 3
;
上面算出的A
、 B
、C
、D
可以简记作:(0, 1, 1, 3)
。
为了熟悉掌握优先级算法 ,我们再来做一些练习:
li /* (0, 0, 0, 1) */
ul li /* (0, 0, 0, 2) */
ul ol+li /* (0, 0, 0, 3) */
ul ol+li /* (0, 0, 0, 3) */
h1 + *[REL=up] /* (0, 0, 1, 1) */
ul ol li.red /* (0, 0, 1, 3) */
li.red.level /* (0, 0, 2, 1) */
a1.a2.a3.a4.a5.a6.a7.a8.a9.a10.a11 /* (0, 0, 11,0) */
#x34y /* (0, 1, 0, 0) */
li:first-child h2 .title /* (0, 0, 2, 2) */
#nav .selected > a:hover /* (0, 1, 2, 1) */
html body #nav .selected > a:hover /* (0, 1, 2, 3) */
OK, 现在已经弄清楚了优先级是怎么算的了。但是,还有一个问题,怎么比较两个优先级的高低呢?
比较规则是: 从左往右依次进行比较 ,较大者胜出,如果相等,则继续往右移动一位进行比较 。如果4位全部相等,则后面的会覆盖前面的
再来看一下例子:
- html:
<div class="nav-list" id="nav-list">
<div class="item">nav1</div>
<div class="item">nav2</div>
</div>
- CSS:
#nav-list .item {
color: #f00;
}
.nav-list .item {
color: #0f0;
}
算出 #nav-list .item
的优先级是 (0, 1, 1, 0)
, .nav-list .item
的优先级是 (0, 0, 2, 0)
。 左边第一位都是0, 再看看左边第二位,前者是1,后者是0, 所以(0, 1, 1, 0)
的大于 (0, 0, 2, 0)
,即 #nva-list .item
大于 .nav-list .item
,所以字体会是红色。
优先级的特殊情况
经过上面的优先级计算规则,我们可以知道内联样式的优先级是最高的,但是外部样式有没有什么办法覆盖内联样式呢?有的,那就要 !important
出马了。因为一般情况下,很少会使用内联样式 ,所以 !important
也很少会用到!如果不是为了要覆盖内联样式,建议尽量不要使用 !important
。、
那可能有人会想,那如果我内联样式用了 !important
,是不是外部样式就没有办法了呢?比如下面的代码:
- HTML:
<div class="app" style="color:#f00!important">666</div>
- CSS:
.app {
color: 0f0!important;
}
是的,你赢了,这时候内联样式已经强大到不管你外部样式怎么写都无法覆盖它了。这种情况在实际代码中是要杜绝的!记住,千万不要在内联样式中使用 !important
最后 , !important
真的是的无法超越的王者吗?其实不是的,一些情况,我们可以超越 !important
, 请看下面的例子:
- html:
<div class="box" style="background: #f00; width: 300px!important;"><div>
- css:
.box {
max-width: 100px;
}
这时候 .box
的宽度只有 100px
, 而不是 300px
, 可见,max-width
可以超越 width!important
!但是,这实际上不是优先级的问题,因为优先级是比较相同属性的,而 max-width
和 width
是两个不同的问题。之所以举这个例子,是要告诉大家,有时候不管怎么设置容器的 width
都不生效,检查一下是不是有人写了 max-width
坑了你哈。
OK,优先级先写到这里啦,朋友们有问题欢迎留言讨论~
深入理解CSS选择器优先级的更多相关文章
- 深入理解CSS选择器优先级的计算
选择器的优先级关系到元素应用哪个样式.在CSS2.1的规范(http://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#specificity)中是 ...
- 关于Css选择器优先级
今天练习css的时候,重叠后的style发现不起作用,原来css选择器优先级大有文章. 声明: yi下内容选自 51cto.com --加以自己的理解 以备日后参照使用,毕竟自己理解的才是自己的. ...
- CSS选择器优先级(转)
原文:http://www.cnblogs.com/wangfupeng1988/p/4285251.html 另外,w3c有文章介绍了CSS选择器的特定性,见https://www.w3.org/T ...
- day44:CSS选择器优先级&JS基础
目录 1.CSS选择器优先级 2.补充:margin是可以设置百分比的 3.JS 3.1 js代码的引入方式 3.2 变量 3.3 数据类型 3.4 数组(类似于python中的列表) 3.5 自 ...
- 看完就懂--CSS选择器优先级的计算
CSS选择器优先级的计算 什么是选择器的优先级 优先级的计算与比较(一) - 优先级具有可加性 - 选择器优先级不会超过自身最大数量级 - 同等优先级情况下,后写的覆盖前写的 - 并集选择器之间的优先 ...
- CSS选择器优先级总结
CSS三大特性-- 继承. 优先级和层叠. 继承:即子类元素继承父类的样式; 优先级:是指不同类别样式的权重比较; 层叠:是说当数量相同时,通过层叠(后者覆盖前者)的样式. css选择符分类 首先来看 ...
- CSS选择器优先级 CSS权值
计算指定选择器的优先级:重新认识CSS的权重 标签的权值为 0,0,0,1 类的权值为 0,0,1,0 属性选择的权值为 0,0,1,1 ID的权值为 0,1,0,0 important的权值为最高 ...
- 导航栏布局时遇到的问题以及解决办法 css选择器优先级
得到的导航栏效果 添加#menu ul li{width:30px;} 效果如图 将会使列表项和分隔区域的宽度同时改变因为id选择器的优先级高于类选择器,此时应该为列表项添加内联样式如图 才能得到如下 ...
- 前端CSS css引入方式 css选择器 css选择器优先级
一. CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素,给HTML设置样式,让它更加美观. 当浏览器读到一个样式表,它就会按照这个样式表 ...
随机推荐
- python builtin列表
Python Builtin function获得通过 python3 -c "import builtins;ff=open('test.txt','w');strlist=[(i+'\n ...
- vue 中生成二维码之爬坑之路
最近在做vue中项目,有个需求是在你提交信息后把后台返给你的链接生成二维码. 一共使用了两种生成二维码的方法 1.vue-qr 这个是在一进入页面直接生成二维码,具体介绍见文档:https://www ...
- 前端开发【第三篇: JavaScript基础】
JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一.如何编写 1.J ...
- java面向对象编程(七)--四大特征之多态
1.多态概念 多态性是对象多种表现形式的体现.比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫.小狗.蜥蜴等等.那么我到宠物店说"请给我一只宠物&quo ...
- 【原创】Aduino小车玩法全记录
本来打算用一周时间好好研究下基于Arduino开发板的小车实验,结果实际上两天就完成了小车可玩的各种功能,包括完成特定动作组合,黑线循迹,(带后退)红外避障和(带舵机)超声波避障,超声波测距,红外遥控 ...
- L2-013 红色警报 (25 分)
L2-013 红色警报 (25 分) 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全 ...
- Linux 驱动——Button驱动4(fasync)异步通知
button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...
- JS里浮点数的运算
//浮点数加法运算 function FloatAdd(arg1,arg2){ var r1,r2,m; try{r1=arg1.toString().split(".")[1]. ...
- Power BI 3-4月功能更新培训合集
Power BI 3-4月功能更新培训合集 Power BI每月功能的更新,都有很多大咖精辟解读,我们一直也都是积极中期待,相信所有P友如是或更甚. 视频学习可以结合微软Power BI 3-4月文 ...
- elasticsearch(es) 集群恢复触发配置(Local Gateway参数)
elasticsearch(es) 集群恢复触发配置(Local Gateway) 当你集群重启时,几个配置项影响你的分片恢复的表现. 首先,我们需要明白如果什么也没配置将会发生什么. 想象一下假设你 ...