07 CSS选择器
上一篇
CSS选择器是CSS的主体内容. 选择器字如其名, 通过一些标识特征, 选中DOM中的元素( 伪元素选择器则不然, 后文会提及 ). 上一篇文章初略地列举了选择器地类型和优先级. 本文会详细整理选择器的相关核心知识.
选择器类型
更具三大优先级进行划分为特点的, 有四种. 结构特点划分, 有另外三种. 此外还有内联和!important两个属性.
特异性为我个人定义的选择器的独立优先级, 姑且分为∞,0, 1, 2, 3递减.
三大优先级
-
id选择器
id选择器有全局特异性, 唯一标识了网页中的一个元素; 所以在开发中, 并不是非常常用, 特别是对于需要后续覆盖和复用规则时, 会遇到困难. 如果DOM结构改变, 使用id选择器可能会是你的噩梦.
通过
#id-name进行调用, 特异性为1; -
class选择器和属性选择器
-
class选择器是最常用的选择器, 而且对CSS本意描述也比较符合——某个元素的样式类型. 而且可以方便开发中进行覆盖, 还能重用.
通过
.class-name调用, 特异性为2; -
属性选择器一定程度上可以替代class和id, 既可以通过自定义data属性来进行筛选, 也可以进行匹配查询; 更像是一个简化正则匹配的选择器. 特异性为2;
使用:
[data]--选定拥有data属性的元素;[data=val]--精确匹配属性值data为val的元素;[data~=val]--检查data属性值是否复合val序列中的任意一个;[data|=val]--匹配所有属性值为val开头的元素.
-
-
标签选择器
标签选择器就是HTML标签进行直接选择, 一般进行页面的初试化和整体布局操作; 较常见的就是进行样式重置, 这里一般用到的是全体选择器, 即
*;特别要注意的是, SVG命名空间和HTML命名空间不同, 需要使用@namescape进行指定, 避免元素选择器冲突:
@namespace svg url(http://www.w3.org/2000/svg); @namespace html url(http://www.w3.org/1999/xhtml); svg|a{} html|a{}这样, svg的a标签就不会与html中的冲突.
三大结构
-
复合选择器
复合选择器是连续写在一起的简单选择器, 通过类的交集运算, 选定同一个元素的.
通过连写
.a.b调用, 即同时具备两种class的元素. -
复杂选择器
复杂选择器
≠复合选择器, 复杂选择器通过连接符进行逻辑上的组合. 这些连接符包括:-
空格: 选中符合条件的后代.".x .y" 表示选中.x后代中具有.y的全部节点.
-
>--子选择器: 选中符合条件的子代节点".x > .y" 表示选中.x的子代( 即第一后代 )中具有.y的节点.
-
~--通用兄弟选择器: 选中所有符合条件的后继节点".x ~ .y" 表示选中.x的后继结点中具有.y的节点.
-
+--相邻兄弟选择器: 选中所有复合条件的直接后继节点".x + .y" 表示当.x的直接后继结点具有.y时选中. 相当于nextSlibling.
-
||--列选择器: 选中对应列中的单元格.
html body > div#pagewrap ~ ul#summer-drinks li.favorite { color: red; font-weight: bold; }而实际开发中并不会有这么复杂奇葩的选择器. 上面这些选择符使用最多的就是"
"和">", 实际的生产环境中, 较多使用class的搭配来避免太过复杂的选择器, 也一般不会直接选择, 太过耦合会导致DOM树变化时, 页面规则错乱失效.! 但是需要注意的时: 当属性为可继承时, 子选择器等同于后代选择器.
-
-
选择器列表
,通过","来同时应用同一种规则, 即两个选择器的内容是一致的, 可以进行列表形式的简写, 以
,分割;"a, b" 表示a, b两个选择器使用的规则是同一个.
两种属性
-
style内联样式
内联样式或内部样式表( style标签 )的优先级是最高的, 将规则直接在html中进行编写, 这在测试和临时覆盖有些用处, 但可维护性和可阅读性都不友好.
-
!important例外规则
!important不在优先级中, 而是直接打破规则, 直接作用在最终表达的元素上, !important 不建议使用, 可能会导致代码难以调试和维护. 特别是你想要后续覆盖某些样式时, 会遇到无法按照规则正常显示的问题.
当然!important也有应用场景, 就是希望默写样式固定下来, 保持CSS的稳定时, 可以考虑使用. 或者在
而不是拿来作为覆盖样式的结晶, 这样只会在后面栽跟头.
选择器优先级
选择器优先级的计算有三元组或者四元组来计算, 后者多考虑了内联的优先级.
如图, 如有三元组( a, b, c)或者四元组(x, a, b, c)

- 存在内联时, x为1
- id选择器数目为a; class\伪类\属性选择器数目为b; 标签和伪元素选择器为c.
确定一个足够大的正数M, 则优先级公式为:
符合优先级 = M * M * a + M * b + c
这个M可以是任何值, 只要足够大( 浏览器设置为65536 ), 现在并没有多少的class覆盖id的说法, 那是IE旧时代的问题. 且
- 同个类型选择器进行横向对比.
- 同个优先级选择器顺序覆盖.
- 针对的是单个复杂选择器, 多个选择器选中同一个不会叠加优先级, 而是由优先级最高的决定其优先级.
举个例子:

如图, 四元组为(0, 1, 1, 3); 优先级 = M*M*1+M+3;
整体上有如下建议:
- 使用class组合来决定元素样式,
- 使用标签选择器来控制布局和风格.
- 使用id等特异性强的选择器控制样式稳定.
伪类和伪元素
强烈建议配合MDN食用本小节 伪类与伪元素🔗
伪类
伪类是一系列针对特定状态而CSS规定的选择器, 形如:pesudoClass.
字面解释伪装的类, 即模仿类的行为, 产生的效果和类一致, 可以理解成其选择方式则是由其特定状态而决定的, 而非类class的属性值制定.
伪类数量众多, 大体上可以划分为用户行为伪类和元素结构伪类.
-
用户行为伪类--选中处于特定用户状态的元素.
这里的用户状态指用户与网页的交互状态, 包括但不限于:
- :hover 鼠标悬停
- :active 激活元素, 如按下按钮但未松开时
- :focus 页面焦点在元素上, 如选中输入框
- :target 选中浏览器URL中hash部分( 即href="#id" )所指示的元素.
- :link 未访问过的链接.
- :visited 访问过的链接
- :checked 选中状态中的单选或者复选框
- :playing 媒体资源播放中
- :paused 媒体资源暂停中
-
元素结构伪类
有一些伪类用于在元素结点上进行选取控制的操作.
- :root 匹配DOM树中的根节点, 即相当于html标签. 特别是在scoped css等场景, 用于选中子树.
- :empty 没有子节点的元素
- :first-child \ :last-child 第一个 \ 最后一个元素
- :nth-child(n) 匹配一列兄弟元素中的元素——兄弟元素按照an+b形式的进行匹配(比如2n+1匹配元素所有的奇数个)
- :only-child 匹配没有兄弟结点的元素.
nth缩写: -->1st. 2nd, 3rd, 4th, ......, nth
-
逻辑伪类
主要是
:not()和is(), 其中is()还未完全支持. 主要用于逻辑判断内部是否包含或者不包含选中部分.
伪元素
伪元素pesudo-element和伪类pesudo-class非常类似, 至少理念上, 都是为了完成一些特殊操作而制定的. 伪元素不仅是一种选择器, 相比伪元素它还能完成一些额外的操作, 如插入元素.
早期伪元素甚至使用的也是:, 后续分离, 使用::进行区别. 所以你看到一些较旧的写法:before, :after实际上是浏览器为了保持兼容, 但新的伪元素是不支持的, 所以建议保持::的风格.
用法也和伪类一致, 都是用于描述默些状态, 而伪元素在于它就如一个伪装的元素一样, 对页面DOM产生影响, 却不在DOM中, 因为它是由CSS负责的, 于HTML中的DOM实际上是两个物种.
它们主要有是针对一些特定场景时非常有用:
- ::first-line \ -letter 第一行\第一个字, 对于一些CMS系统自动生成HTML时, 管理样式非常有用.
- ::before 在匹配元素前插入一个可样式化的元素
- ::after 在匹配元素前插入一个可样式化的元素
- ::selection 文档被选中部分.
下一篇
参考引用
- 伪类和伪元素 - 学习 Web 开发 | MDN. (2020). Retrieved 5 March 2021, from developer.mozilla.org/zh-CN/docs/…
- 优先级 - CSS(层叠样式表) | MDN. (2020). Retrieved 5 March 2021, from developer.mozilla.org/zh-CN/docs/…
- Specifics on CSS Specificity | CSS-Tricks. (2010). Retrieved 5 March 2021, from css-tricks.com/specifics-o…
转发请附上原链接, thx~