~= 匹配空格分隔的独立单词,如[class~="btn"]匹配class="btn primary"但不匹配"class=btn-primary";= 进行无边界子串匹配,易误命中,如[class="btn"]会匹配"button"和"subtle-btn"。

~= 匹配 class 中的独立单词,不是字符串包含
它只认空格分隔的完整词,[class~="btn"] 能匹配 class="btn primary" 和 class="primary btn large",但不会匹配 class="btn-primary"、class="button" 或 class="rebtn"。这是因为 ~= 把整个 class 属性值按空白符切分成词表,再逐个比对是否完全相等。
常见误用是把它当“含 btn 就行”的模糊搜索——实际它比 .btn 类选择器还严格(后者还能被预处理器扩展),只是支持任意属性(比如 [lang~="zh"] 也能匹配 lang="zh-CN")。
- 仅适用于空格分隔的多值属性(
class、lang、data-*等) - 大小写敏感,
[class~="Btn"]不匹配class="btn" - 不处理连字符、下划线或数字后缀,
class="btn2"是一个词,≠"btn"
*= 做纯子串扫描,容易误命中
[class*="btn"] 是把整个 class 属性值当成长字符串,只要连续出现 "btn" 三个字符就匹配。它不管词边界、空格或语义,所以会命中 class="subtle-btn"、class="button",甚至 class="attention"(因为含 "tten"?不对,是 "btn" ——等等,"attention" 并不含 "btn";但 "button" 含,"obtain" 也含)。
真正危险的是 CMS 或组件库动态生成的 class 名:比如 class="icon-12345"、class="status-pending",*= 会无差别扫出所有含目标子串的部分。
- 对
title、alt这类自然语言属性慎用,[title*="error"]可能选中"This is not an error" - 大小写默认敏感,现代浏览器支持
[data-type*="user" i]忽略大小写,IE 不支持 - 不要在
id上滥用,[id*="1"]会同时匹配id="1"、id="item-123"、id="debug1flag"
什么时候该用 ~=,什么时候该用 *=
核心判断标准是:你控制的是值格式,还是依赖 HTML 原生语义?
如果 class 名由你统一管理、空格分隔、无连字符干扰(如 BEM 风格的 btn btn--primary),优先用 [class~="btn"] —— 它语义清晰、可预测、调试友好。
如果你要匹配的是自定义 data- 属性,且值由 JS 动态拼接(如 data-id="user-123-draft"),[data-id*="draft"] 更直接有效,因为你能确保子串唯一性。
- 想匹配多值中的某个语义化标签 → 用
~= - 想识别前缀统一的命名空间(如
data-component="modal-header")→ 用^= - 想找文件扩展名或固定后缀 → 用
$= - 只有当你明确需要“字符串里有这段连续字符”,且已排除误匹配风险 → 才用
*=
真实项目里最常翻车的点
很多人在调试时发现样式没生效,回头一看是写了 [class="btn"] 想“包含 btn”,结果它只匹配 class="btn" 这种单值情况,连 class="btn primary" 都不中——这是把 = 和 ~= 搞混了。
另一个高频坑:用 [class*="icon"] 给图标加样式,结果 class="notification" 也被染上了(因为含 "noti",而 "noti" 含 "i"?不对,"notification" 含 "icon" —— 是的,它确实含 "icon",这就是 *= 的本质:不负责判断是不是你想找的那个 icon)。
真正安全的做法是:把机器可读的标识挪到 data- 属性里,比如 data-role="icon",再用 [data-role~="icon"] 或 [data-role*="icon"] 匹配——这样你完全掌控值的内容和结构,不被 HTML 原生属性的语义包袱拖累。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











