# 选择器

# 选择器的概念

一个选择器代表一个结构。这种结构可以用作一个条件(例如,在 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 或以上。一般来说,我们认为不同层级选择的权重是不可跨越的。

# 学习资料

Selectors Level 3 (opens new window)

Selectors Level 4 (opens new window)