[attr~="value"]只匹配空格分隔的完整单词,因css规范定义其为全词匹配:将属性值按ascii空格切分为token后逐个严格相等比对,不支持子串、前缀、大小写忽略或非空格分隔符。
![css如何匹配具有空格分隔属性值中的一个_使用[attr~=\'value\']符号](https://img.php.cn/upload/article/000/969/633/177467949345814.jpeg?x-oss-process=image/resize,p_40)
为什么[attr~="value"]只匹配空格分隔的单词,而不是子串
因为 CSS 规范明确定义了[attr~="value"]是「全词匹配」:它把属性值按空格切分成独立 token,再逐个比对是否完全等于value。不是indexOf,也不是正则includes,更不支持通配或模糊。
常见错误现象:class="btn btn-primary"能被[class~="btn-primary"]命中,但data-tags="javascript react vue"写成[data-tags~="react"]就有效;而data-tags="javascript-react-vue"哪怕含react二字,也完全不匹配——中间没空格,就不算一个独立词。
- 必须是空格(U+0020)分隔,制表符、换行、全角空格都不行
- 首尾空格会被忽略,但连续多个空格等价于一个分隔符
- 大小写敏感,
[lang~="en"]不会匹配lang="EN"
[attr~="value"]和[attr*="value"]、[attr^="value"]的根本区别
三者语义完全不同,混用会导致样式失效或误匹配:
-
[attr~="value"]:只认空格分隔的完整单词,适合class、rel、lang这类设计为多值的属性 -
[attr*="value"]:子串搜索,只要属性值中任意位置包含value就匹配,比如href*="github"能匹配https://github.com/user/repo -
[attr^="value"]:前缀匹配,比如src^="https://"筛 HTTPS 资源
性能上,~需做 token 切分和遍历,比^略慢但可忽略;而*在长属性值里可能触发回溯,尤其带正则风格字符时(虽然 CSS 本身不支持正则,但引擎内部处理类似)。
哪些 HTML 属性真正适合用[attr~="value"]
不是所有带空格的属性都适用——必须是规范定义为「空格分隔的无序集合」的属性,浏览器才按 token 解析。典型有:
-
class:最常用,[class~="hidden"]匹配class="section hidden" -
rel:如[rel~="noopener"]匹配rel="noopener noreferrer" -
rev(已废弃,但旧代码可能遇到) -
lang:严格按 BCP 47 标准,[lang~="en-US"]匹配lang="en-US en-GB"
反例:data-*属性虽常存空格分隔字符串,但浏览器不将其视为 token 化属性,[data-roles~="admin"]对data-roles="admin editor"无效——得用[data-roles*="admin"]或改用 JS 处理。
容易被忽略的边界情况和调试技巧
实际写的时候,几个细节一错就白忙:
- 属性值两端不能有引号以外的不可见字符(比如复制粘贴带的零宽空格),Chrome DevTools 的「Computed」面板里看
element.getAttribute("attr")返回值最准 -
[attr~=""]永远不匹配任何元素——空字符串不是合法 token - 若属性不存在,选择器直接不生效,不会报错也不会 fallback,容易误判为样式没加载
- 用
getComputedStyle(el).getPropertyValue()查不到~匹配结果,得靠el.matches('[attr~="value"]')实测
真要匹配data-类多值属性,别硬扛~,老老实实用data-roles*=" admin "加空格保底,或者干脆交给 JS 做el.dataset.roles.split(/\s+/).includes("admin")——CSS 的~不是万能分词器,它只忠于标准定义的那几个属性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











