# 选择器
# 选择器的概念
一个选择器代表一个结构。这种结构可以用作一个条件(例如,在 CSS 规则中),用于确定选择器在文档树中匹配哪些元素,或者用作与该结构相对应的 HTML 或 XML 片段的平面描述。
每个元素可能具有以下五个方面中的任何一个,可以对其进行选择,所有这些都以字符串的形式匹配:
- 元素的类型(标签名)。
- 元素的命名空间(namespace)。
- 一个 ID 标识(id)。
- 它所属的类(class)。
- 属性(它们是名称-值对)。
# 选择器的种类
基本选择器,通过标签的基本特征进行选择
基本选择器 | 示例 | 描述 |
---|---|---|
通配 | * | 选择所有元素。 |
标签 | p | 选择所有 <p> 元素。 |
ID | #id1 | 选择 id="id1" 的所有元素。 |
类名 | .class1 | 选择 class="class1" 的所有元素。 |
属性选择器,通过表带自身的属性进行选择
属性选择器 | ||
---|---|---|
准确匹配 | [target] | 选择带有 target 属性的元素。 |
准确匹配 | [target=a] | 选择带有 target 属性,且属性值为 a 的元素。 |
准确匹配 | [title~=flower] | 选择带有 title 属性,其中包含 "flower" 的元素。 |
子串匹配 | [src^="https"] | 选择其 src 属性值以 "https" 开头的元素 |
子串匹配 | [src$=".pdf"] | 选择其 src 属性以 ".pdf" 结尾的元素 |
子串匹配 | [src*="abc"] | 选择其 src 属性中包含 "abc" 子串的元素。 |
伪类是简单的选择器,允许基于文档树之外的信息进行选择,或者使用其他简单的选择器可能难以表达或无法表达。它们也可以是动态的,从某种意义上说,当用户与文档交互时,元素可以获取或丢失伪类,而文档本身不会发生变化。伪类不会出现在或修改文档源或文档树。
状态伪类选择器,在用户交互时进行选择
状态伪类选择器 | |
---|---|
a:link | 选择所有未被访问的链接。 |
a:visited | 选择所有已被访问的链接。 |
a:hover | 选择鼠标指针位于其上的链接。 |
a:active | 选择被鼠标点中的链接。 |
input:focus | 选择获得焦点的 <input> 元素。 |
input:enable | 选择状态为可用的元素 |
input:disable | 选择状态为禁用的元素 |
input:checked | 选择状态为被选中的元素 |
input:required | 选择状态为必选的元素 |
input:potional | 选择状态为可选的元素 |
input:default | 选择状态为默认的元素 |
input:valid | 选择状态为输入合法的元素 |
input:invalid | 选择状态为输入非法的元素 |
input:in-range | 选择状态为输入在范围内的元素 |
结构伪类选择器,用于常规选择器难以表达的情况下进行选择
结构伪类选择器 | |
---|---|
:root | 选中 html |
p:first-child | 选中和 p 元素同级的第一个元素 |
p:last-child | 同理,选中 p 元素同级最后一个子元素 |
p:only-child | 选中 p 元素同级的一个唯一子元素,即单独一个 p 时选中 p |
p:first-of-type | 选中和 p 元素同级的第一个 p 元素 |
p:last-of-type | 选中和 p 元素同级的最后一个 p 元素 |
p:only-of-type | 选中 p 元素同级的一个无同类元素的子元素 |
p:nth-child(num) | 现在可以选择第几个 |
p:nth-of-type(num) | 同理 |
p:nth-last-child(num) | 现在给我倒过来数 |
p:nth-last-of-type(num) | 同理 |
伪元素表示一个元素不直接出现在文档树中。它们用于创建关于文档树的抽象,超出文档树提供的抽象。
伪元素选择器 | |
---|---|
p::first-line | 选择每个 <p> 元素的第一行 |
p::first-letter | 选择每个 <p> 元素的第一个字符 |
p::before | 在每个 <p> 元素的内容之前插入内容。默认属于行内元素 |
p::after | 在每个 <p> 元素的内容之后插入内容。默认属于行内元素 |
p::selection | 选择被用户选取的元素部分 |
通过逻辑组合,实现更多选择和权重搭配
逻辑组合 | ||
---|---|---|
交集 | div.nav | div.nav 选择所有类名含有 nav 的<div> 元素。 |
取反 | div:not(.nav) | div:not(.nav) 选择所有类名不含 nav 的<div> 元素。 |
并集 | div,p | div,p 选择所有 <div> 元素和所有 <p> 元素。 |
通过层次关系,实现更多选择和权重搭配
层级关系 | ||
---|---|---|
后代元素 | div p | div p 选择 <div> 元素内部的所有 <p> 元素。 |
子元素 | div > p | div > p 选择父元素为 <div> 元素的直接 <p> 子元素 |
相邻元素 | div + p | div + p 选择紧接在 <div> 元素之后的第一个<p> 元素 |
兄弟元素 | div ~ p | div ~ p 选择紧接在 <div> 元素之后的所有<p> 元素。 |
# 选择器的权重
选择器 | 例子 | 权重 |
---|---|---|
!important | style=" xxx !important" | 高阶无穷 |
!important | !important | 无穷 |
行内样式 | style="" | 1, 0, 0, 0 |
ID | #nav | 0, 1, 0, 0 |
类名/伪类/属性 | .header ,:hover ,[] | 0, 0, 1, 0 |
元素/伪元素 | body | 0, 0, 0, 1 |
通用(*)、子(>)、相邻同胞(+) | 比如 ul>li (总权重仍然是 0, 0, 0, 2) | 0, 0, 0, 0 |
权重不可跨越
听说早期的浏览器权重实现比较粗暴,每个级别之间使用 255 作为进制,因此如果使用 256 个以上的类名,可以超过 ID 选择器的权重,好像后来又改成了 65535 或以上。一般来说,我们认为不同层级选择的权重是不可跨越的。