CSS选择器学习笔记
🎯 CSS 选择器终极指南:从基础到高级 (完整版)
这份笔记旨在提供一份全面、现代的 CSS 选择器参考,涵盖核心概念、类型详解、组合策略、优先级规则、实用技巧以及前沿特性。
📌 一、 核心概念回顾:选择器的作用与结构
- 作用: CSS 选择器是用于“定位”HTML 文档中一个或多个元素的模式或表达式,以便为它们应用样式规则 (
{ ... }内的声明)。 - 结构: 一条 CSS 规则通常由选择器 (Selector) 和声明块 (Declaration Block) 组成。
选择器 { 属性1: 值1; 属性2: 值2; /* ... */ }
🔍 二、 选择器类型详解 (分类增强版)
1️⃣ 基本选择器 (Fundamental Selectors)
| 选择器 | 语法 | 描述 | 示例 | 使用频率 |
|---|---|---|---|---|
| 元素选择器 (Type Selector) | element |
选择所有指定类型的 HTML 元素。 | p 选择所有 <p> 元素。 |
⭐⭐⭐⭐⭐ |
| 类选择器 (Class Selector) | .classname |
选择所有具有指定 class 属性值的元素(一个元素可以有多个类)。 |
.warning 选择 class="warning" 的元素。 |
⭐⭐⭐⭐⭐ |
| ID 选择器 (ID Selector) | #idname |
选择具有指定 id 属性值的元素(ID 在文档中应唯一)。 |
#header 选择 id="header" 的元素。 |
⭐⭐⭐⭐ (谨慎使用) |
| 通配选择器 (Universal Selector) | * |
选择文档中的所有元素。 | * 选择页面所有元素。 |
⭐ (特定场景) |
| 属性选择器 (Attribute Selector) | [attr] |
选择具有指定属性的元素(不论值)。 | [disabled] 选择所有带 disabled 属性的元素。 |
⭐⭐⭐⭐ |
| 分组选择器 (Grouping Selector) | selector1, selector2, ... |
将相同的样式应用于多个选择器匹配的所有元素。 | h1, h2, .title 选择所有 <h1>, <h2> 和 .title 元素。 |
⭐⭐⭐⭐⭐ |
属性选择器增强详解:
| 语法 | 描述 | 示例 |
|---|---|---|
[attr] |
存在属性 attr。 |
[target] |
[attr=value] |
属性 attr 的值精确等于 value (区分大小写)。 |
[type="submit"] |
[attr~=value] |
属性 attr 的值是一个由空格分隔的列表,其中包含 value。 |
[class~="btn"] (匹配 class="btn btn-primary", 不匹配 class="btn-primary") |
| `[attr | =value]` | 属性 attr 的值精确等于 value 或 以 value- 开头(常用于语言子码)。 |
[attr^=value] |
属性 attr 的值以 value开头。 |
a[href^="https://"] |
[attr$=value] |
属性 attr 的值以 value结尾。 |
a[href$=".pdf"] |
[attr*=value] |
属性 attr 的值包含子字符串 value。 |
[src*="logo"] |
[attr operator value i] |
在操作符后添加 i (或 I) 使比较不区分大小写。 |
[class*="primary" i] |
2️⃣ 组合选择器 (Combinators - 关系选择器)
| 选择器 | 语法 | 描述 | 示例 | 使用频率 |
|---|---|---|---|---|
| 后代组合器 (Descendant) | A B |
选择作为元素 A 后代的所有元素 B(不限于直接子元素)。 |
article p 选择 <article> 内的所有 <p> (无论嵌套多深)。 |
⭐⭐⭐⭐⭐ |
| 直接子代组合器 (Child) | A > B |
选择作为元素 A 直接子元素的所有元素 B。 |
ul > li 选择直接嵌套在 <ul> 内的 <li>。 |
⭐⭐⭐⭐ |
| 一般兄弟组合器 (General Sibling) | A ~ B |
选择元素 A 之后所有同层级的元素 B。 |
h2 ~ p 选择同一父元素中 <h2> 之后的所有 <p>。 |
⭐⭐⭐ |
| 相邻兄弟组合器 (Adjacent Sibling) | A + B |
选择紧接在元素 A 之后的下一个同层级元素 B。 |
h1 + p 选择紧跟在 <h1> 之后的第一个 <p>。 |
⭐⭐⭐ |
| 列组合器 (Column) | `A | B` | (实验性/Level 4) 选择属于表格列 A 一部分的元素 B。 |
3️⃣ 伪类 (Pseudo-classes) - 基于元素状态或位置
| 类别 | 伪类 | 描述 | 示例/用途 | 使用频率 |
|---|---|---|---|---|
| 状态伪类 | :link |
选择未被访问过的超链接。 | a:link |
⭐⭐ |
:visited |
选择已被访问过的超链接(出于隐私限制,可应用的样式有限)。 | a:visited |
⭐ | |
:hover |
选择鼠标指针悬停在其上的元素。 | button:hover |
⭐⭐⭐⭐⭐ | |
:active |
选择正在被激活的元素(如鼠标按下时)。 | a:active, button:active |
⭐⭐⭐ | |
:focus |
选择获得焦点的元素(如通过 Tab 键导航或点击)。 | input:focus |
⭐⭐⭐⭐ | |
:focus-visible |
选择通过键盘等非指针设备获得焦点且浏览器认为应该显示焦点指示的元素。 | button:focus-visible (替代 :focus 避免在鼠标点击时显示) |
⭐⭐⭐⭐ (推荐) | |
:focus-within |
选择自身或其任何后代获得焦点的元素。 | form:focus-within (当表单内任意输入框聚焦时高亮整个表单) |
⭐⭐⭐⭐ | |
:target |
选择 URL 片段标识符(如 #section1)指向的元素。 |
:target |
⭐⭐ | |
:enabled |
选择可用状态的表单元素(默认状态)。 | input:enabled |
⭐⭐ | |
:disabled |
选择禁用状态 (disabled) 的表单元素。 |
input:disabled |
⭐⭐⭐ | |
:checked |
选择被勾选的复选框 (<input type="checkbox">)、单选按钮 (<input type="radio">) 或 <option>。 |
input[type="checkbox"]:checked |
⭐⭐⭐⭐ | |
:indeterminate |
选择不确定状态的复选框(通常由 JavaScript 设置)、未选择的单选按钮组或进度条。 | input[type="checkbox"]:indeterminate |
⭐⭐ | |
:placeholder-shown |
选择显示占位符文本 (placeholder 属性) 的 <input> 或 <textarea>。 |
input:placeholder-shown |
⭐⭐⭐ | |
:required |
选择必填 (required) 的表单元素。 |
input:required |
⭐⭐⭐ | |
:optional |
选择非必填 (没有 required) 的表单元素。 |
input:optional |
⭐⭐ | |
:valid |
选择通过验证的表单元素(符合 pattern 或类型要求)。 |
input:valid |
⭐⭐⭐ | |
:invalid |
选择未通过验证的表单元素。 | input:invalid |
⭐⭐⭐ | |
:in-range |
选择值在 min/max 范围内的数字输入框 (<input type="number"> 等)。 |
input[type="number"]:in-range |
⭐⭐ | |
:out-of-range |
选择值超出 min/max 范围的数字输入框。 |
input[type="number"]:out-of-range |
⭐⭐ | |
:read-only |
选择只读 (readonly) 的元素。 |
input:read-only |
⭐⭐ | |
:read-write |
选择非只读(没有 readonly)的元素。 |
input:read-write |
⭐⭐ | |
| 结构性/位置伪类 | :root |
选择文档的根元素(通常是 <html>)。定义 CSS 变量的理想位置。 |
:root { --color-primary: blue; } |
⭐⭐⭐⭐ |
:first-child |
选择其父元素中的第一个子元素。 | ul li:first-child |
⭐⭐⭐⭐ | |
:last-child |
选择其父元素中的最后一个子元素。 | ul li:last-child |
⭐⭐⭐⭐ | |
:only-child |
选择是其父元素中唯一子元素的元素。 | div p:only-child |
⭐⭐ | |
:nth-child(n) |
选择其父元素中第 n 个子元素。n 可以是数字、关键字 (odd, even) 或公式 (2n+1)。 |
tr:nth-child(odd), li:nth-child(3), div:nth-child(3n+1) |
⭐⭐⭐⭐⭐ | |
:nth-last-child(n) |
选择其父元素中倒数第 n 个子元素。 | tr:nth-last-child(1) (最后一行) |
⭐⭐⭐ | |
:first-of-type |
选择其父元素中同类型元素中的第一个。 | article p:first-of-type |
⭐⭐⭐⭐ | |
:last-of-type |
选择其父元素中同类型元素中的最后一个。 | article p:last-of-type |
⭐⭐⭐⭐ | |
:only-of-type |
选择其父元素中唯一的该类型元素。 | article img:only-of-type |
⭐⭐ | |
:nth-of-type(n) |
选择其父元素中同类型元素中的第 n 个。 | article p:nth-of-type(2) |
⭐⭐⭐⭐ | |
:nth-last-of-type(n) |
选择其父元素中同类型元素中的倒数第 n 个。 | article p:nth-last-of-type(1) |
⭐⭐⭐ | |
:empty |
选择没有子元素(包括文本节点,空格也算文本节点)的元素。 | div:empty |
⭐⭐ | |
:not(selector) |
否定伪类:选择不匹配内部选择器 selector 的元素。 |
button:not([disabled]), div:not(.special) |
⭐⭐⭐⭐ | |
:where(selector) |
匹配伪类:匹配内部选择器 selector,但其权重始终为 0。用于引入低权重覆盖。 |
:where(header, footer) a { ... } |
⭐⭐⭐ (Level 4) | |
:is(selector) |
匹配伪类:匹配内部选择器 selector,权重由内部选择器列表中权重最高的决定。简化复杂选择器。 |
:is(header, footer) a { ... } |
⭐⭐⭐ (Level 4) | |
:has(selector) |
父选择器/关系伪类:(Level 4,逐步支持) 选择包含匹配 selector 的后代元素、直接子元素或相邻兄弟的元素。 |
article:has(img.highlight), div:has(> p.warning), h1:has(+ p.intro) |
⭐⭐⭐⭐ (未来核心) |
4️⃣ 伪元素 (Pseudo-elements) - 样式化元素的特定部分
| 伪元素 | 语法 (推荐) | 描述 | 示例/用途 | 使用频率 |
|---|---|---|---|---|
::before |
::before |
在元素内容之前创建一个可样式化的虚拟子元素。需配合 content 属性。 |
.quote::before { content: "“"; font-size: 2em; } |
⭐⭐⭐⭐ |
::after |
::after |
在元素内容之后创建一个可样式化的虚拟子元素。需配合 content 属性。 |
.link::after { content: " ↗"; } |
⭐⭐⭐⭐ |
::first-letter |
::first-letter |
选择块级元素 (block) 的第一行第一个字母。常用于首字下沉效果。 |
p::first-letter { font-size: 200%; float: left; } |
⭐⭐ |
::first-line |
::first-line |
选择块级元素的第一行文本。 | p::first-line { font-weight: bold; } |
⭐⭐ |
::selection |
::selection |
选择用户用鼠标或其他设备选中的文本部分。 | ::selection { background-color: yellow; color: black; } |
⭐⭐ |
::placeholder |
::placeholder |
选择表单元素中占位符文本 (placeholder 属性)。 |
input::placeholder { color: #999; } |
⭐⭐⭐ |
::marker |
::marker |
选择列表项 (<li>) 的标记符号(项目符号或数字)。 |
li::marker { color: red; } |
⭐⭐ |
::backdrop |
::backdrop |
(实验性) 选择在全屏模式或使用 <dialog> 元素时元素背后的底层区域。 |
dialog::backdrop { background-color: rgba(0,0,0,0.5); } |
⭐ (特定场景) |
注意: 虽然 :before 和 :after 等单冒号写法仍广泛兼容,但规范已明确推荐使用双冒号 (::) 语法来区分伪类和伪元素。
⚖️ 三、 优先级 (Specificity) 与层叠 (Cascading)
-
层叠规则 (Cascading): 当多个规则应用于同一个元素时,CSS 通过以下顺序(优先级递增)决定最终应用哪个样式:
- 来源顺序: 后出现的规则覆盖先出现的规则(在同一个样式表中)。
!important: 带有!important的声明具有最高优先级(谨慎使用,易导致维护困难)。- 优先级 (Specificity): 计算选择器的权重。
-
优先级计算规则: 选择器权重由 4 个部分(a, b, c, d)组成,比较时从左到右(a > b > c > d):
- a:
style属性(行内样式),加 1 (1,0,0,0)。 - b: ID 选择器的数量。
- c: 类选择器、属性选择器、伪类选择器的数量。
- d: 元素选择器、伪元素选择器的数量。
- 通配符 (
*)、组合器 (+,>,~,) 和:where(): 权重为 0。 :is(),:not(),:has(): 其权重等于参数列表中权重最高的选择器。
选择器示例 权重 (a,b,c,d) 计算说明 style="color:red;"1, 0, 0, 0 行内样式 (a=1) #header0, 1, 0, 0 1个ID选择器 (b=1) .nav .item.active0, 0, 3, 0 3个类选择器 (c=3) ul li a:hover0, 0, 1, 3 1个伪类 ( :hoverc=1), 3个元素选择器 (d=3)div0, 0, 0, 1 1个元素选择器 (d=1) *0, 0, 0, 0 通配符 :is(#main, .content) p0, 1, 0, 1 :is()内最高权重是#main(b=1), 加上p(d=1):where(.special) p0, 0, 0, 1 :where()权重为0, 加上p(d=1)button:not([disabled])0, 0, 1, 1 :not()权重为1个属性选择器[disabled](c=1), 加上button(d=1) - a:
🧠 四、 高级技巧与最佳实践
- 善用组合: 结合不同类型的选择器精确匹配目标元素 (e.g.,
.user-list li:first-child img). :not()的威力: 排除特定元素非常高效 (e.g.,input:not([type="hidden"]),div:not(.ignore)).:where()和:is()简化: 减少重复代码,管理权重 (:where()用于引入低权重覆盖)。:has()的潜力: (逐步支持) 实现基于内容的父元素选择,是 CSS 逻辑的重大飞跃。- 属性选择器灵活性: 利用
^=,$=,*=,|=,~=进行模式匹配。 - 伪元素
::before/::after创意: 添加装饰性内容、图标、清除浮动等,无需额外 HTML。 - 状态反馈:
:hover,:focus/:focus-visible,:active,:disabled对交互至关重要。 - 结构性伪类优化列表/表格:
:nth-child(),:first-child,:last-child美化列表项。 - 表单状态增强:
:valid,:invalid,:required,:placeholder-shown提升表单体验。 - 优先级管理:
- 避免过度使用 ID 选择器(权重过高,难以覆盖)。
- 尽量使用类选择器,保持低权重和可复用性。
- 谨慎使用
!important,只在万不得已时(如覆盖第三方库样式)。 - 利用
:where()降低引入样式的权重。
- 性能考量:
- 避免过于复杂或深层嵌套的选择器链 (e.g.,
body div#container ul li a span.highlight)。 - 浏览器解析 CSS 是从右向左的。
.sidebar > .nav > .item会先找到所有.item,再检查其父级。确保最右边的选择器(键选择器)尽可能具体高效。 - 相对于
div .myClass,直接使用.myClass通常性能更好(只要不引起冲突)。 - 现代浏览器优化很好,性能瓶颈更可能在 JS 或渲染,但仍应保持选择器简洁。
- 避免过于复杂或深层嵌套的选择器链 (e.g.,
- 可访问性 (A11y):
- 确保
:focus状态清晰可见(可使用:focus-visible)。 :hover效果不应是唯一的信息提示方式。- 结构选择器 (
:nth-child,:first-of-type) 不影响源码顺序和屏幕阅读器导航。
- 确保
- 命名约定 (BEM, SMACSS 等): 使用如
.block__element--modifier(BEM) 规范类名,提高可读性和降低选择器复杂度。
🚀 五、 CSS 选择器 Level 4+ 新特性 (前瞻/实验性)
:has()全面支持: 将彻底改变 CSS 选择能力,允许根据子元素或兄弟元素状态选择父元素。:focus-within增强: 更广泛支持。:dir(ltr/rtl): 基于文本方向选择元素。:any-link: 匹配任何超链接 (:link或:visited)。:blank: 选择空输入框或完全为空的元素 (比:empty宽松)。:user-invalid/:user-valid: 区分用户交互后的验证状态。:nth-col() / :nth-last-col(): 更精细的表格列选择。:scope: 在特定上下文中选择当前作用域元素 (在 Shadow DOM 或querySelector中更有用)。- 相对选择器语法: (如
A:has(+ B)) 更灵活地表达关系。
📝 总结
这份扩充版笔记覆盖了从最基础的到最前沿的 CSS 选择器知识。掌握它们,你将能:
- 精确定位文档中的任何元素或元素组。
- 响应元素状态(交互、表单、验证)。
- 基于位置和结构应用样式。
- 创建装饰性内容而不污染 HTML。
- 编写高效、可维护的 CSS 代码。
- 理解并控制样式规则的层叠和优先级。
核心建议: 优先使用类选择器,善用组合和伪类,谨慎使用 ID 和 !important,关注性能与可访问性,并持续关注新标准 (:has() 是未来重点!)。实践是掌握选择器的最佳途径。💪
本文来自博客园,作者:liessay,转载请注明原文链接:https://www.cnblogs.com/liessay/p/19065224

浙公网安备 33010602011771号