CSS选择器 学习笔记1

今天读了一本非常会整活的书:《CSS选择器世界》,这本书的封面写着“颠覆对CSS的认知”,我仅详细阅读到三分之一,就已经把我的认知颠覆的地覆天翻了。总结起来就是非常会整活,但也有很多值得学习的干货,这里把一些经典内容整理成笔记,时间关系最终没有读完,以后还会再来看这本书的。

基本概念

CSS选择器分为四类,选择器,选择符,伪类,伪元素。

  • 选择器:平常使用的CSS声明块前面的标签、类名等。
  • 选择符:表示后代关系的空格( ),表示父子关系的尖括号(>),表示相邻兄弟关系的加号(+),表示兄弟关系的波浪线(~),表示列关系的双管道(||)。
  • 伪类:通常与浏览器行为和用户行为相关联,可以看成CSS世界的JavaScript。
  • 伪元素:伪元素是一个附加至选择器末的关键词,允许你对被选择元素的特定部分修改样式。

CSS选择器只有一个全局作用域,以前出现过伪类:scope,用来匹配局部作用域,但现在被舍弃了。

CSS选择器具有命名空间namespace,让来自多个XML词汇表的元素的属性或样式之间没有冲突。但是使用命名空间解决冲突的方式都可以用其他选择器组合解决,所以也没啥大用。

无效CSS选择器特性几乎是IE独有的一个花活,假如你把一些有效选择器和一个无效选择器写在一起,那么这几个选择器都将一起无效。这个特性可以区分IE和其他浏览器(我???)

CSS选择器优先级

CSS优先级有着不可逾越的等级制度(后面就bug打脸了),前四个等级由CSS选择器决定,后两个等级由书写形式和特定语法决定。

  • 0级:通配符,选择符,逻辑组合伪类
  • 1级:标签选择器
  • 2级:类选择器、属性选择器、伪类
  • 3级:ID选择器
  • 4级:style内嵌属性
  • 5级:!important

CSS优先级的计算规则是数值计数法,每个选择器都可以对应一个数值,选择器组合即数值相加,数值越高优先级越高。

规则:0级+0,1级+1,2级+10,3级+100。当两个选择器优先级相同时,按照后来者居上的原则,后出现的优先适用。

选择器的优先级不考虑DOM的位置。如果需要增加CSS优先级,可以增加嵌套,或者增加一个标签选择器,但是这样增加的代码的耦合度,有个小技巧是重复选择器自身,借助必然会存在的属性选择器也可以。

其实数值计数法不是很严谨,如果有10个1级标签选择器写在一起,按算法就和2级类选择器相同等级了,但实际上应该无论加多少都不应该越级,不过这个例子很不现实,毕竟应该不会有人写10个标签选择器嵌套的阴间CSS,所以数值计数法也是可以使用的。

在2015年之前,浏览器中有一个很奇怪的现象,根据等级制度,id选择器要比类选择器高一级,但如果把类选择器叠到256个以上,就会把等级突破…

(吐槽:这种bug到底是怎么找出来的…)

出现这种bug的原因是类名以8字节字符串存储,能容纳的最大值是255,所以当出现256个以上的类选择器时,内存会溢出到ID区域,不过现在采用16字节存储的字符串就不会出现这种现象了,能容纳足够多的类选择器(除非你真的闲着没事堆65536个类选择器。。)

CSS选择器命名

现在实际上已经没有严格意义上的对大小写敏感的选择器了,这个在后面章节有详细讨论。

最常见的错误是类名选择器和ID选择器以数字开头,但实际上可以通过转义字符来使其强行数字开头。比如不可以用数字1开头,但是可以用数字1的十六进制转码\31表示,但是这样表示需要在后面加空格与其他部分区分,如果不想加空格,可以表示成\000031,将高位的0补齐就可以了。

其实,首字符支持的字符集有大小写a到z,下划线,非ASCII字符(中文,全角字符等),双短横线,单短横线带其他合法字符,后面的字符支持的字符集有大小写a到z,0到9,下划线,短横线以及非ASCII字符。然而这个规则可以通过转义字符“escape”掉,对于非字符集中出现的字符,使用转义字符转化一下也是可以的。

这意味着你甚至可以使用emoji字符当做类名编写CSS,这样在别人查看你源代码时,能看到代码里出现了很多表情,这似乎也挺有趣的。

CSS选择器的命名是一个哲学问题。如果你开发的项目是小项目,独自开发,生存期短的,那可以完全放飞自我。CSS随便写名,中文,emoji,各种高级选择器都可以用起来,但多人协作可就万万不可这样了。有些自我良好的开发人员写的CSS代码其实质量堪忧,但他们自己根本意识不到这个问题。

建议使用短命名,语义问题可以不怎么关心。理论上推荐组合命名,但具体也应看实际开发情况有所取舍。建议项目中CSS样式添加一个统一的前缀,各个业务模块一定要采用多名称组合的命名方式。应当尽量避免命名冲突。面向属性的命名优点在于CSS重用率高,性能好,即插即用,方便快捷,但不足是适用场景有限,容易被过度使用增加维护成本。面向语义的命名优点是应用场景广泛,可以实现非常精致的布局效果,不足在于代码啰嗦,效率一般。如果是小项目建议使用面向语义,大项目两者一起使用。

不应当在命名中使用拼音,可以从HTML标签或者特定值中寻找灵感,也可以从CSS伪类和HTML布尔属性中寻找灵感。没有任何理由在实际项目中使用id选择器,尽量不要嵌套选择器,使用无嵌套的纯类名选择器,不要歧视面向属性的命名。

可以将一个网站的页面归为下面几块:公用结构,公用模块,UI组件,精致布局和一些细枝末节。除了细枝末节之外都不适合使用面向属性的类名,细枝末节比较适合。

应当正确使用状态类名,最佳实践方法就是使用.active.checked等这样的状态类名进行交互。但是状态类名本身不能存在CSS样式,这样实现交互控制能有效降低日后的维护成本,可读性也增加了。

不建议使用驼峰类名,驼峰命名建议给JavaScript DOM用。组合命名的个数5个为极限,CSS基础样式使用类选择器,没有层级没有标签。

CSS选择符

当包含后代选择符的时候,整个选择器的优先级与祖先元素的DOM层级没有任何关系,这时要看落地元素的优先级,CSS选择器是独立于整个页面的。

使用子选择符的主要目的是为了避免冲突,通过限制关系使得结构更加稳固,但同时也失去了弹性和变化,需要审慎使用。

相邻兄弟选择符会忽略文本节点和注释节点,只认元素节点,可以配合伪类进行低成本实现交互效果。

相邻兄弟选择符的性能比随后兄弟选择符性能要高,但CSS如果不达到数量级讨论性能没有意义。

为什么没有前面兄弟选择符?因为浏览器解析HTML文档是从前往后,从外及里的,这个技术本身实现不难,但不做的原因是CSS和HTML本身的渲染机制决定了这东西大概率不会存在,现在是,以后也是。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2021 Shawn Zhou
  • Hexo 框架强力驱动 | 主题 - Ayer
  • 访问人数: | 浏览次数:

感谢打赏~

支付宝
微信