CSS结构和层叠

每个合法的文档都会生成一个文档树,从而能根据元素的祖先,属性,兄弟元素等创建选择器来选择元素。有了这个结构树,选择器才能起作用,这也是CSS继承的核心。继承是从一个元素向其后代元素传递属性值所采用的机制。确定应当向一个元素应用哪些值时,用户代理不仅要考虑继承,还要考虑声明的特殊性,另外需要考虑声明本身的来源,这个过程称为层叠。

1.特殊性 每个选择器都有特殊性,对于每个规则,用户代理会计算选择器的特殊性,并将这个特殊性附加到规则中的各个声明。若一个元素有两个或多个冲突的属性声明,那么有最高特殊性的声明将胜出。

特殊性顺序 “important > 内联 > ID > 类| 伪类 | 属性选择 > 标签| 伪对象 > 通配符” > 继承


Selectors 选择符


Syntax Samples 语法


ensample 示例


Specificity 特性


通配选择符(Universal Selector)


*


*.div { width:560px;}


0,0,0,0


类型选择符(Type Selectors)


E1


td { font-size:12px;}


0,0,0,1


伪类选择符(Pseudo-classes Selectors)


E1:link


a:link { font-size:12px;}


0,0,1,0


属性选择符(Attribute Selectors)


E1[attr]


h[title] {color:blue;}


0,0,1,0


ID选择符(ID Selectors)


#sID


#sj{ font-size:12px;}


0,1,0,0


类选择符(Class Selectors)


E1.className


.sjweb{color:blue;}


0,0,1,0


子对象选择符(Child Selectors)


E1 > E2


body > p {color:blue;}


E1+E2


相邻选择符(Adjacent Sibling Selectors)


E1 + E2


div + p {color:blue;}


E1+E2


选择符分组(Grouping)


E1,E2,E3


.td1,a,body {color:blue;}


E1 E2 E3


包含选择符(Descendant Selectors)


E1 E2


table td {color:blue;}


E1+E2

2.重要性 有时某个声明可能很重要,超过了所有其他声明,CSS2.1称之为重要声明,并允许在这些声明的结束分号之前插入!important来标志。 标志为!important的声明并没有特殊的特殊性值,不过要与非重要声明分开考虑。实际上,所有!important声明会分组在一起,重要声明的特殊性冲突会在重要声明内部解决,而不会与非重要声明相混。类似地,我们认为所有非重要声明也归为一组,使用特殊性来解决冲突。若一个重要声明和一个非重要声明冲突,胜出的总是重要声明。 3.继承 基于继承机制,样式不仅应用到指定的元素,还会应用到它的后代元素。继承是CSS中最基本的内容,除非有必须,否则一般不会特别考虑。不过需要注意以下几点: 1)注意有些属性不能被继承,这往往归因于一个简单的常识。一般地,大多数框模型属性(包括外边距,内边距,背景和边框)都不能被继承。 2)继承的值根本没有特殊性,甚至连0特殊性都没有。如下:

Java代码  

  1. *{color:gray;}
  2. h1#page-title{color:black;}
  3. <h1 id="page-title">Meetkat <em>CEntral</em><h1>
  4. <p>Welcome to the best place on the web</p>

因为通配选择器适用于所有元素,而且有0特殊性,其颜色声明指定的值gray要优先于继承值(black),因为继承值根本没有特殊性。故em元素会显示为灰色而不是黑色。 4.层叠 CSS所基于的方法是让样式层叠在一起,这是通过继承和特殊性做到的,CSS2.1的层叠规则如下: 1)找出所有相关的规则,这些规则都包含与一个给定元素匹配的选择器 2)按显式权重对应用到给定元素的所有声明排序。标志!important的规则的权重高于没有!important标志的规则。按来源对应用到给定元素的所有声明排序。共有3种来源:创作人员,读者,用户代理。正常情况下,创作人员的样式要胜于读者的样式表,有!important标志的读者样式要强于所有其他样式,这包括有!important标志的创作人员样式。创作人员样式和读者样式都比用户代理的默认样式要强。 3)按特殊性对应用到给定元素的所有声明排序。有较高特殊性的元素权重重要大于较低特殊性的元素。 4)按出现顺序对应用到给定元素的所有声明排序。一个声明在样式表或文档中越后出现,它的权重就越大。如果样式表中有导入样式表的话,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。 接下来对2)3)4)详细说明: 2)按权重和来源排序 若两个样式规则应用到同一个元素,而且其中一个规则有!important标志,这个重要规则将胜出。在声明权重方面要考虑5级,权重由大到小的顺序依次为: 1.读者的重要声明 2.创作人员的重要声明 3.创作人员的正常声明 4.读者的正常声明 5.用户代理声明 3)按特殊性排序若 若向一个元素应用多个彼此冲突的声明,而且它们的权重相同,则要按特殊性排序,最特殊的声明最优先。 4)按顺序排序 若两个规则的权重,来源和特殊性完全相同,那么在样式表中后出现的一个会胜出。特别地,认为元素style属性中指定我样式位于文档样式表的最后,即放在所有其他规则的后面。不过,这一点已经没有意义了,因为CSS2.1明确指明内联样式的特殊性要高于所有样式表选择器。 正是由于这种按顺序排序,所以才有了通常推荐的链接样式顺序:link-visited-hover-active(LVHA)。

Java代码  

  1. :link{color:blue;}
  2. :visited{color:purple;}
  3. :hover{color:red;}
  4. :active{color:orange;}

这四个选择器的特殊性都是一样的:0,0,1,0。因为它们有相同的权重,来源,特殊性,故与元素匹配的最后一个选择器才会胜出。 正在“点击”的未访问链接可以与其中3个规则匹配——:link,:hover,:active——所以在这三个规则当中最后声明的一个胜出。若按照LVHA顺序,:active将会胜出,这也正是所期望的。 5.非CSS表现提示 文档有可能包含非CSS的表现提示,例如font元素。非CSS提示被处理为特殊性为0,并出现在创作人员样式表的最前面。只要有创作人员或读者样式,这种表现提示就会被覆盖,但用户代理的样式不能将其覆盖。

注意:

1. 行内样式优先级Specificity值为1,0,0,0,高于外部定义。

如:<div style=”color: red”>sjweb</div>

外部定义指经由<link>或<style>标签定义的规则;

2.!important声明的Specificity值最高;

3.Specificity值一样的情况下,按CSS代码中出现的顺序决定,后者CSS样式居上;

4.由继续而得到的样式没有specificity的计算,它低于一切其他规则(比如全局选择符*定义的规则)。

5.由于它能匹配任何元素,所以通配选择器往往有一种短路继承的效果。

6..当遇到多个选择符同时出现时候,按选择符得到的Specificity值逐位相加{数位之间没有进制 比如说: 0,0,0,5 + 0,0,0,5 =0,0,0,10 而不是 0,0, 1, 0}就得到最终计算得的specificity,然后在比较取舍时按照从左到右的顺序逐位比较。

-----------以上内容都是权重理论上的知识,按理说支持css2.1的浏览器应该都遵循----------------- IE6和IE7却不完全是那么回事;这里说的IE7排除掉IE8的兼容模式。

Java代码  

  1. a { /* 权重为[0,0,1] */
  2. color: #00f;
  3. background-color: #ff0;
  4. }
  5. a:hover { /* 权重为[0,1,1] */
  6. color: #ff0;
  7. background-color: #00f;
  8. }
  9. 这是基础样式:蓝色字,黄色背景,鼠标悬停的时候颜色颠倒

接下来,添加规则

Java代码  

  1. p a.cl1 { /* 权重为[0,1,2] */
  2. color: #f00;
  3. background-color: #0ff;
  4. }
  5. <p><a class="cl1" href="#">...</a></p>

红色字,浅绿色背景,权重为 [0,1,2], 比第一条权重高

在IE6下”normal” (not hover) 的值被覆盖了, 但是没有覆盖”hover”的值. 换句话说,权重为[0,1,1]的”hover”依然生效, 它没有被比他权重高的p a.cl1 [0,1,2]所覆盖 (但是没有定义:hover伪类)

Java代码  

  1. .cl2 a.cl3 { /* 权重为 [0,2,1] */
  2. color: #f00;
  3. background-color: #0ff;
  4. }
  5. <p class="cl2"><a class="cl3" href="#">...</a></p>

红色字,浅绿色背景,权重为 [0,2,1], 比第一条规则”normal”和”hover”都要高现在在IE6下不管是”normal”还是”hover”的值都被覆盖了,这时候权重 [0,2,1] 完全覆盖了权重 [0,1,1]

Java代码  

  1. div p :hover { /* 权重为 [0,1,2] */
  2. color: #f00;
  3. background-color: #0ff;
  4. }
  5. <div><p><a href="#">...</a></p></div>

当鼠标悬停在链接上的时候是红色字,浅绿色背景 , 权重为 [0,1,2], 比第一条”hover”的权重 [0,1,1]高

第一条:hover完全被覆盖,IE6也是一样. 这个例子的权重 [0,1,2]和第二个例子的权重是一样的,但是它多了对 伪类:hover的定义就能完全覆盖第一条”hover”规则, 而第二个例子就不会覆盖 演示地址:IE6/Win: 关于伪类:hover的权重问题 IE6/win下伪类:visited也存在类似问题,不再赘述,演示地址:IE6-/Win: 关于伪类:visited的权重问题

还有其他一些,在IE67下都会产生错误权重的情况,其他浏览器有条件的请帮忙测试一下: 情况一:

Java代码  

  1. p.c12 {/* 权重为[0.1.1] */
  2. color: #c00;
  3. }
  4. div .c12 {/* 权重为[0.1.1] */
  5. color: #090;
  6. }
  7. <div><p class="c12">el.class (red), el .class (green)  (错误显示 IE67/Win, IE/Mac and Op7-显示为红色)</p></div>

如果顺序换过来el .class (red), el.class (green),就是正确的了

情况二:

Java代码  

  1. div .c24 {/* 权重为[0.1.1] */
  2. color: #009900;
  3. }
  4. .c23 p {/* 权重为[0.1.1] */
  5. color: #CC0000;
  6. }
  7. <div class="c23"><p class="c24">.class el (red), el .class (green)  (错误显示 IE67/Win, IE/Mac and Op7-显示为红色)</p></div>

如果顺序换过来el .class (red), .class el (green),就是正确的了

情况三:

Java代码  

  1. div #c28 {/* 权重为[1.0.1] */
  2. color: #009900;
  3. }
  4. #c27 p {/* 权重为[1.0.1] */
  5. color: #CC0000;
  6. }
  7. <div id="c27"><p id="c28">#id el (red), el #id (green)  (错误显示 IE67/Win, IE/Mac and Op7-显示为红色)</p></div>

如果顺序换过来el #id (red), #id el (green),就是正确的了

:first-letter使用的比较少,这个例子就不写了

情况四:

p.c31 {/* 权重为[0.1.1] */ color: #c00;/* red */ } body p.c31 {/* 权重为[0.1.2] */ color: #090;/* green */ color: miao; /* 故意的错误 */ } <p class="c31">在IE67下会错误显示红色</p>

演示地址:其他权重错误

下面来看下!important 这个诡异的东西。

1 <style type="text/css">  2  div{background: red !important; background: blue} 3 </style> ­

除了IE6,其他浏览器都会显示背景为红色,正是!important的作用,意思就是只要我在这里我就是最重要的啦,任何东西都不能取代我,没看见都是一个 !外加一个英文单词 important 吗?很形象,很贴切了。IE6这里会显示背景为蓝色,并不是IE6不支持!important,而是它会按照样式声明顺序后出现的覆盖前面的,此时它已经不认识!important了,它六亲不认了。这正是广为流传的IE6 hack之一。而如果这样写会正常显示背景为红色:

1 <style type="text/css">  2 div{background: blue; background: red !important; } 3 </style> ­

再来看下4位特殊性标志 [0.0.0.0]
从左至右,每次给某一个位置+1,前一段对后一段具有无可辩驳的压倒性优势。无论后一位数值有多大永远无法超过前一位的1。
1,内联样式 [1.0.0.0] 
A:<span id="demo" ></span> B:还有就是JS控制的内联样式style对象,document.getElementByIdx("demo").style.color="red"; 这两者属于同一级别,不过一般情况是JS控制的内联样式优先级高,这与先后顺序申明有关系与本质无关,因为往往DOM操作是在DOM树加载完毕之后。
2,ID选择器 [0.1.0.0] 3,类,属性,伪类 选择器 [0.0.1.0] 4,元素标签,伪元素 选择器 [0.0.0.1]
关于CSS选择器可以查看W3C或者CSS的手册,不啰嗦了。 注意下 伪类选择器
LVHA伪类,样式按LVHA优先级顺序从右至左覆盖,不同的顺序会产生不同的效果。 a:link - 默认链接样式 a:visited - 已访问链接样式 a:hover - 鼠标悬停样式 a:active - 鼠标点击样式
最后写下关于JS控制内联样式 带!important的现象:
看下正常的Demo1:

1 <style type="text/css">  2 div{background: red !important; height:20px;}  3 #demo1{ background: green;}  4 .demo1{ background:blue;}  5 </style> ­

1 <div class="demo1" id="demo1" style="background: yellow"></div>

1<script type="text/javascript"> 2document.getElementByIdx("demo1").style.background="black";  3</script>

最终显示背景为红色,这应该不会有什么问题, !important 放到哪都会改变优先级的,而后面的JS代码也不会改变优先级。

另外一个Demo2:

1 <style type="text/css"> 2 div{background: red !important; height:200px;} 3 #demo2{ background: green;} 4 .demo2{ background: blue;} 5 </style> 6

1 <div class="demo2" id="demo2" style="background: yellow !important"></div>

1 <script type="text/javascript"> 2 document.getElementByIdx("demo2").style.background="black"; 3 </script>

IE6,7        显示 红色

FF2+        显示 黄色

Opera9+   显示 红色

Safari       显示 黄色

Demo3:

1 ­<style type="text/css"> 2 div{background: red !important; height:200px;} 3 #demo3{ background: green;} 4 .demo3{ background: blue;} 5 </style>

1 <div class="demo3" id="demo3" style="background: yellow !important"> </div>

1 ­<script type="text/javascript"> 2 document.getElementByIdx("demo3").style.background="black !important"; 3 </script>

IE6,7       显示红色

FF2+       显示黄色

Opera9+  显示黑色

Safari      显示黑色

解释下上面两个例子:

JS控制的style对象 实际就是内联样式style,这个没错

但是对于 JS控制style对象属性值里增加的!important 三个浏览器却给出了不同的结果:

IE:JS控制style对象属性值完全覆盖内联style属性值,不支持Element.style.property="value !important",将报错:参数无效。
FF2+:不完全支持 Element.style.property="value !important" : !important无效,不会报错, 如果内联style属性值无!important,则完全覆盖,有!important 则内联style属性优先级最高,不会受JS控制style的任何影响。
Opera9+ :JS控制style对象属性值完全覆盖内联style属性值,支持Element.style.property="value !important"。
Safari:支持Element.style.property="value !important" ,如果内联style属性值无!important,则完全覆盖,有!important 则内联style属性优先级最高,不会受JS控制style的任何影响。

这一部分规则为我们提供了解决CSS优先级最万能的方法: !important ,遇到无法解决的CSS优先级问题请考虑使用!important。另外请注意IE6的BUG,在使用!important的时候需要把!important写在此行CSS规则的末尾,否则将无法生效,如: .zhongsou {font-size:18px !important; font-size:12px;} IE6下!important将被忽略,字号为12px;其他浏览器显示字号为18px。 .zhongsou {font-size:12px; font-size:18px !important;} 所有浏览器显示字号为18px。

参考文献:http://blog.csdn.net/bill200711022/article/details/7882033

http://www.cnblogs.com/yizuierguo/archive/2009/03/16/1413721.html

[教程] css2.1的权重(specificity)在IE6/7下的一些错误规则

http://bbs.blueidea.com/thread-3030468-1-1.html

http://blog.sina.com.cn/wangfengteacher

css权威指南(第三版)

时间: 2024-10-28 15:21:01

CSS结构和层叠的相关文章

深入理解CSS中的层叠上下文和层叠顺序(转)

by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时

[转]深入理解CSS中的层叠上下文和层叠顺序

http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/ 零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时候,显

深入理解CSS中的层叠上下文和层叠顺序

零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时候,显然,是不可能做到完全等同的,先后顺序,身份差异就显现出来了.例如,杰克和罗斯,只能一人浮在木板上,此时,出现了冲突,结果大家都知道的.那对于CSS世界中的元素而言,所谓的“冲突”指什

初学者用div+css结构写网页的几个误区

1.用div+css结构制作静态html网页不等于彻底抛弃古老的table写法.之所以不建议用table来布局网页是因为在网页加载很慢的时候要等table结构加载完成才能看到网页,其次是table的布局没有一定的语义,网页代码修改起来比较麻烦. 在写一些栏目块时,特别是数据分类较多,比如“求购信息”的栏目块,顶部可能出现“发布人.发布时间.信息标题.联系方式”等项目,像这样的地方建议还是要用table来写,因为table是专门用来写数据表格的,控制起来很方便,而且符合语义要求,还有页面中出现类似

css优先级和层叠

css优先级和层叠 1.优先级    计算方法:        a.行内样式        b.id选择器的数量        c.类,伪类和属性选择器的数量        d.标签选择器和伪元素选择器的数量    假设a,b,c,d的权重分别为1000,100,10,1    那么有: 2.css层叠 了解了css的优先级,这时候我们就不得不提css中的层叠(此时考虑的还不涉及到z-index),我们应该知道如下几点:        1.当优先级相同,属性名相同时,后面的样式会覆盖前面的样式 

[读书笔记] CSS权威指南2: 结构和层叠

层叠样式表中最基本的一个方面可能就是层叠——冲突的声明要通过这个层叠过程排序,并由此确定最终的文档表示.这个过程的核心是选择器及其相关声明的特殊性,以及继承机制. 特殊性 对于每个规则,用户代理会计算选择器的特殊性,并将这个特殊性附加到规则中的各个声明.如果一个元素有两个或多个冲突的属性声明,那么有最高特殊性的声明就会胜出. 选择器的特殊性由选择器本身的组件确定.特殊性值表述为4个部分,如:0,0,0,0.一个选择器的具体特殊性如下确定: 对于选择器中给定的各个ID属性值,加0,1,0,0. 对

css 权威指南笔记( 五)结构和层叠之三种样式来源

CSS中的样式一共有三种来源:创作人员.读者和用户代理,来源的不同会影响到样式的层叠方式 首先,创作人员(author's+style)样式应该是我们最熟悉的,如果你是一个前端开发者,那么你写的那些样式就叫做创作人员样式. 然后是用户代理样式(agent's+style),用户代理也就是我们通常所说的浏览器(IE.Firefox等等),这些浏览器会提供一些默认的样式,比如IE浏览器中,一个纯粹由html代码构成的网页里,我们会发现超链接会带有一个蓝色的前景色,这其实就用户代理样式,借用一些插件我

《CSS权威指南(第三版)》---第三章 结构和层叠

这章主要讲的是当某个对象被选择器多次提取使用样式之后的一些冲突性解决方案: 1.特殊性:指的是当多个效果作用的时候的最终选择: 这个规则用0,0,0,0来比较.其中:内联式是1,0,0,0  ID选择器是0,1,0,0 类选择器,属性选择器和伪类:0,0,1,0 元素和伪元素:0,0,0,1 结合性和通配性对特殊性没有贡献,是0,0,0,0 注意:这里面给出一个特权,某个声明特别重要的时候使用!import 那么它的优先级是最高的. 2.继承:指的是在节点树中,子元素的样式继承父元素. 注意:继

css细节复习笔记——结构与层叠

每个合法的文档都会生成一个结构树,有了结构树元素的祖先.属性兄弟元素等等创建选择器来选择元素,这是CSS继承的核心.继承是从一个元素向后代元素传递属性值所采用的机制.面向一个元素使用哪些值时,用户代理不仅要考虑继承,还要考虑特殊性,另外需要考虑声明本身的来源,这个过程就叫层叠. 本文讨论3种机制之间的关联:特殊性.继承和层叠. 特殊性 同一元素可以使用不同的方法来选择元素.但是每个规则,用户代理会计算选择器的特殊性,并将这个特殊性附加到规则的个个声明.如果一个元素有两个或多个冲突的属性声明,那么