选择器是匹配元素的一种模式,不只是在CSS中,JavaScript对CSS的选择器也是支持的,比如document.querySelector( )
和document.querySelectorAll( )
。
选择器类型
基本选择器
- 通配符选择器(
*
) - id选择器(
\#ID
) - 类选择器(
.className
) - 元素选择器(
E
) - 后代选择器(
E F
) - 子元素选择器(
E>F
) - 相邻兄弟元素选择器(
E + F
) - 群组选择器(
selector1,selector2,...,selectorN
)
属性选择器
使用CSS3属性选择器,你可以只指定元素的某个属性,或者你还可以同时指定元素的某个属性和其对应的属性值。
E[attr]
:只使用属性名,但没有确定任何属性值E[attr="value"]
:指定属性名,并指定了该属性的属性值E[attr~="value"]
:指定属性名,并且具有属性值,此属性值是一个词列表,并且以空格隔开,其中词列表中包含了一个value词,而且等号前面的~
不能不写E[attr^="value"]
:指定了属性名,并且有属性值,属性值是以value开头的;E[attr$="value"]
:指定了属性名,并且有属性值,而且属性值是以value结束的;E[attr*="value"]
:指定了属性名,并且有属性值,而且属值中包含了value;E[attr|="value"]
:指定了属性名,并且属性值是value或者以“value-”开头的值( 比如说zh-cn );
伪类选择器
伪类选择器的形式就是:xxx
, 比如:hover
, :link
, :nth
。
动态伪类
这些伪类并不存在于HTML中,而只有当用户和网站交互的时候才能体现出来.
动态伪类包含两种,第一种是我们在链接中常看到的锚点伪类,如:link
,:visited
;
另外一种被称作用户行为伪类,如:hover
,:active
和:focus
。
锚点伪类
锚点伪类爱恨原则(LoVe/HAte)
为了可以正确地渲染链接元素的样式,:link
伪类选择器应当放在其他伪类选择器的前面,并且遵循LVHA的先后顺序,即::link
— :visited
— :hover
— :active
。
:link
:link
伪类选择器是用来选中元素当中的链接。它将会选中所有尚未访问的链接,包括那些已经给定了其他伪类选择器的链接(例如:hover
选择器,:active
选择器,:visited
选择器)。
:visited
:link
伪类选择器是用来选中所有已访问过的链接
用户行为伪类
:hover
: 用于当用户把鼠标移动到元素上面时的效果:active
: 用于用户点击元素那一下的效果( 正发生在点的那一下,松开鼠标左键此动作也就完成了 ):focus
: 用于元素成为焦点,这个经常用在表单元素上
UI元素状态伪类
我们把:enabled
,:disabled
,:checked
伪类称为UI元素状态伪类,这些主要是针对于HTML中的Form元素操作。
最常见的比如我们”type=”text”有enable
和disabled
两种状态,前者为可写状态后者为不可状态;另外”type=”radio”和”type=”checkbox”有checked
和unchecked
两种状态。
IE6-8不支持:checked
,:enabled
,:disabled
这三种选择器。
CSS3的:nth选择器
需要注意的是CSS3添加的nth选择器在IE8下不支持。
:first-child
选择某个元素的第一个子元素;:last-child
选择某个元素的最后一个子元素;:nth-child()
选择某个元素的一个或多个特定的子元素;:nth-last-child()
选择某个元素的一个或多个特定的子元素,从这个元素的最后一个子元素开始算;:nth-of-type()
选择指定的元素;:nth-last-of-type()
选择指定的元素,从元素的最后一个开始计算;:first-of-type
选择一个上级元素下的第一个同类子元素;:last-of-type
选择一个上级元素的最后一个同类子元素;:only-child
选择的元素是它的父元素的唯一一个了元素;:only-of-type
选择一个元素是它的上级元素的唯一一个相同类型的子元素;:empty
选择的元素里面没有任何内容。
选择器权重
权重,也就是选择器的优先级,每条选择器的规则都有其权重,权重大的会覆盖掉权重小的,很多CSS出现问题的场景,都是某处定义了一个更高权重的规则,导致此处规则不生效。
权重的计算
通过这篇文章你应该知道的一些事情——CSS权重。了解下权重的计算,主要的规则就是:
id选择器 > 类,属性选择器和伪类选择器 > 元素和伪元素
需要注意的是!improtant
,凡是属性值后加上了!important
,那么它的值不会被其他值替换。
根据样式所在位置,对元素的影响也有关系:内联样式( 标签内style形式 ) > style标签 > link标签。
CSS解析器
HTML 经过解析生成 DOM Tree;而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render tree,最终用来进行绘图。
Render tree 中的元素( WebKit 中称为renderers
,Firefox 下为frames
)与 DOM 元素相对应,但非一一对应:一个 DOM 元素可能会对应多个renderer
,如文本折行后,不同的行会成为 Render tree 中不同的renderer
。也有的 DOM 元素被 Render tree 完全无视,比如display:none
的元素。
在建立 Render tree 时( WebKit 中的Attachment
过程 ),浏览器就要为每个 DOM Tree 中的元素根据 CSS 的解析结果( Style Rules )来确定生成怎样的renderer
。对于每个 DOM 元素,必须在所有 Style Rules 中找到符合的selector
并将对应的规则进行合并。选择器的解析实际是在这里执行的,在遍历 DOM Tree 时,从 Style Rules 中去寻找对应的selector
。
解析顺序–从右到左原则
浏览器读取你的选择器,遵循的原则是从选择器的右边到左边读取。换句话说,浏览器读取选择器的顺序是由右到左进行著作权归作者所有,即选择器从右到左的原则。
CSS匹配不是从左到右进行查找,而是从右到左进行查找。如果从左到右的顺序,那么每条选择器都需要遍历整个DOM树,性能很受影响。所谓高效的CSS就是让浏览器在查找style匹配的元素的时候尽量进行少的查找。
选择器的最后一部分,也就是选择器的最右边部分被称为“关键选择器”,它将决定你的选择器的效率如何?是高还是低。
选择器优化
选择器效率
- id选择器(
#myid
) - 类选择器(
.myclassname
) - 标签选择器(
div
,h1
,p
) - 相邻选择器(
h1+p
) - 子选择器(
ul > li
) - 后代选择器(
li a
) - 通配符选择器(
*
) - 属性选择器(
a[rel="external"
]) - 伪类选择器(
a:hover
,li:nth-child
)
id和类名用于关键选择器上效率是最高的,而CSS3的仿伪类和属性选择器,虽然使用方便,但其效率却是最低的。
几种书写高效率的CSS选择器
- 避免普遍规则
- 不要在ID选择器前加标签名或类名
- 不要在类名选择器前加标签名
- 尽可能使用具体的类别
- 避免使用后代选择器
- 标签分类规则中不应该包含一个子选择器
- 子选择器的问题
- 借助相关继承关系
- 使用范围内的样式表
附CSS选择器图: