规则:名必须以 data- 开头,后面只能用小写字母、数字和连字符(不能有大写、不能有点);值总是字符串。
<div class="card" data-level="hot">…</div>
.card[data-level="hot"] { border-color: #cf222e; } /* 精确匹配 */
.card[data-level] { … } /* 只要存在这个属性 */
[data-level|="hot"] { … } /* hot 或以 hot- 开头 */
[data-level^="h"] { … } /* 前缀匹配,还有 $= *= ~= */
.card[data-level]::after { content: attr(data-level); } /* 直接把值显示出来 */
点按钮切换状态,样式全靠 data-state 而不是往 class 里塞 is-loading:
const b = document.getElementById('b')
b.dataset.state // 读:'idle'
b.dataset.clicks // 读:字符串 '0' —— 数字要自己 parseInt
b.dataset.state = 'ok' // 写:同步更新 HTML 属性,CSS 选择器立刻生效
// 连字符名 → 驼峰名
// data-max-width → el.dataset.maxWidth
// data-user-id → el.dataset.userId
// 反过来也成立:dataset 里写驼峰,属性里变成 kebab-case
// 遍历全部
for (const [k, v] of Object.entries(b.dataset)) console.log(k, v)
// 删除
delete b.dataset.clicks
把「跨几列」这种内容属性写在 data 上,CSS 用 [data-span="2"] { grid-column: span 2 } 响应;换主题或改布局时 JS 完全不用动。(CSS 侧的选择器写法见 CSS 教程第三章。)
data-color="red" 通常说明你其实想要一个语义类名。aria-expanded、aria-current、aria-hidden 会被读屏播报,data-* 不会。data-config='{"a":1}' 存 JSON 再 JSON.parse,比散成十几个属性好维护(注意单引号包 JSON)。