我是靠谱客的博主 畅快彩虹,最近开发中收集的这篇文章主要介绍css覆盖规则_赠书 | 张鑫旭新书CSS选择器世界章节试读,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近发现我心目中前端大神张鑫旭又出书了,名叫《CSS选择器世界》,好书要让大家都知道啊,于是赶紧联系大神来外刊君宣传一波,本文带来了该书的第2章试读,以飨读者。文末还有一个送书的小活动,希望你们喜欢!

《CSS选择器世界》就是做了这样的事情,十年如一日的技术学习与积累,在CSS领域不断深耕,不断探索,不断研究,去粗取精,紧贴实践,尽可能将CSS选择器的完整世界呈现在大家面前。—— 张鑫旭:关于《CSS选择器世界》这本书

5fefe85b8bf223e24c70e1964741c12c.png
《CSS选择器世界》

下面就开始试读吧——


第2章 CSS选择器的优先级

几乎所有的CSS样式冲突、样式覆盖等问题都与CSS声明的优先级错位有关。因此,在详细阐述CSS选择器的优先级规则之前,我们先快速了解一下CSS全部的优先级规则。

2.1 CSS优先级规则概览

CSS优先级有着明显的不可逾越的等级制度,我将其划分为0~5这6个等级,其中前4个等级由CSS选择器决定,后2个等级由书写形式和特定语法决定。下面我将对这6个等级分别进行讲解。

(1)0级:通配选择器、选择符和逻辑组合伪类。其中,通配选择器写作星号(*)。示例如下:

* { color: #000; }

选择符指+、>、~、空格和||。关于选择符的更多知识可参见第4章。

逻辑组合伪类有:not()、:is()和:where等,这些伪类本身并不影响CSS优先级,影响优先级的是括号里面的选择器。

:not() {}

需要注意的是,只有逻辑组合伪类的优先级是0,其他伪类的优先级并不是这样的。

(2)1级:标签选择器。示例如下:

body { color: #333; }

(3)2级:类选择器、属性选择器和伪类。示例如下:

.foo { color: #666; }[foo] { color: #666; }:hover { color: #333; }

(4)3级:ID选择器。示例如下:

#foo { color: #999; }

(5)4级:style属性内联。示例如下:

优先级

(6)5级:!important。示例如下:

.foo { color: #fff !important; }

!important是顶级优先级,可以重置JavaScript设置的样式,唯一推荐使用的场景就是使JavaScript设置无效。例如:

.foo[style*="color: #ccc"] {  color: #fff !important;}

对于其他场景,没有任何使用它的理由,切勿滥用。

不难看出,CSS选择器的优先级(0级至3级)属于CSS优先级的一部分,也是最重要、最复杂的部分,学会CSS选择器的优先级等同于学会了完整的CSS优先级规则。

2.2 深入CSS选择器优先级

本节内容将有助于深入理解CSS选择器的优先级,包括计算规则、实用技巧以及一些奇怪的有趣特性。

2.2.1 CSS选择器优先级的计算规则

对于CSS选择器优先级的计算,业界流传甚广的是数值计数法。具体如下:每一段CSS语句的选择器都可以对应一个具体的数值,数值越大优先级越高,其中的CSS语句将被优先渲染。其中,出现一个0级选择器,优先级数值+0;出现一个1级选择器,优先级数值+1;出现一个2级选择器,优先级数值+10;出现一个3级选择器,优先级数值+100。

于是,有表2-1所示的计算结果。

选择器计算值计算细则
* {}01个0级通配选择器,优先级数值为0
dialog {}11个1级标签选择器,优先级数值为1
ul > li {}22个1级标签选择器,1个0级选择符,优先级数值为1+0+1
li > ol + ol {}33个1级标签选择器,2个0级选择符,优先级数值为
.foo {}101个2级类名选择器,优先级数值为10
a:not([rel=nofollow]) {}111个1级标签选择器,1个0级否定伪类,1个2级属性选择器,优先级数值为1+0+10
a:hover {}111个1级标签选择器,1个2级伪类,优先级数值为1+10
ol li.foo {}121个2级类名选择器,2个1级标签选择器,1个0级空格选择符,优先级数值为1+0+1+10
li.foo.bar {}212个2级类名选择器,1个1级标签选择器,优先级数值为10×2+1
#foo {}1001个3级ID选择器,优先级数值为100
#foo .bar p {}1111个3级ID选择器,1个2级类名选择器,1个1级标签选择器,优先级数值为100+10+11

表2-1 选择器优先级计算值

趁热打铁,我出一个小题考考大家,元素的颜色是红色还是蓝色?

  颜色是?body.foo:not([dir]) { color: red; }html[lang] > .foo { color: blue; }

我们先来计算一下各自的优先级数值。

首先是body.foo:not([dir]),出现了1个标签选择器body,1个类名选择器.foo和1个否定伪类:not,以及属性选择器[dir],计算结果是1+10+0+10,也就是21。

接下来是html[lang] > body.foo,出现了1个标签选择器html,1个属性选择器[lang]和1个类名选择器.foo,计算结果是1+10+10,也就是21。

这两个选择器的计算值居然是一样的,那该怎么渲染呢?

这就引出了另外一个重要的规则—“后来居上”。也就是说,当CSS选择器的优先级数值一样的时候,后渲染的选择器的优先级更高。因此,上题的最终颜色是蓝色(blue)。

后渲染优先级更高的规则是相对于整个页面文档而言的,而不仅仅是在一个单独的CSS文件中。例如:

其中在a.css中有:

body { color: yellow; }

在b.css中有:

body { color: blue; }

此时,body的颜色是蓝色,如图2-1所示,因为blue这段CSS语句在文档中是最后出现的。

b2a279722f188c2e2b69161cf4f04d18.png
图2-1 浏览器中body颜色的优先级

还有一个误区有必要强调一下,那就是CSS选择器的优先级与DOM元素的层级位置没有任何关系。例如:

body .foo { color: red; }html .foo { color: blue; }

请问.foo的颜色是红色还是蓝色?

答案是蓝色。虽然是的子元素,离.foo的距离更近,但是选择器的优先级并不考虑DOM的位置,所以后面的html.foo{}的优先级更高。

1.增加CSS选择器优先级的小技巧

实际开发时,难免会遇到需要增加CSS选择器优先级的场景。例如,希望增加下面.foo类名选择器的权重:

.foo { color: #333; }

很多人的做法是增加嵌套,例如:

.father .foo {}

或者是增加一个标签选择器,例如:

div.foo {}

但这些都不是最好的方法,因为这些方法增加了耦合,降低了可维护性,一旦哪天父元素类名变化了,或者标签换了,样式岂不是就失效了?这里给大家介绍一个增加CSS选择器优先级的小技巧,那就是重复选择器自身。例如,可以像下面这样做,既提高了优先级,又不会增加耦合,实在是上上之选:

.foo.foo {}

如果你实在不喜欢这种写法,借助必然会存在的属性选择器也是不错的方法。例如:

.foo[class] {}#foo[id] {}

2.对数值计数法的点评

上面提到的CSS选择器优先级数值的计数法实际上是一个不严谨的方法,因为1和10之间的差距实在太小了,这也就意味着连续10个标签选择器的优先级就和1个类名选择器齐平了。然而事实并非如此,不同等级的选择器之间的差距是无法跨越的存在。但由于在实际开发中,我们是不会连续写上多达10个选择器的,因此不会影响我们在实际开发过程中计算选择器优先级。

而且对于使用CSS选择器而言,你的书写习惯远比知识更重要,就算你理论知识再扎实,如果平时书写习惯糟糕,也无法避免CSS样式覆盖问题、样式冲突等问题的出现。我将在第3章中深入探讨这个问题。因此,对于数值计算法,我的态度是,学一遍即可,没有必要反复攻读,做到面面俱到,只要你习惯足够好,是不会遇到乱七八糟的优先级问题的。

在CSS选择器这里,等级真的是无法跨越的鸿沟吗?其实不是,这里有大家不知道的冷知识。

2.2.2 256个选择器的越级现象

有如下HTML:

颜色是?``如下CSS:```css#foo { color: #000; background: #eee; }.f { color: #fff; background: #333; }

很显然,文字的颜色是#000,即黑色,因为ID选择器的级别比类名选择器的级别高一级。但是,如果是下面的CSS呢?256个.f类名合体:

#foo { padding: 10px 20px; color: #000; background: #eee; }.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f { color: #fff; background: #333; }

在IE浏览器下,神奇的事情发生了,文字的颜色表现为白色,背景色表现为深色,如图2-2所示。

b27fc9784dfb89b3da1051a6c629e7a8.png
图2-2 IE浏览器中类名的优先级更高

在IE浏览器下,读者可以输入https://demo.cssworld.cn/selector/2/2-1.php亲自体验与学习。

同样,256个标签选择器的优先级大于类名选择器的优先级的现象也是存在的。

实际上,在过去,Chrome浏览器、Firefox浏览器下都出现过这种256个选择器的优先级大于上一个选择器级别的现象,后来,大约2015年之后,Chrome浏览器和Firefox浏览器都修改了策略,使得再多的选择器的优先级也无法超过上一级,因此,目前越级现象仅在IE浏览器中可见。

为什么会有这种有趣的现象呢?早些年查看Firefox浏览器的源代码,发现所有的类名都是以8字节字符串存储的,8字节所能容纳的最大值就是255,因此同时出现256个类名的时候, 势必会越过其边缘,溢出到ID区域。而现在采用了16字节的字符串存储,能容纳的类型数量足够多了,就不会出现这种现象。

当然,这个冷知识并没有多大的实用价值,大致了解一下即可。

2.3 为什么按钮:hover变色了

了解了CSS选择器的优先级之后,很多日常工作中遇到的一些问题你就知道是怎么回事了,举一个按钮:hover变色的例子。

例如,我们写一个蓝底白字的按钮,使鼠标经过按钮时会改变背景色:

.cs-button {  background-color: darkblue;  color: white;}.cs-button:hover {  background-color: blue;}按钮

看代码没有任何问题,但是页面一刷新就出现问题了。鼠标经过按钮的时候,文字居然变成蓝色了,而不是预期的白色!

究竟是哪里出了问题呢?一排查,这个问题居然是CSS reset导致的。

在实际开发中,我们一定会对全局的链接颜色进行设置,例如,按钮默认颜色为蓝色,鼠标经过的时候变成深蓝色:

a { color: blue; }a:hover { color: darkblue; }

按钮变色就是这里的a:hover导致的。因为a:hover的优先级比.cs-button的优先级高(:hover伪类的优先级和类选择器的优先级一样),所以鼠标经过按钮的时候按钮颜色表现为a:hover设置的深蓝色。

知道原因,问题就好解决了,常见做法是再设置一遍鼠标经过按钮的颜色:

.cs-button:hover {  color: white;  background-color: blue;}

或者按钮改用语义更好的button标签,而不是传统的a标签。


赠书活动看这里——

  • 在评论区发言积赞,自发文起24小时内,按照评论获得?数排序,前5名读者免费获赠《CSS选择器世界》纸质书一本(赞数相同,按发表时间倒序排列);
  • 任何有非正常刷赞嫌疑(无法自正赞数合理性)的将会被取消参与本公众号任何活动的资格。
当然,如果您是土豪,建议您直接购买:

最后

以上就是畅快彩虹为你收集整理的css覆盖规则_赠书 | 张鑫旭新书CSS选择器世界章节试读的全部内容,希望文章能够帮你解决css覆盖规则_赠书 | 张鑫旭新书CSS选择器世界章节试读所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部