[data-]选择器仅检测属性存在性,不校验值;=匹配全等,~=匹配空格分隔单词;多属性组合影响性能;data-与css自定义属性(--)不可混用;属性名自动小写化。

用 [data-*] 直接匹配自定义属性存在性
只要 HTML 元素写了 data- 开头的属性,不管有没有值、值是不是空字符串或非法字符,[data-id] 这类写法就能命中。比如 <div data-id>、<code><span data-role="admin"></span>、<button data-loading=""></button> 全部被 [data-loading] 选中——它只查 Element.hasAttribute('data-loading') 返回 true/false。
常见误操作是写成 [data-id=""] 去“找没赋值的”,结果漏掉 <div data-id> 这种省略等号的合法写法;真要区分“有属性但值为空”,得用 <code>[data-id=""],而“有属性且值非空”得靠 [data-id]:not([data-id=""])。
[data-role="admin"] 和 [data-role~="admin"] 的区别很关键
等号匹配(=)要求属性值**完全一致**,比如 data-role="admin" 只匹配字面值就是 "admin" 的元素;而波浪号匹配(~=")针对的是**空格分隔的多值属性**,类似 class 的行为。
-
[data-tags~="urgent"]能匹配data-tags="urgent high-priority",但不匹配data-tags="urgently"或data-tags="super-urgent" -
[data-tags="urgent"]只匹配data-tags="urgent",哪怕后面多一个空格都不行 - 如果自定义属性存的是 JSON 字符串(如
data-config='{"theme":"dark"}'),别用~="dark",它会按单词切分,可能意外命中"dark-mode"里的dark
组合多个自定义属性时注意特异性与性能
写 [data-section="user"][data-status="active"] 比单独用 .user-active 类更语义化,但要注意:浏览器必须对每个元素检查两个属性是否存在,DOM 越大、匹配越慢;尤其在滚动区域里频繁重排时,这类选择器可能比单类名慢 10%–20%。
实际建议:
- 优先用
[data-*]替代冗余 class,但别堆砌超过 3 个属性条件(如[a][b][c][d]) - 避免在动画帧里用
querySelectorAll('[data-*]'),改用document.querySelectorAll('[data-*]')缓存后复用 - 若需大小写不敏感匹配(如
data-name="John"和data-name="JOHN"都要中),加i标志:[data-name="john" i](Chrome 63+、Firefox 64+ 支持)
data- 属性不是万能的,别和 CSS 自定义属性(--*)混淆
data- 是 HTML 属性,用于存储页面数据,CSS 选择器能读取它;而 --color-primary 是 CSS 自定义属性,属于样式变量,**不能被选择器匹配**,只能用 var(--color-primary) 在声明块里引用。
容易踩的坑:
- 写
[--theme="dark"]是无效语法,CSS 解析器直接忽略整条规则 - 想根据主题切换样式?得靠 JS 动态加
data-theme="dark",再用[data-theme="dark"]写样式 -
data-属性值不会自动参与 CSS 计算,比如data-size="12"不能直接用在font-size: var(--size)里,得用 JS 提取后设置
最常被忽略的一点:HTML 中 data- 属性名会被浏览器自动转为小写,所以 data-MyId 和 data-myid 是同一个属性,CSS 里必须用小写形式书写选择器。











