解读CSS的优先级

2010-10-20 16:34:20

<p>首先,我们对CSS作一个简单的说明:CSS是层叠样式表(Cascading Style Sheets)的简称。它的规范代表了互联网历史上一个独特的发展阶段。现在对于从事网页制作的朋友来说,应该很少没有听说过CSS了,因为在制作网页过 程中我们经常需要用到。</p> <p>其次:我们能通过CSS为文档设置丰富且易于修改的外观,以减轻网页制作者的工作负担,从而减轻制作及后期维护的代价。</p> <p>其实现在还来讲CSS是什么,CSS有什么作用完全是多余的,相信从事网页制作的朋友都已经或多或少的接触过了。</p> <p>言归正传,我们开始进入今天的话题:</p> <p><strong>一、什么是CSS优先级?</strong></p> <p>所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序。</p> <p><strong>二、CSS优先级规则</strong></p> <p>既然样式有优先级,那么就会有一个规则来约定这个优先级,而这个&amp;ldquo;规则&amp;rdquo;就是本次所需要讲的重点。</p> <p>样式表中的特殊性描述了不同规则的相对权重,它的基本规则是:</p> <ol> <li>统计选择符中的ID属性个数。</li> <li>统计选择符中的CLASS属性个数。</li> <li>统计选择符中的HTML标记名个数。</li> </ol> <p>最后,按正确的顺序写出三个数字,不要加空格或逗号,得到一个三位数(css2.1是用4位数表示)。( 注意,你需要把数字转换成一个以三个数字结尾的更大的数)。相应于选择符的最终数字列表可以很容易确定较高数字特性凌驾于较低数字的。</p> <p>例如:</p> <ol> <li>每个ID选择符(#someid),加 0,1,0,0。</li> <li>每个class选择符(.someclass)、每个属性选择符(形如[attr=value]等)、每个伪类(形如:hover等)加0,0,1,0。</li> <li>每个元素或伪元素(:firstchild)等,加0,0,0,1。</li> <li>其它选择符包括全局选择符*,加0,0,0,0。相当于没加,不过这也是一种specificity,后面会解释。</li> </ol> <p><strong>三、特性分类的选择符列表</strong></p> <p>以下是一个按特性分类的选择符的列表:</p> <p> <table width=&#34;500&#34; cellspacing=&#34;0&#34; cellpadding=&#34;0&#34; border=&#34;1&#34;> <tbody> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-weight: bold; font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;><font>选择符</font></span></p> </td> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-weight: bold; font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;><font>特性值</font></span></p> </td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>h1 {color:blue;}</span></p> </td> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>1</span></p> </td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>p em&amp;nbsp;{color:purple;}</span></p> </td> <td>2</td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>.apple&amp;nbsp;{color:red;}</span></p> </td> <td>10</td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>p.bright&amp;nbsp;{color:yellow;}</span></p> </td> <td>11</td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>p.bright&amp;nbsp;em.dark&amp;nbsp;{color:brown;}</span></p> </td> <td>22</td> </tr> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;>#id316&amp;nbsp;{color:yellow}</span></p> </td> <td>100</td> </tr> </tbody> </table> </p> <p>单从上面这个表来看,貌似不大好理解,下面再给出一张表:</p> <p> <table width=&#34;500&#34; cellspacing=&#34;0&#34; cellpadding=&#34;0&#34; border=&#34;1&#34;> <tbody> <tr> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-weight: bold; font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;><font>选择符</font></span></p> </td> <td> <p class=&#34;0&#34; style=&#34;text-align: justify;&#34;><span style=&#34;font-weight: bold; font-size: 10.5pt; font-family: &#39;Times New Roman&#39;;&#34;><font>特性值</font></span></p> </td> </tr> <tr> <td>h1&amp;nbsp;{color:blue;}</td> <td>1</td> </tr> <tr> <td>p em&amp;nbsp;{color:purple;}</td> <td>1+1=2</td> </tr> <tr> <td>.apple {color:red;}</td> <td>10</td> </tr> <tr> <td>p.bright {color:yellow;}</td> <td>1+10=11</td> </tr> <tr> <td>p.bright em.dark {color:brown;}</td> <td>1+10+1+10=22</td> </tr> <tr> <td>#id316 {color:yellow}</td> <td>100</td> </tr> </tbody> </table> </p> <p>通过上面,就可以很简单的看出,HTML标记的权重是1,CLASS的权重是10,ID的权重是100,继承的权重为0(后面会讲到)。</p> <p>按这些规则将数字符串逐位相加,就得到最终的权重,然后在比较取舍时按照从左到右的顺序逐位比较。</p> <p>优先级问题其实就是一个冲突解决的问题,当同一个元素(内容)被CSS选择符选中时,就要按照优先级取舍不同的CSS规则,这其中涉及到的问题其实很多。</p> <p>说到这里,我们不得不说一下CSS的继承性。</p> <p>&amp;nbsp;</p> <div style=&#34;width: 610px; overflow: hidden;&#34;> <p><strong>四、CSS的继承性</strong></p> <p><strong>4.1 继承的表现</strong></p> <p>继承是CSS的一个主要特征,它是依赖于祖先-后代的关系的。继承是一种机制,它允许样式不仅可以应用于某个特定的元素,还可以应用于它的后代。例如一个BODY定义了的颜色值也会应用到段落的文本中。</p> <p>样式定义:</p> <p><span class=&#34;code&#34;>body {color:#f00;} </span></p> <p>举例代码:</p> <p><span class=&#34;code&#34;>&amp;lt;p&amp;gt;CSS&amp;lt;strong&amp;gt;继承性&amp;lt;/strong&amp;gt;的测试&amp;lt;/p&amp;gt; </span></p> <p>举例效果:</p> <p align=&#34;center&#34;><a href=&#34;http://img.68design.net/art/20090603/MdMpbosxQ6dSpKo.gif&#34; target=&#34;_blank&#34;><img border=&#34;0&#34; alt=&#34;&#34; src=&#34;http://img.68design.net/art/20090603/MdMpbosxQ6dSpKo.gif&#34; /></a></p> <p>这段代码的应用结果是:&amp;ldquo;CSS继承性的测试&amp;rdquo;这段话是红颜色的,&amp;ldquo;继承性&amp;rdquo;几个字由于应用了&amp;lt;strong&amp;gt;标签,所以是粗体。很显然,这段文字都继承了由body {color:#f00;}样式定义的颜色。这也就是为什么说继承性是CSS的一部分。</p> <p>然而CSS继承性的权重是非常低的,是比普通元素的权重还要低的0。</p> <p>我们仍以上面的举例代码为例:在样式定义中添加一条:</p> <p><span class=&#34;code&#34;>strong {color:#000;}</span></p> <p>举例效果:</p> <p>发现只需要给&amp;lt;strong&amp;gt;加个颜色值就能覆盖掉它继承自&amp;lt;body&amp;gt;的样式颜色。由此可见:任何显示申明的规则都可以覆盖其继承样式。</p> <p><strong>4.2 继承的局限性</strong></p> <p>继承是CSS重要的一部分,我们甚至不用去考虑它为什么能够这样,但CSS继承也是有限制的。</p> <p>有一些属性不能被继承,如:border, margin, padding, background等。</p> <p>样式定义:</p> <p><span class=&#34;code&#34;>div {border:1px solid #000;} </span></p> <p>举例代码:</p> <p><span class=&#34;code&#34;>&amp;lt;div&amp;gt;我是&amp;lt;em&amp;gt;border&amp;lt;/em&amp;gt;我是不能被继承滴&amp;lt;/div&amp;gt; </span></p> <p>预期效果:</p> <p align=&#34;center&#34;><a href=&#34;http://img.68design.net/art/20090603/iV7jj6CHhkDzfAQ.gif&#34; target=&#34;_blank&#34;><img border=&#34;0&#34; alt=&#34;&#34; src=&#34;http://img.68design.net/art/20090603/iV7jj6CHhkDzfAQ.gif&#34; /></a></p> <p>实际效果:</p> <p align=&#34;center&#34;><a href=&#34;http://img.68design.net/art/20090603/UVw83bBZxTNLDlg.gif&#34; target=&#34;_blank&#34;><img border=&#34;0&#34; alt=&#34;&#34; src=&#34;http://img.68design.net/art/20090603/UVw83bBZxTNLDlg.gif&#34; /></a></p> <p>从上面的效果中,我们可以看出,border是不能被继承的,还有一些其它的属性也是如此,这里就不一一列举。</p> <p><strong>五、附加说明</strong></p> <ol> <li>文内的样式优先级为1,0,0,0,所以始终高于外部定义。这里文内样式指形如&amp;lt;div style=&amp;quot;color:red&amp;quot;&amp;gt;blah&amp;lt;/div&amp;gt;的样式,而外部定义指经由&amp;lt;link&amp;gt;或&amp;lt;style&amp;amp; amp; gt;卷标定义的规则。</li> <li>有!important声明的规则高于一切。</li> <li>如果!important声明冲突,则比较优先权。</li> <li>如果优先权一样,则按照在源码中出现的顺序决定,后来者居上。</li> <li>由继承而得到的样式没有specificity的计算,它低于一切其它规则(比如全局选择符*定义的规则)。</li> <li>关于经由@import加载的外部样式,由于@import必须出现在所有其它规则定义之前(如不是,则浏览器应该忽略之),所以按照后来居上原则,一般优先权冲突时是占下风的。</li> </ol> <p>还需要说一下,IE是可以识别位置错误的@import的,但无论@import在什么地方,它都认为是位于所有其它规则定义之前的,这可能会引发一些误会。</p> <p>优先权问题看起来简单,但背后还是有非常复杂的机制,在实际应用中需要多多留意。</p> <p><strong>六、练习</strong></p> <p>看完上面的文字后,来做几道非常简单的题目。(<strong>自己答完前,请不要先看各题给出的链接地址哦</strong>)</p> <p>1. 如何让使用两个使用相同样式名的元素具有不同的效果:</p> <p>1. 如何让使用两个使用相同样式名的元素具有不同的效果:</p> <p>运行代码框<br /> <span><textarea class=&#34;codeTextarea&#34; style=&#34;width: 510px; height: 251px;&#34; rows=&#34;1&#34;>&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt; &amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt; &amp;lt;head&amp;gt; &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=gb2312&amp;quot; /&amp;gt; &amp;lt;meta http-equiv=&amp;quot;Content-Language&amp;quot; content=&amp;quot;gb2312&amp;quot; /&amp;gt; &amp;lt;title&amp;gt;test&amp;lt;/title&amp;gt; &amp;lt;meta name=&amp;quot;Author&amp;quot; content=&amp;quot;doyoe(飘零雾雨), edzmaster@gmail.com&amp;quot; /&amp;gt; &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt; .test { width:200px; border:1px solid #000; font:12px/200% &amp;quot;宋体&amp;quot;; color:#f00; background:#ddd; } p.test { color:#fff; background:#070; } &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body&amp;gt; &amp;lt;div class=&amp;quot;test&amp;quot;&amp;gt;测试测试测试&amp;lt;/div&amp;gt; &amp;lt;p class=&amp;quot;test&amp;quot;&amp;gt;测试测试测试&amp;lt;/p&amp;gt; &amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt;</textarea><br /> &amp;nbsp;[Ctrl+A 全部选择]</span></p> <p>固定效果:</p> <p align=&#34;center&#34;><a href=&#34;http://img.68design.net/art/20090603/RS66VrrtZVI0thU.gif&#34; target=&#34;_blank&#34;><img border=&#34;0&#34; alt=&#34;&#34; src=&#34;http://img.68design.net/art/20090603/RS66VrrtZVI0thU.gif&#34; /></a></p> <p>固定代码:</p> <p>&amp;nbsp;</p> <p>&amp;lt;div class=&amp;quot;test&amp;quot;&amp;gt;传说中的测试&amp;lt;/div&amp;gt; <br /> &amp;lt;p class=&amp;quot;test&amp;quot;&amp;gt;传说中的测试&amp;lt;/p&amp;gt;</p> </div> <p>我去,上次baidu 那哥们问我 class 和 id的优先级,我竟然说反了,好久没用,试试就知道了!</p>