一、CSS选择器优先级
!important > 内联【1000】 > id 【100】> class/属性选择器/伪类选择器 【10】> tagName / 伪装元素【1】通配符:0>继承
二、选择器种类
-
*
通配符 -
id选择器
-
class选择器
-
标签选择器
-
组合:
- 后代选择器:
ol li{}
- 子选择器:
div > p {}
- 并集选择器:
ul,div {}
- 相邻选择器:
h1 + p{}
- 后代选择器:
-
属性选择器
- *[att],选择所有具有att属性的元素
- E[att] ,选择所有具有att属性的E元素
- E[att=“value”],选择所有具有att属性,且att属性的值为value的E元素
- E[att~=“value”],选择所有具有att属性,且att属性的其中一个值为value的E元素
- a[href][title] 所用具有href 和title的a标签
-
伪类选择器:是实际DOM元素的某种状态
- 状态伪类:
link、visited、hover、active
- 结构伪类:
p:first-child
: p元素且是父元素的第一个
子元素,如果第一个
不是p元素就没有效果【同理last-child
最后一个p】
p:first-of-type
: 第一个类型为p的字元素,不一定父元素的第一个元素【同理p:nth-of-type(n)
表示n个p类型元素】
p:nth-child(n)
: 父元素中第n个元素,且是p元素【同理p:nth-last-child(2n+1)
表示倒数第n个】
p:only-child
:没有任何兄弟元素
p:only-of-type
:没有任何同类型的兄弟元素
:empty
: 空元素
p:not(.irrelevant)
: 不满足指定条件
root
: 根元素 - 表单伪类:
:invalid
和:valid
表单输入内容是否有效
:required
和:optional
表单项是否必填
:in-range
和:out-of-range
表单项是否超出范围
:read-only
和:read-write
表单项是否只读
:enabled
和:disabled
表单项是否禁用
- 状态伪类:
-
伪元素:附加在选择器上关键字,不属于DOM树上真正的元素,只是元素特定部分的内容
::first-line
:只作用于块级元素::first-letter
只作用于块级元素::before
:元素内容之前插入一些内容::after
:元素内容之后插入一些内容::selection
:用户所选定的元素部分
选择器的性能
CSS选择器匹配的机制:从右到左进行规则匹配
例如:
#header > a
,先匹配所有的 a 元素,再确定其父元素的 id 是否为 header#header a
先匹配所有的 a 元素, 再向其上级遍历直到根节点找是否有 id 是否为 header
所以称最右边选择符称之为关键选择器。
如何减少 CSS 选择器性能损耗
选择器效率排序
id > 类 > 标签 > 相邻选择器(h1+p) > 子选择器(ul > li) > 后代选择器(li a) > 通配符选择器(*) > 属性选择器(a[rel=“external”]) >伪类选择器(a:hover, li:nth-child)
- 关键选择器避免使用通配符
- 避免使用低效选择器修饰效选择器 :用标签/类限制ID选择器:
button#backButton
,标签限制类:treecell.indented {…}
- 尽量少使用子选择器
- 嵌套越短越好
- 尽量利用继承选属性
关于!important
MDN指出“使用 !important 是一个坏习惯,应该尽量避免”,并给出了使用!important 的情况:
一定要优先考虑使用样式规则的优先级来解决问题而不是 !important
只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important
永远不要在你的插件中使用 !important
永远不要在全站范围的 CSS 代码中使用 !important