在设计网页时如果css样式发生冲突

在我们设计网页时,如果特殊性相等的两个规则同时应用到同一个元素会怎么样呢?浏览器如何解决这个冲突?例如,假设有以下规则:

h1 {color:red;}

h1 {color:blue;}

哪一个会占上风?这两个规则的特殊性都是0,0, 0,1,所以它们的权重相等,都应当应用到元素。但这是不可能的,因为一个元素不可能既是红色又是蓝色。但是到底应用哪一个规则呢?

“层叠样式表”这个名字可能会提供一点提示。CSS所基于的方法就是让样式层叠在一起,这是通过结合继承和特殊性做到的。CSS2.1的层叠规则相当简单:

找出所有相关的规则,这些规则都包含与一个给定元素匹配的选择器。

按显式权重对应用到该元素的所有声明排序。标志!important的规则的权重要高于没有!important标志的规则。按来源对应用到给定元素的所有声明排序。共有3种来源:网页设计师、读者和用户代理。正常情况下,创作人员的样式要胜过读者的样式。有!important标志的读者样式要强干所有其他样式,这包括有!important标志的网页设计师样式。网页设计师样式和读者样式都比用户代理的默认样式要强。

按特殊性对应用到给定元素的所有声明排序。有较高特殊性的元素权重要大于有较低特殊性的元素。

按出现顺序对应用到给定元素的所有声明排序。一个声明在样式表或文档中越后出现,它的权重就越大。如果样式表中有导入的样式表,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。

为了淸楚地说明如何做到这些,下面来看三个例子,由此介绍上述4条层叠规则中的后三条规则。

按权重和来源排序

根据第二条规则,如果两个样式规则应用到同一个元素,而且其中一个规则有!important标志,这个重要规则将胜出:

p {color:gray !important;}

<p style="color:black;">Well,<em>hello</em> there!</p>

尽管段落的style属性中指定了一个颜色,不过有!important标志的规则会胜出,所以段落为灰色。em元素也会继承这个灰色。

另外,还要考虑规则的来源。如果一个元素与网页设计师样式表中的正常权重样式匹配,另外还与读者样式表中的正常权重样式匹配,则会使用网页设计师的样式。例如,假设以下样式分别来自注释中指定的来源:

p em {color: black;}/* author's style sheet */

p em {color: yellow;}/* reader's style sheet */

在这种情况下,段落中强调的文本为黑色,而不是黄色,因为有正常权重的网页设计师样式要优先于正常权重的读者样式。不过,如果两个规则都标志有!important,情况就不同了:

p em {color: black !important;}/* author's style sheet */

p em {color: yellow !important;}/* reader's style sheet */

现在段落中的强调文本将是黄色而不是黑色。

一般地,用户代理的默认样式(通常受用户首选项的影响)也要考虑在内。默认样式声明在所有声明当中影响是最小的。因此,如果网页设计师定义的一个规则应用到锚(例如,声明这些锚颜色为white),该规则会覆盖用户代理的默认样式。

总结一下,在声明权重方面要考虑5级。权重由大到小的顺序依次为:

读者的重要声明

创作人员的重要声明

创作人员的正常声明

读者的正常声明

用户代理声明

网页设计师通常只需要考虑前4个权重级別,因为任何声明都会胜过用户代理样式。

按特殊性排序

根据第3条规则,如果向一个元素应用多个彼此冲突的声明,而且它们的权重相同,则要按特殊性排序,最特殊的声明最优先。例如:

p#bright {color: silver;}

p {color: black;}

<p id="bright">Well, hello there!</p>

给定以上所示的规则,段落的文本将是银色,为什么呢?因为p#bright 的特殊性(0,1, 0,1)大于p的特殊性(0,0, 0,1),尽管后一条规则在样式表中较后出现。

按顺序排序

最后,根据第4条规则,如果两个规则的权重、来源和特殊性完全相同,那么在样式表中后出现的一个会胜出。因此,再来看前面的例子,在文档样式表中可以看到以下两个规则:

h1 {color: red;}

h1 {color: blue;}

因为指定blue的规则在样式表中较后出现,所以文档中所有h1元素的color值将是blue,而不是red。倘若文档中包含的规则比导入的规则权重高,那么文档中包含的规则将胜出。即使这个规则是文档样式表的一部分而不是元素style属性的一部分,也是如此。考虑以下规则:

p em {color: purple;}/* from imported style sheet */

p em {color: gray;}/* rule contained within the document */

在这种情况下,以上第二个规则会胜过导入的规则,因为第二个规则是文档样式表的一部分。

根据层叠的第4条规则,认为元素style属性中指定的样式位于文档样式表的最后,即放在所有其他规则的后面。不过,这一点没有实际意义,因为在CSS2.1中内联样式声明的特殊性要高于所有样式表选择器。

注意:要记住,在CSS2中,内联样式声明与ID选择器的特殊性相等。在一个CSS2(而非CSS2.1)用户代理中,认为style属性声明出现在文档样式表的最后,并且与样式表中所有其他声明一样,按权重、来源、特殊性和顺序排序。

正是由于这种按顺序排序,所以才有了通常推荐的链接样式顺序。一般建议按link-visited-hover-active (LVHA)的顺序声明链接样式如下:

:link {color: blue;}

:visited {color: purple;}

:hover {color: red;}

:active {color: orange;}

根据这一章的介绍,现在你知道了所有这些选择器的特殊性都是一样的:0,0,1,0。因为它们都有相同的权重、来源和特殊性,因此与元素匹配的最后一个选择器才会胜出。正在“点击”的未访问链接可以与其中3个规则匹配--:link.:hover和:active--所以在这三个规则当中最后声明的一个将胜出。如果按照LVHA顺序,:active 会胜出,这可能正是创作人员所期望的。

假设你想忽略这种常用的顺序,而是按字母顺序排列链接样式。这就会得到:

:active {color: orange;}

:hover {color: red;}

:link {color: blue;}

:visited {color: purple;}

按照这种顺序,任何链接都不会显示:hover或:active样式,因为:link和:visited 规则后出现。所有链接都必须要么是已访问,要么是未访问的,所以:link和:visited 样式总是会覆盖:hover规则。

下面考虑网页设计师可能想使用的LVHA顺序的一个变种。采用这种顺序,只有未访问的链接会有悬停样式,已访问的链接没有这种样式。已访问和未访问的链接都可以有激活样式(active):

:link {color: blue;}

:hover {color: red;}

:visited {color: purple;}

:active {color: orange;}

当然,有时如果所有规则试图设置同一个属性,就会出现这种冲突。如果各规则为不同的属性设置样式,那么顺序无关紧要。在下面的情况中,链接样式可以按任何顺序指定,而且不论采用何种顺序都能正常起作用:

:link {font-weight: bold;}

:visited {font-style: italic;}

:hover {color: red;}

:active {background: yellow;}

你可能还发现,:link和:visited样式的顺序并不重要。可以按LVHA或VLHA的顺序指定样式,这没有任何不良后果。不过,LVHA更好一些,因为这是CSS2规范中推荐的顺序,另一个原因是LVHA拼作“LoVe-HA!”,这个词更易于记忆,流通很广。

有关系。鼠标停留的未访问链接不会与针对悬停状态已访问链接的规则相匹配,反之亦然。如果要增加激活状态样式,就要重新考虑顺序了,请看下面的例子:

:link {color: blue;}

:visited {color: purple;}

:link:hover {color: red;}

:visited:hover {color: gray;}

:link:active {color: orange;}

:visited:active {color: silver;}

如果把激活样式移到悬停样式前面,它们会被忽略。同样地,这是由于特殊性冲突所致。可以向链中增加更多的伪类来避免这种冲突,如下:

:link:hover:active {color: orange;}

:visited:hover:active {color: silver;}

通过将伪类链接在一起,能缓解特殊性和顺序带来的问题,如果Internet Explorer以前就一直支持这种串链的伪类,它的应用可能会更广(有关的更多内容见第2章)。

非CSS表现提示

网页文档有可能包含非CSS的表现提示,例如font元素。非CSS提示被处理为特殊性为0,并出现在网页设计师样式表的最前面。只要有网页设计师或读者样式,这种表现提示就会被覆盖,但是用户代理的样式不能将其覆盖。

小结

层叠样式表中最基本的一个方面可能就是层叠了——冲突的声明要通过这个层叠过程排序,并由此确定最终的文档表示。这个过程的核心是选择器及其相关声明的特殊性,以及继承机制。

在下一章中,我们将介绍多种用于为属性值提供含义的单位,讨论完下一章后,你就能清楚地了解全部基础知识,并做好进一步学习指定文档样式的属性的准备。