CSS入门8-三大特性之层叠特性与优先级

html-css013

CSS入门8-三大特性之层叠特性与优先级,第1张

所谓的层叠性与优先级,其实说白了可以理解为,不同的规则起冲突的情况下,听谁的呢?有的时候这种冲突很容易解决,有的时候我们自己都难以决断,比如好声音三位导师都选你,该跟谁走呢。索性css给出了这些规则的优先级,不需要我们去苦恼。

元素的样式该如何去展现呢,首先看一下某个元素某个属性可能作用样式的情况:

下面我们来详细分析一下这三种情况。

我们先来看有唯一指定样式的情况,因为,这种情况最简单,就一个选择,也别挑了,说啥就是啥。我们还是来大致看看。

结论:若只有唯一指定样式,以该样式为准。

多个样式规则冲突,其实有很多种情况。还记得我们学过样式引入方式有四种,涉及三种样式,分别是内联,内部和外部(参考 CSS入门4-引入CSS )。首先我们来看只引入其中一种类型的情况下,出现冲突该如何解决。

仅有内联的情况下,要出现冲突,只可能是在style中多次对同一个属性赋值。

看上图,审查一下元素,可以看到该元素样式中,前面的red被覆盖了,color最后的取值是blue。最右边文字的颜色确实也是蓝色。

结论:只有内联样式,后面的属性赋值优先级大于前面的属性赋值。

内部样式,已经可以选择多种选择器来指定样式。所以,这里情况比内联会复杂很多。首先来复习一下选择器的种类,可以参考 CSS入门5-选择器 。这么多的选择器类型和组合关系,可能都会产生冲突,这个时候怎么办呢,想想都复杂,我们继续拆分问题。将选择器分为四类:

可以看到div中两个类对颜色的定义冲突时,不管class定义的顺序如何,以style中类的顺序为准,后面的覆盖前面的样式。如果是同一选择器,也是后者覆盖前者,这种情况可以涵盖在同类选择器的情况下。

结论:同类型选择器(类型一样,即同为元素选择器,类选择器,id选择器或者属性选择器),按style中的先后顺序,后者优先级更高。

我们选择正反两种顺序,来看不同选择器之间的比较。首先,四种选择器在一起时,id选择器获胜。然后排除id选择器,剩余三种选择器比较时,类和属性谁在下边谁赢,也就是后者覆盖前者。最后,元素分别与类和属性比较,发现元素都输了。

结论:id >(类和属性) >元素,类和属性同级,遵循同级元素后者覆盖前者的规则。

注:查看某个元素样式的时候,调试窗口是按照优先级规则从小到大往上排的,越往上的规则优先级越高,对同个属性的样式规定将会覆盖下面低优先级的样式规定。

注:要想在调试器看到动态伪类效果,需要在styles中勾选该效果。

看上面示例,我们在style内先按id,类,属性,元素,静态伪类(只应用于超链接),动态伪类(可应用于任何元素),目标伪类:target(IE8-不支持,匹配锚点对应的目标元素),UI元素伪类(IE8-不支持),结构伪类(IE8-不支持)的顺序指定规则。结果发现其表现如下:

a:id >结构伪类 >动态伪类 >静态伪类 >属性 >类 >元素 >浏览器默认属性 >继承属性

input:id >结构伪类 >UI元素伪类 >目标伪类 >动态伪类 >类 >元素 >浏览器默认属性 >继承属性

我们合并一下这两个结论,有如下结论:

3.2.1.2.2.1-1 id >结构伪类 >UI元素伪类 >目标伪类 >动态伪类 >静态伪类 >属性 >类 >元素 >浏览器默认属性 >继承属性

(当然,需要注意的是,并不是每个元素都有这些属性的)

然后,我们将style内各规则倒序一下:

结果发现其表现如下:

a:id >类 >属性 >静态伪类 >动态伪类 >结构伪类 >元素 >浏览器默认属性 >继承属性

input:id >类 >动态伪类 >目标伪类 >UI元素伪类 >结构伪类 >元素 >浏览器默认属性 >继承属性

我们合并一下这两个结论,有如下结论:

3.2.1.2.2.1-2 id >类 >属性 >静态伪类 >动态伪类 >目标伪类 >UI元素伪类 >结构伪类 >元素 >浏览器默认属性 >继承属性

综合3.2.1.2.2.1-1和3.2.1.2.2.1-2来看,我们再次验证了类和属性同级,并且发现它们和伪类也是同级的。有如下结论:

结论:id >(类,属性,伪类) >元素,类,属性和伪类同级,遵循同级元素后者覆盖前者的规则。

伪元素,说是元素,但又不是真实的元素,是一个虚拟的元素。如何详细理解这段话呢,我们来看一下下面这个例子。

先按后代,子代,通用兄弟,相邻兄弟在style中排序,发现后面的优先级高。然后顺序反过来:

由以上几点结论可以得出, 亲戚关系发生冲突时,先看id选择器数量,谁多谁大,一样多就看类(及其同级)选择器,谁多谁大,若还是一样多,则看元素选择器,谁多谁大。如果仍然一样多,谁在后面谁优先。

可以看出, 通配选择器样式优先级仅比浏览器默认样式和继承样式优先级高一些

总结3.2.1.2 仅有内部样式的情况,有如下结论:

ps:对于社群关系,在比较优先级时,将其理解为在该位置拆按顺序成一个个单独的个体即可。

这种情况的表现形式与内部样式一样。

这种情况遵循后者覆盖前者的原则,后面的link优先于前面的link,而不管其加载的顺序如何。

内联 >内部 >外部

CSS的继承性、层叠性、权重

css知多少(3)——样式来源与层叠规则

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

上面是一个简单的html案例,对于同一个元素应用多个规则时,规则中可能包含冲突的声明,在style样式表中包含了三个规则集,每一个规则给它指定了不同的字体颜色。标题不可能同时拥有三种颜色,所以最终的效果是显示的红色(red)。

浏览器如何知道并解决声明冲突,这其中层叠指的就是这一系列规则。它决定了如何解决冲突,是css语言的基础。层叠会依据三种条件解决冲突。

叠层的规则是按照这种顺序来考虑的,看下图

这些规则让浏览器可以以预测的方式解决css样式规则中的冲突。

你添加到网页里的样式表并不是浏览器唯一使用的样式表,还有其他类型或来源的样式表。你的样式表属于作者样式表,除此之外还有用户代理样式表,即浏览器默认的样式。用户代理样式表优先级低,你的样式会覆盖它们。

用户代理样式表在不同浏览器上稍有差异,但是大体上是在做相同的事情:为标题 <h1>到 <h6>和段落 <p>添加上下边距,为列表 <ol>,<ul>添加左侧内边距,为链接添加颜色,为元素添加各种默认字号。

浏览器应用了用户代理样式表后才会应用你的样式表,即作者样式表,你指定的声明会覆盖用户代理样式表里面的样式,如果在html里链接了多个样式表,那么它们的来源都相同,即属于作者样式表。

用户代理样式表因为设置了用户需要的样式,所以不会做出一些超出预期的事情,当不喜欢默认样式的时候,可以在自己的样式表里面设置别的样式来覆盖用户代理样式即可。

作为一个标准的前端打工仔,必定熟悉覆盖代理样式。这种做法实际上就是利用了层叠的样式来源规则。你写的样式会覆盖用户代理样式,因为来源不同。

样式来源规则有一个例外,标记为重要 !important 的声明。该声明就会被标记为重要的声明。

标记了 !important 的声明会被当做更高优先级的来源,因此总体的优先级按照由高到低排列,如下所示:

如果无法用来源解决冲突声明,浏览器会尝试检查它们的优先级。理解优先级很重要,因为作者样式几乎都是属于优先级的范围,日常工作接触的大部分开发样式是来自于同源,如果不理解优先级,写出来的css样式会被坑的很惨。

浏览器将优先级分为两部分:HTML的行内样式和选择器的样式。

如果HTML的style属性写样式,这个声明只会作用域当前元素。实际上行内元素属于“带作用域”的声明,它会覆盖任何来自样式表或<style>标签的样式。行内样式没有选择器,因为它们直接作用于所在的元素。

上面就是一个行内样式,设置了颜色color为黄色yellow。

如果你希望在样式表中覆盖行内样式的声明,需要在样式表中对应标签下的声明后添加 !importanta ,这样能够将它提升到一个更高优先级来源。但如果行内样式也被标记为 !imortant 那就无法覆盖它了。最好不要在行内使用 !important ,而是只在样式表中使用 !important 。

优先级的第二部分是由选择器优先级决定。比如,有两个类名的选择器比只有一个类名的选择器优先级更高。具体可以看下面的案例。

通过比较选择器类型来决定哪个选择器优先值最高。

上面的样式表中最终显示的color颜色值为红色(red)。

一个常用的表示优先级的方式是用数组形式来标记,通常用都好隔开每个数。比如“1,2,3”表示用1个id、2个类、2个标签组成。优先级最高的id列为第一位,紧接着是类,最后是标签。

我们可以通过下面的表格来查看各种选择器和对应的优先级。

现在,通过比较数值就能快速明确决定哪个优先级更高。所以上面的顺序是"1,0,0">"0,2,0">"0,1,3">"0,0,4"。而优先级低的样式表会被优先级高的样式表给覆盖。

我们日常开发不建议某个元素的样式表写过长的标签名和类名连体。一般只要能够区分优先级即可。

叠层的第三步,也是最后一步,是源码顺序。如果两个声明的来源和优先级相同,其中一个声明在样式表中出现较晚,或者位于页面较晚引入的样式表中,则该声明胜出。

在上面方法中,选择器优先级相同,都是(0,1,1),最终浏览器呈现的颜色color是灰色gray。