css层叠管理

css的层叠决定哪些样式要被应用于元素的一套规则。它指定Web浏览器如何应用同一标签的多个样式,以及CSS属性发生冲突时,它该怎么做。这里,我们可以从继承来的样式和元素自生拥有的样式来讨论。

继承来的样式

对于某个元素继承来的样式,css又分两种情况。第一种,若继承来的样式中css属性不发生冲突(即同一个css属性在不同的标签里面定义了不同的值),则这些属性可以很融洽的合作,即都运用在这个元素上。第二种,若是继承来的css属性有冲突,那么只有最靠近这个元素的继承样式起作用。例如有下面的情况:

<html>
    <head>
        <title>优先级</title>
        <style type = "text/css">
        div {
            color: red;
        }
        p {
            color: orange;
        }
        </style>
    </head>
    <body>
        <div>
            <p>
                <span>我是什么颜色</span>
            </p>
        </div>
    </body>
</html>

运行结果:

上面的css代码中,div和p标签都定义了color属性,但是最后文本的颜色继承了p标签的属性,显示为黄色。因为p标签离span标签最近,所以span继承了它的属性。即时有使用了!important(可以改变样式的权重)也是如此:

<html>
    <head>
        <title>优先级</title>
        <style type = "text/css">
        div {
            color: red !important;
        }
        p {
            color: orange;
        }
        </style>
    </head>
    <body>
        <div>
            <p>
                <span>我是什么颜色</span>
            </p>
        </div>
    </body>
</html>

运行结果:

 继承来的样式和自身样式

继承来的样式和某元素自身的样式也有两种情况,若继承来的样式和元素自身的样式css属性没有冲突,则它们也可以很好的合作,若是有冲突,总是元素自身的样式起作用:

<html>
    <head>
        <title>优先级</title>
        <style type = "text/css">
        p {
            color: orange ; /*color: orange !important*/
        }
        span {
            color: red;
        }
        </style>
    </head>
    <body>
        <div>
            <p>
                <span>我是什么颜色</span>
            </p>
        </div>
    </body>
</html>

 

运行结果:

span标签和p标签都定了color属性,span自身的color属性得到应用,而忽略继承来的p属性。即使p标签运用了!important也一样。

元素的自身样式

元素的自身样式也分两种情况,如果某个元素自身的样式中css属性没有冲突,那么这些样式可以协作工作,如果有冲突,则需要分以下两步来决定:

1 通过计算权重值来决定运用哪个样式

下面的内容引用自博客园$雨$的一片文章

有很多文章在说到权重值的时候,都会给出如下公式:

内联样式(即直接用style属性声明在元素标签里)权重值为1000;

id选择器的权重值为100;

类选择器的权重值为10;

标签选择器的权重值为1;

按照这种方法来计算,大多数情况不会出错,但是请看下面的例子:

 

<html>
    <head>
        <title>优先级</title>
        <style type = "text/css">
        body div div div div div div div div div span {
            color: orange;
        }
        .text {
            color: red;
        }
        </style>
    </head>
    <body>
        <div>
            <div>
                <div>
                    <div>
                        <div>
                            <div>
                                <div>
                                    <div>
                                        <div>
                                            <span class = "text" >我是什么颜色</span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

运行结果:

如果按照上面的公式计算,第一条样式的选择器权重应该是11,第二条样式的权重为10,照理应该运用第一条规则,可是结果却是字显示为红色,应用了第二条规则,这就是上面的公式局限的地方。接下来就来解释为什么会应用第二条规则的原因。

实际上,对于权重值的计算与比较,应该分成A B C D四个层次:

如果样式写在标签的style属性里面,则A = 1,否则 A = 0。

计算ID选择器的数量,如果有则B = 1, 否则B = 0。

计算类、伪类以及其他属性的数量(不包括伪元素),有则C = 1,否则C = 0。

计算伪元素及标签的数量,有则D = 1,否则D = 0。

比如:

对于<span style = "color: red">文本</span> 根据上面的方法A = 1 B = 0 C = 0 D = 0(简写为1000);

对于#idName这样的选择器,则为A = 0 B = 1 C = 0 D = 0(简写为0100);

对于.className这样的选择器,则为A = 0 B = 0 C = 1 D = 0(简写为0010);

对于p这样的普通标签,则为A = 0 B = 0 C = 0 D = 1(简写为0001);

通过观察后面的简写形式,就会发现为什么有很多地方将内联样式的权重定义为1000,id选择器的权重定义为100,类选择器的权重定义为10, 标签选择器的权重定义为1的原因。

下面是更多的例子:

  • *             {}  /* 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 */

在比较权重值的时候,对于A B C D四个层次是依次比较,如果两个样式中有一个样式的A值大,则这个样式的优先级大;如果A值相同,再比较B值,B值大的样式优先级大;若果B值相同,再比较C值,依次类推。如果A B C D四个值都相同,那么后出现的样式优先级大。

那么,让我们分析刚才html代码的情况。第一个样式拥有11个标签,因此A = 0 B = 0 C = 0 D = 11(简写为000 11);第二个样式拥有一个类名,因此A = 0 B = 0 C = 1 D = 0(简写为0010),依次比较,样式二胜出,因此会运用样式二。

内部样式表和外部样式表

对于内部样式表和外部样式表,可以运用相同的方法。首先比较权重值,由权重值决定样式的优先级;权重值相等,那么样式的声明顺序决定样式的优先级,后声明的样式优先级大。因此内部样式表和外部样式表在html文件中的顺序,也能影响到样式优先级的顺序。

特殊的!important

在比较元素自身样式的优先级的时候,声明!important的样式优先级最高,比如:

样式一: p span {color: red !important; font-size: 10px;}

样式二: p .text {color:orange; font-size: 12px;}

他们都作用于span元素,.text是span元素的一个类名。代码如下:

<html>
    <head>
        <title>优先级</title>
        <style type = "text/css">
        p span {
            color: red !important;
            font-size: 10px;
        }
        .text {
            color: orange;
            font-size: 50px;
        }
        </style>
    </head>
    <body>
        <div>
            <p>
                <span class = "text">我是什么颜色</span>
            </p>
        </div>
    </body>
</html>

运行结果:

样式一的权重值为A = 0 B = 0 C = 0 D =2(简写为0002),样式二的权重值为A = 0 B = 0 C = 1 D = 0(简写为0010)。按照上面的比较方式,应该样式二优先级大,文本颜色应为orange,字体为50px;但是实际情况是文本颜色为red,但是字体认为50px。出现这个原因就是样式一种的color属性被声明成了!important,它的优先级最大,因此优先应用它,但font-size还是按比较的结果执行。

另外,若两个样式的权重值一样,而且都有!important,那么这是就由样式的声明顺序决定,靠后的样式将胜出,优先级大。

!important属性容易造成混乱,最好不要使用。

 

总结

对于css的层叠规则,作出如下总结:

1 分清元素的继承样式和自身样式

2 看继承样式和自身样式是否冲突,若冲突,自身样式总是胜出(即使继承样式有!important)

3 接下来看自身样式是否冲突,若冲突,按照权重值的比较规则比较

4 最后考虑!important的影响

更详细请参看《KB005: CSS层叠》

 

posted @ 2013-02-26 16:16  chaoguo1234  阅读(322)  评论(0编辑  收藏  举报