当前位置: 首页 > Web前端 > CSS

前端面试CSS系列——选择器、权重计算(二)

时间:2023-03-30 16:45:07 CSS

面试题及答案Q:CSS选择器权重是如何计算的?(或者说CSS选择器的优先级是怎么计算的?)答:CSS权重的计算分为a、b、c、d四个等级;HTML元素的style属性中定义的声明属于a级,id选择器属于b级,属性选择器、类选择器、伪类选择器属于c级,类型选择器属于d级;四个等级中,a级的权重值最高,d级的权重值最低。权重值按照每一级出现的次数进行统计,每一级出现1次计1次。权重值根据a、b、c、d四个等级计算出的数字从高到低依次进行比较。如果是同级PK结果的值,则不进行后续比较。如果同一层的数相同,则继续比较下层的数。其中一些选择器不参与优先级的计算,包括:通用选择器“*”号、否定伪类:not选择器、组合选择器中的子类选择器、相邻兄弟选择器、普通兄弟选择器设备。但是,否定伪类选择器中的选择器会参与选择器优先级的计算。包含!important的CSS声明比较特殊,不参与权重值的计算,高于a、b、c、d四个级别;当两者都包含!important时,会根据选择器值的匹配规则计算权重。谁的权重值高,就应用谁的风格。基本概念CSS规则CSS规则由两个主要部分组成:选择器和一个或多个语句;选择器通常是需要改变样式的HTML元素;语句由一个属性和一个值组成。Attributes就是你要设置的样式属性,每个属性都有一个值(属性值),属性和值之间用冒号隔开。优先级浏览器使用优先级来确定哪些属性值与元素最相关,然后将这些属性值应用到该元素。优先级基于由不同种类的选择器组成的匹配规则。再次回顾,优先级是基于不同种类的选择器组成的匹配规则。我们也用上面CSS规则中的图片例子来说明,//选择器“p”是计算优先级p的“匹配规则”{font-size:14px;背景:#ff0;}ul#navli.activea{font-size:14px;}body.ie7.col_3h2~h2{字体大小:16px;}//『ul#navli.activea』和『body.ie7.col_3h2~h2』是计算优先级匹配规则的权重由匹配选择器中每个选择器类型的值决定。权重计算出的数字越大,对应匹配规则的优先级越高。如果在两个优先级相同的匹配规则中定义了一个CSS声明,则最后一个匹配规则中的CSS声明将按照CSS文件中匹配规则的顺序应用到该元素上。示例我的字体大小

#id{font-size:18px;}.class{font-size:16px;}最终文字大小为18px,根据选择器类型#id的计算结果值为:1,0,0;.class的值为:0,1,0。计算过程我们先压表,然后点击查看代码示例中同等优先级的匹配规则。class{font-size:18px;}[class='class']{font-size:16px;}Lasttext的大小是16px。根据选择器类型的计算结果,.class的值为:0,1,0,[class='class']的值为:0,1,0。点击查看代码示例具体上面我们说#id的计算结果为:1,0,0;.classand[class='class']evaluatesto:0,1,0为什么会计算出这样的值呢?这就是我们要讲的specific,英文specific。下面引用W3C官方的译文:选择器的特殊性计算如下:如果声明来自“样式”属性而不是带有选择器的规则,则计数1,否则为0(=a)(在HTML中,元素的值“style”属性是样式表规则。这些规则没有选择器,所以a=1,b=0,c=0,d=0.)countthenumberofIDattributesintheselector(=b)countthenumber选择器中其他属性和伪类的数量(=c)计算选择器中元素名称和伪元素的数量(=d)特异性仅基于选择器的形式。特别是,“[id=p33]”形式的选择器被算作属性选择器(a=0,b=0,c=1,d=0),即使id属性被定义为“ID"在源文档的DTD中。连接四个数字a-b-c-d(在具有大基数的数字系统中)给出了特异性。选择器的特殊性计算规则如下:如果CSS声明来自HTML元素的样式属性,而不是带选择器的规则,则计算为1,否则为0;(在HTML中,元素的样式属性值是样式表规则。这些规则没有选择器;元素的style属性定义的样式规则在特异性计算中用a表示,所以通常在HTML中,元素的style属性定义的样式表规则的特异性表示为:a=1,b=0,c=0,d=0。)计算选择器中id属性的个数,用b表示选择器中其他属性(包括类属性)和伪类的个数,用c表示选择器中元素名和伪元素的个数,而用d来表示“特异性”这个词真的很难理解,按照语义,我根本不明白它是什么意思,为了更好的理解,我用“权重值”来表示“特异性”.计算示例*{}/*a=0b=0c=0d=0->权重值=0,0,0,0*/li{}/*a=0b=0c=0d=1->权重值=0,0,0,1*/li:first-line{}/*a=0b=0c=0d=2->权重值=0,0,0,2*/ulli{}/*a=0b=0c=0d=2->权重值=0,0,0,2*/ulol+li{}/*a=0b=0c=0d=3->权重值=0,0,0,3*/h1+*[rel=up]{}/*a=0b=0c=1d=1->权重值=0,0,1,1*/ulolli.red{}/*a=0b=0c=1d=3->权重值=0,0,1,3*/li.red.level{}/*a=0b=0c=2d=1->权重值=0,0,2,1*/#x34y{}/*a=0b=1c=0d=0->权重值=0,1,0,0*/style=""/*a=1b=0c=0d=0->weightvalue=1,0,0,0*/注意:当ID选择器用作属性选择器时有时,如[id='id'],权重值的计算会使用C级来计算权重值计算规则weightvalue=a*num,b*num,c*num,d*num;权重值的计算网上还有一个比较流行的说法:style属性定义的样式权重值为1000,一个id选择器的权重值为100,一个属性和伪类选择器的权重为表示为10,一个元素名和伪元素的权重值都是1。例如:按照我们说的权重值计算规则,图中的总值应该表示为:0,1,1,3.直接用数字113只是为了方便记忆,但是选择器优先级的比较不能用数字来比较。例如:两条匹配规则,一个是11个属性选择器,一个是1个id选择器,比较它们的权重值时:11个属性选择器得到的结果是110,发送第二个id选择器得到的结果是100。很明显“11个属性选择器”得到的数值最大,是否优先级最高?让我们来做个实验:HTML文本应用了样式
CSS样式#id{background:red;}[id='id'][class~='c1'].c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11{background:yellow;}也可以点击例子试试权重给自己赋值比较比较两个权重时,等级上的权重值是从A到D逐渐计算的(比如权重1,0,0,0对应-->A,B,C,D)为比较,不是简单的1000个数+100个数+10个数+1个数的总和进行比较。也就是说,无论有多少个低级选择器,其级别都不会超过高级选择器的优先级;请看下图:汇总权重值的比较按照a、b、c、d的等级逐级比较。如果同级的值相同,则继续到下一级进行比较。如果计算出的权重值相同,则以最后匹配的规则为准,应用CSS声明!important超出上述权重值计算规则,具有最高优先级。不参与计算的选择器并不是所有的选择器都参与权重值的计算规则,有的不参与,包括:一般选择器“*”否定伪类选择器“:not”组合选择器“+”,~,>』负伪类选择器::not(),虽然它本身不计算权重,但是里面写的css选择器是需要计算权重的。!important!important是一个特殊的存在,!important不是in是在css选择器的权重计算范围内,之所以能让css选择器生效,是因为浏览器在遇到!important时会做特殊判断,当需要比较多个!importants时,它们的weights会先计算再比较,一般情况下不鼓励使用!important,但是当我们需要重写style属性中定义的样式时,可以选择使用!important。其他说明优先级计算忽略了DOM树中的距离;例如:htmlp和bodyp权重值相同,谁后写谁应用谁的css声明伪类选择器、属性选择器、类选择器权重值相同参考ComputationalselectorspecificityCSS2赋属性值,级联,和继承CSS22计算选择器优先级前端讲:css权重优先CSS级联CSS继承深入理解CSS选择器优先级