本文摘录于《css 选择器世界》。
选择器的相关内容并不多,在逻辑关联性和历史发展上也不像 js
能有很多扩展。在这有限的条件下还能写出一本书,的确得佩服作者的水平。
除前端开发都基本能掌握的知识点进行了必要的陈述,此书对伪类做较多扩展,并对各选择器的使用技巧和浏览器兼容性做详细描述,在 css
应用与 js
中的差异,用兼容性反推测用户浏览器 ( - _ - |||
最佳设计实践
最佳设计实践本书最干的部分,也是工作中最应该重视的部分。( 再往后的的内容都是查缺漏的基础内容 )
-
避免使用 ID 选择器
ID 选择器的优先级太高,与js
耦合,不利于维护。 -
避免过多嵌套
嵌套过多导致渲染性能下降,每一层嵌套都导致浏览器多一层计算。
优先级混乱,尽可能的通过命名与设计保持选择器的低优先级。
样式布局脆弱,与html
的结构高度的耦合。.nav a { } .nav a img { } /** 不建议 **/ .nav-a { } .nav-a-img { } /** 建议 **/
-
注意选择器的命名
选择器命名全小写,组合命名可以用-
和_
,不建议使用驼峰命名
要注意避免选择器命名过长。
避免使用拼音命名。
添加合适的前缀。.header { } /** 不建议 **/ .cs-header { } /** 建议 **/ .cs-module-section { } /** 根据标签 **/ .hide { display: none; } /** 根据语义 **/ .ml20 { margin-left: 20px; } /** 根据属性 **/ .cs-radio { } /** 根据标签属性 **/
-
善用伪类和 html 中的布尔值
如:.active
、disabled
、checked
等。 -
项目中选择器分布依据情况使用
规模项目 | 规模项目(含外部引用) | 微小项目 | |
---|---|---|---|
网站级变量 | √ | √ | ? |
css rest/通用结构 | √ | √ | ? |
模块/业务样式 | ? | √ | √ |
样式库 | √ | √ | × |
选择器命名合法性
- 大小写区分:
选择器类型 | 是否敏感 |
---|---|
标签选择器 | 不敏感 |
属性选择器 | 对属性不敏感,属性值敏感 |
类选择器 | 敏感 |
ID 选择器 | 敏感 |
简而言之,对标签名与属性这些在 html 中对大小写不敏感的数据所对应的选择器也不敏感,对于属性值、类名、ID 值这些区分大小写的值属性数据所对应的选择器也敏感。
此外属性选择器支持属性值大小写也不敏感:
[CLASS~='COTNET' i] {
} /** 添加小写 i 即可令属性值的大小写不敏感 **/
- 支持以数字为开头,但在
css
中必须以使用转义符:
.1-foo {
} /** 不支持 **/
.\31-foo {
} /** 支持 **/
- 支持不合法的
ASCII
字符,同样需要转义。 - 支持中文字符。
- 支持
emoji
表情。
选择器的作用域
- 全局作用域
:scpoe
(昙花一现的标准,现已弃用)Shadow DOM
var el = doucment.getElementById('el');
var shadow = el.attachShadow({ mode: 'open' });
shadow.innerHTML = '<p>Shadow DOM</p>';
shadow.innerHTML += '<style>p{color:#fff}</style>';
选择器的命名空间
@namespace url(http:www.w3.org/1999/xhtml);
@namespace svg url(http:www.w3.org/2000/svg);
/* xhtml 的命名空间 */
a {
}
/* svg 的命名空间 */
svg|a {
}
选择器命名空间的兼容性非常好,但却很少用,主要原因在于直接用 css
的嵌套也可以解决命名冲突的问题。而命名空间则提高了该选择器的优先级。
选择器的优先级
级别 | 权重值 | css/选择器 |
---|---|---|
0 | 0 | 通配符 * 、组合连接符( + 、> 、~ 等) 、逻辑组合伪类( :is() 、:not() 、:where() 等) |
1 | 1 | 标签选择器 |
2 | 10 | 类选择器、 属性选择器 、伪类选择器 |
3 | 100 | ID 选择器 |
4 | - | 内联样式 |
5 | - | !important 关键字 |
组合选择器的权重值即为所有单一选择器权重之和,权重值越高则优先级越高。
但权重值的数字和计算方法仅是业内广为流传的说法而并不是绝对的。也即为 11 个标签选择器无法越级 1 个类选择器的权重。
组合连接符
- 后代选择器 ( 空格 )
- 子代选择器 ( > )
- 相邻兄弟选择器 ( + )
- 兄弟选择器 ( ~ )
- 双管道选择器 ( || )
前 4 种选择器太基础不赘述,值得一提的是:由于 DOM
的渲染计算顺序,所有选择器的效果都是 父代影响后代 、排前的选择器影响排后的兄弟节点,此顺序不可逆。
双管道选择器 是 table
布局中的 <colgroup>
与 <col>
的相关实现。
元素选择器
- 唯一不能重复自身的选择器。(其余选择器可以重复自身,但实际开发并没有意义)
- 级联使用时必须写在最前。(可以理解为元素选择器是唯一没有对应关键符号的选择器)
- 高版本浏览器支持自定义标签选择器。
- 通配符选择器支持各种标签,但不包括伪元素。
属性选择器
- ID 与类选择器都属于属性选择器,使用写法和优先级不同。
- 属性值匹配选择器,支持直接匹配与正则匹配。
表达式 描述 [attr] 直接匹配 [attr=val] 完全匹配 [attr|=val] 片段开头匹配 val 或 val- 开头的值 [attr^=val] 匹配 val 开头 [attr$=val] 匹配 val 结尾 [attr*=val] 匹配包含 val
用户行为伪类
-
手型经过伪类
:hover
移动端也能触发,但体验效果不佳故不适用。
桌面端常用语鼠标上浮 和Tip
浮层。 -
激活状态伪类
:active
当鼠标主键按下或触控屏幕时元素触发,可用于任何元素。
主要作用是反馈点击交互,各浏览器兼容效果不同,不适合做复杂交互。 -
聚焦伪类
:focus
匹配:非disabled
状态的表单标签、 包含href
的a
标签、area
标签、summary
标签。
聚焦转态可通过tab
键触发,在其他职能设备上也可通过相关配套设备进行交互,可重置但不应直接取消:focus
的默认样式。 -
整体聚焦伪类
:focus-within
当前元素或当前元素的任意子元素处于聚焦状态则触发。 -
键盘焦点伪类
:focus-visible
仅Chrome
支持
在部分特殊情况下,不同的交互 ( 比如鼠标点击和键盘切换键 ) 预期的效果不同,此时浏览器会主动判断是否应该出现聚焦转态的轮廓。
URL 定位伪类
-
链接伪类
:link
匹配没有访问过href
的a
标签。与 访问过href
的伪类:visited
对应。
由于伪类的优先级相同,样式书写时应注意顺序::link
->:visited
->:hover
->:active
。 -
链接历史伪类
:visited
支持的css
属性有限:color
、background-color
、column-rule-color
、outline-color
。
不支持伪元素,但子元素支持伪元素。
支持半透明的写法,但效果上不支持半透明。
css
属性只能重置不能添加设置。
设置的颜色不能通过js
获取。 -
超链接伪类
:any-link
匹配所有设置了href
的链接标签:a
、link
、area
。
匹配所有:link
与:visited
-
锚点伪类
:target
与URL
中的哈希值匹配,页面元素的id
值 或者a
标签的name
值。 -
目标伪类
:target-within
与:focus-within
类似, 当子元素处于:target
时匹配。
输入伪类
该类伪类常作用于表单组件,与直接用属性选择器的效果不同。属性选择器可以作用于任何标签元素,且不具备表单元素中 fieldset
等联动与继承效果,而此类伪类可以提供更好的设计方案。
-
可用状态伪类
:enabled
与 禁用状态伪类:disabled
在正常情况下,两个伪类完全对立,即两个状态必有一个匹配。 -
读写特性伪类
:ready-only
与:ready-write
匹配html
的readyonly
属性。
:ready-only
与:disabled
的区别是前者依旧可以被表单提交且样式为默认样式,后者默认样式文字置灰。 -
占位符伪类
:placeholder-shown
匹配表单空值时placeholder
占位符显示。 -
默认选项伪类
:default
匹配option
的selected
选中状态。 -
选中项伪类
:checked
匹配单选框和复选框,书中介绍了很多:checked
的使用场景,基本是利用label
与checked
联动使用。 -
不确定值伪类
indeterminate
匹配半选中的复选框。 -
有效性验证伪类
:valid
与:invalid
与html
中required
、pattern
关联匹配。 -
范围伪类
:in-range
与:out-of-range
指的注意type
为rang
的 滑动元素并不存在:out-of-range
-
可选伪类
:required
与optional
相互对立, 匹配是否设置了required
属性的表单元素。 -
用户交互伪类
:user-invalid
与 空值伪类:blank
尚未成熟的伪类。
:user-invalid
为用户输入不匹配内容且用户与之进行明显交互后匹配 ( 尝试提交表单和再次与表单元素交互前 )。
:blank
规范多变,一开始匹配空标签元素,后改为没有输入值表单元素。
树状结构伪类
-
根伪类
:root
匹配html
节点 -
:empty
匹配空标签元素和可闭合的替换元素:button
、textarea
。
注释节点、空格、换行的情况不匹配。
伪元素::before
与::after
不影响匹配。 -
子元素索引伪类:
:first-child
第一个子元素。
:last-child
最后一个子元素。
:only-child
唯一的子元素。
:nth-child()
第 n 个子元素。
:nth-last-child()
反向第 n 个子元素。 -
类型索引伪类:
:first-of-type
同类型第一个元素。
:last-of-type
同类型最后一个元素。
:only-of-type
同类型唯一元素。
:nth-of-type()
第 n 个同类型元素。
:nth-last-of-type()
反向第 n 个同类型元素。
逻辑组合伪类
-
否定伪类
:not()
对只能重置而不能设置的属性可以巧用此伪类使代码更简洁更好理解。 -
任意匹配伪类
:is()
前身为:matches
、:any()
,匹配表达式内任意内容。
与:where()
用法和作用相同,但:where()
的优先级为 0 。 -
has()
- 设想中的功能强大,但目前暂不支持。
其他伪类选择符
-
作用域伪类:
:scope
局部作用域伪类。
:host()
Shadow DOM
根节点伪类 。
:host-context()
Shadow DOM
根节点上下文伪类 。 -
全屏伪类
:fullscreen
-
语言相关伪类:
:dir()
语言方向伪类,:dir(rtl)
为从左向右、:dir(rtl)
为从右向左 。
:lang()
语言类型伪类。 -
资源状态伪类:
:playing
与:paused
播放状态伪类。