CSS三种写法的优先级
在HTML文件中引入CSS样式有三种方法:
- 外部样式:通过link标签引入CSS样式;
- 内页样式:写在HTML页面里面的style标签里面;
- 行内样式:写在对应标签的style属性里面。
我知道一般情况下使用外部样式,减少代码冗余,同时便于后期维护。但如果同时用三种方式引入相同的CSS样式,谁的优先级更高呢?
就做了个小测试:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"/>
<title>css样式优先级</title>
<link href="index.css" rel="stylesheet" type="text/css"/>
<style type="text/css">
.box{
background:red;
border:1px solid black;
width:100px;
height:100px;
}
</style>
</head>
<body>
<div style="background:yellow;width:100px;height:100px;" class="box"> </div>
</body>
</html>
外部CSS样式代码:
.box{
width:100px;
height:100px;
background:blue;
}
- 外部样式:blue
- 内页样式:red
- 行内样式:yellow
最后显示的效果是:

把行内CSS的背景样式去掉后,显示:

可见,CSS三种位置写法的优先级是:行内样式>内页样式>外部样式
从CSS代码存放位置看权重优先级:内嵌样式 > 内部样式表 > 外联样式表。其实这个基本可以忽视之,大部分情况下CSS代码都是使用外联样式表。
从样式选择器看权重优先级:important > 内嵌样式 > ID > 类 > 标签 | 伪类 | 属性选择 > 伪对象 > 继承 > 通配符。
- important的权重为1,0,0,0
- ID的权重为0,1,0,0
- 类的权重为0,0,1,0
- 标签的权重为0,0,0,1
- 伪类的权重为0,0,1,0
- 属性的权重为0,0,1,0
- 伪对象的权重为0,0,0,1
- 通配符的权重为0,0,0,0
id 的选择器为什么要这么写 li#first?
一. 一个疑问?
看到过一篇关于 CSS 的文章,其中说到:对于类似 li#first 这样的选择器,由于使用 id 就已经可以确定元素了,没有必要再写上前面的 li, 直接写上 #first 这样的 id 选择器就可以了。听起来说得不错,简单测试一下也没有问题。
可是,我们经常看到带有元素名称的选择器,例如,在微软的项目模板中就有大量的带有元素名称的选择器,如果没有用的话,为什么要这样写呢?

ul#navlist
{
float: right;
} ul#navlist li
{
display: inline;
}

二. 问题出现了!
写一个简单的菜单,使用 ul 和 li 实现,菜单项之间使用边框来实现间隔线。
html 代码如下:

<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li><a href="#">Store</a></li>
<li><a href="#">ShoppingCart</a></li>
<li><a href="#">Admin</a></li>
</ul>

使用下面的样式表,首先通过为所有的超级链接增加一个左边框来画出间隔的虚线,然后将第一个菜单项的左边框去掉,我的第一个样式使用了 .first a。
ul#navlist li{ display: inline;} ul#navlist li a{ border-left: 1px dotted #8A8575; padding: 10px; margin-top: 10px; color: #8A8575; text-decoration: none; float: left;} .first a{ border: none;} |
看一下效果,完全没有反应。

还有的地方说 id 选择器的级别比较高,那么将类改成 id 。
<li id="first"><a href="/" id="current">Home</a></li> |
将样式表也进行相应的修改。
#first a{ border: none;} |
可是结果呢?岿然不动!

用火狐的 firebug 看一看,被忽略了。

三. 探源
为什么我的样式被秒杀了?
网上有大量的文章,但是说法并不一致,有的说要考虑三个级别,可是也有的说需要考虑四个级别,但是总的方向大致是关于层叠的。
不如到 W3C 的网站上看一个究竟。相关的标准在 这个页面 可以看到,目前为止的 CSS 标准有三个: CSS1, CSS2, 以及 CSS3。
CSS1 是最早的标准,其中关于层叠顺序的描述在 这里,还提供了一个简单的示例进行说明。
LI {...} /* a=0 b=0 c=1 -> specificity = 1 */UL LI {...} /* a=0 b=0 c=2 -> specificity = 2 */UL OL LI {...} /* a=0 b=0 c=3 -> specificity = 3 */LI.red {...} /* a=0 b=1 c=1 -> specificity = 11 */UL OL LI.red {...} /* a=0 b=1 c=3 -> specificity = 13 */#x34y {...} /* a=1 b=0 c=0 -> specificity = 100 */ |
在 CSS1 中将优先级分为三组,将 id 选择器作为 a 组,类选择器作为 b 组,元素名作为 c 组,每组中出现一次,计数一次,按照先 a 组进行比较,相同的情况下,使用 b 组进行比较,最后是 c 组。什么选择器的优先级别高,什么选择器提供的样式有效。比如在上面的例子中,第 5 组使用 id 的级别最高,所以,这组的样式设置生效,而其他的设置将会被忽略掉。
在 CSS2 中,又增加了关于行内说明 style 的组,所以参与比较的组成为了 4 组,其中 style 的优先级别最高。同样,在 CSS2 的标准说明中也提供了样例。
* {} /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */<br><br> |
<style type="text/css"> #x97z { color: red }</style><p id="x97z" style="color: green"></p>在这个示例中,style 的优先级别最高,所以将会覆盖掉通过 id 进行的设置,颜色为绿色。
四. 解决问题
通过上面的分析可以看到,仅仅提供选择器并不足以能够生效,还要看选择器的优先级别,在我们的问题中,即使使用 id 来选择第一个菜单项:#first a ,包括了一个 id 和一个元素名,那么所得的优先级别为:
a=0, b=1, c=0, d=1
可是,通用的选择器是这样的:ul#navlist li a,优先级中却包括了一个 id, 还有 3 个元素名称,所以优先级别为:
a=0, b=1, c=0, d=3
所以我们的选择器没有比过通用的选择器,悲剧发生了!
知道了原因,问题也就简单了,提高我们选择器的优先级别,超过通用选择器的优先级就可以了,比如,我们可以写成这样:
ul#navlist li#first a |
现在的优先级是多少呢?
a=0, b=2, c=0, d=3
在 b 组比较的时候就已经超过了,看看是否已经成功了!

还可以加上重要性说明,也可以解决。!important 必须写在样式与分号之间,每个样式必须单独声明。
#first a{ border: none !important;} |
看来选择器不是那么简单呀!
------------------------
感谢司徒正美的奉献,转载地址:http://www.cnblogs.com/rubylouvre/archive/2012/09/26/2524700.html
CSS三种写法的优先级的更多相关文章
- 设置css三种方法的优先级
有的小伙伴问了,如果有一种情况:对于同一个元素我们同时用了三种方法设置css样式,那么哪种方法真正有效呢?在下面代码中就出现了这种情况 1.使用内联式CSS设置“超酷的互联网”文字为粉色. 2.然后使 ...
- css三种样式表写法
css三种样式表:1.内嵌样式表: <head> <style type="text/css"> 样式表写法 </style> < ...
- Python 45 css三种引入方式以及优先级
一:css三种引入方式 三种方式为:行间式 | 内联式 | 外联式 行间式 1.在标签头部的style属性内 2.属性值满足的是css语法 3.属性值用key:value形式赋值,value具 ...
- css三种引入方式以及其优先级的说法
css 三种引入方式 方式一:行间式 1.在标签头部的style属性内 2.属性值满足css语法 3.属性值用key:value形式赋值,value具有单位 4.属性值之间用 分号 : ...
- 006 CSS三种引入方式
CSS三种引入方式 一.三种方式的书写规范 1.行间式 <div style="width: 100px; height: 100px; background-color: red&q ...
- 链接属性rel=’external’、rel=’nofollow’、rel=’external nofollow’三种写法的区别
链接属性rel='external'.rel='nofollow'.rel='external nofollow'三种写法的区别 大家应该都知道rel='nofllow'的作用,它是告诉搜索引擎, ...
- jquery 在页面中三种写法
jQuery 分 2 个系列版本 1.x 与 2.x,主要的区别在于 2.x 不再兼容 IE6.7.8浏览器,这样做的目的是为了兼容移动端开发.由于减少了一些代码,使得该版本比 jQuery 1.x ...
- 总结 React 组件的三种写法 及最佳实践 [涨经验]
React 专注于 view 层,组件化则是 React 的基础,也是其核心理念之一,一个完整的应用将由一个个独立的组件拼装而成. 截至目前 React 已经更新到 v15.4.2,由于 ES6 的普 ...
- CSS三种样式
CSS 指层叠样式表 (Cascading Style Sheets): 1 内联样式:无法复用,在元素style内写 ,很少使用: 2 内部样式:在head元素内style属性内写,此样式可以被当前 ...
随机推荐
- js知识点
在变量复制方面,基本类型和引用类型也有所不同,基本类型复制的是值本身,而引用类型复制的是地址. 循环引用 一个很简单的例子:一个DOM对象被一个Javascript对象引用,与此同时又引用同一个或其它 ...
- spring quartz 配置实现定时任务 详解
一. 编写定时任务JAVA类 比如: public class QuartzJob { public QuartzJob(){ System.out.println(" ...
- 部署Thomas Kyte 的 runstats 工具
runstats是由Thomas Kyte开发的脚本,该脚本能对做同一件事的两个不同方法进行比较,得出孰优孰劣的结果. 1.授权 SQL> grant select on v_$statname ...
- C# Json传值与解析
最近接触了工作室的项目,觉得一个功能的实现有点不好,心想不能就动手改了下,做了才知道我的js是多么的渣,功能是这样的: 我要实现的功能就是当选择学院时,就放松get请请求到后台,后台返回json信息再 ...
- 20145337 GDB调试汇编堆栈过程分析
20145337 GDB调试汇编堆栈过程分析 测试代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const ...
- 浏览器中CSS的BUG
对于web2.0的过度,请尽量用xhtml格式写代码,而且DOCTYPE 影响 CSS 处理,作为W3C的标准,一定要加 DOCTYPE声明. 其它请参考:CSS hack 针对IE6,IE7,fir ...
- Quartz 2D在ios中的使用简述二:创建画布
在iOS中使用Quartz画图时,第一步就是要获取画布(图形上下文),然后再画布上做各种操作.先看下CoreGraphics.h这个头文件,就可以知道能够创建多少种上下文类型. #include &l ...
- Linux堆内存管理深入分析(上)
Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全 0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...
- 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)
前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...
- MySQL 主主复制
200 ? "200px" : this.width)!important;} --> 介绍 环境 OS:CentOS 6.7,MySQL 5.6 Master:192.16 ...