选择器是匹配元素的一种模式,不只是在CSS中,JavaScript对CSS的选择器也是支持的,比如document.document.querySelectorAll
。
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匹配的元素的时候尽量进行少的查找, 所以选择器最好写的简洁一点。
权重,也就是选择器的优先级,每条选择器的规则都有其权重,权重大的会覆盖掉权重小的,很多CSS出现问题的场景,都是某处定义了一个更高权重的规则,导致此处规则不生效。
根据样式所在位置,对元素的影响也有关系:内联样式(标签内style形式) > style标签 > link标签。
另外一点需要注意的是!improtant
,凡是属性值后加上了!important
,那么它的值不会被其他值替换。
通过这篇文章你应该知道的一些事情——CSS权重。了解下权重的计算,主要的规则就是:
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"。先来看最常见的锚点伪类。
主要是针对于HTML中的Form元素操作, IE8不支持":checked",":enabled",":disabled"这三种选择器。
主要注意的是CSS3添加的nth选择器在IE8下不支持。
见图:
选择器的兼容性: