真正影响运行时行为的全局属性仅有少数几个:id和class决定JS选择与CSS匹配;data-*仅在JS中通过dataset读写有效;tabindex需为0或正整数才参与焦点流;hidden和contenteditable为布尔属性,存在即生效,值无效。

id 和 class 决定 JS 能不能选中、CSS 能不能生效;其余多数全局属性,不配合 JS 或 CSS 就等于没写。
哪些全局属性真正在运行时起作用
浏览器解析 HTML 时,并不会因为加了某个全局属性就自动改变行为——必须被 JS 读取、被 CSS 匹配、或被辅助技术识别,它才算“活”了。
-
id:只允许唯一,document.getElementById("xxx")只返回第一个匹配元素;多个同名id会让 JS 逻辑出错,但 CSS 仍会批量命中(造成样式误覆盖) -
class:值必须用引号包裹,<div class="btn" primary></div>实际只解析出btn,primary变成文本节点丢弃 -
data-*:连字符自动转驼峰,data-user-id="123"→ JS 中用element.dataset.userId访问,不是user-id(语法错误);IE11 不支持大写字母转换(data-MyKey→mykey,非myKey) -
tabindex:只有0或正整数才进 Tab 焦点流;tabindex="-1"仅允许 JS 主动.focus(),不参与键盘导航 -
hidden和contenteditable是布尔属性:存在即生效,hidden="false"或contenteditable="0"都无效,必须是"true"或"false"字符串
data-* 怎么安全传数据又不踩坑
它不是“随便塞字符串”的保险箱,而是有明确边界的数据通道。
- 命名必须全小写 + 连字符,
data-api-url合法,data-apiUrl或data-API-URL在 dataset 中不可见 - 数字开头的 key 被忽略:
data-1st-place="gold"→dataset里查不到1stPlace - 别存对象或函数:它只序列化为字符串,想存复杂结构得手动
JSON.stringify()和JSON.parse() - 框架里不响应式:Vue/React 修改
dataset不触发视图更新,状态得走组件内部 data / state
无障碍和语义化里最容易被忽略的三个点
这些属性不改样式、不报错,但一缺就让屏幕阅读器卡住、SEO 掉权重、键盘用户无法操作。
立即学习“前端免费学习笔记(深入)”;
-
title:鼠标悬停提示不保证显示(尤其移动端),但它仍是无障碍工具链里重要的补充说明来源 -
lang:没设lang="zh-CN",TTS 朗读可能用英文音调读中文,影响理解 -
aria-*属性(如aria-label):不是可选项,是当原生语义缺失时的强制补救手段;比如自定义按钮没用<button></button>,就必须加aria-role="button" aria-pressed="false"
真正难的不是记住 33 个全局属性的名字,而是判断哪个该用、哪个多余、哪个用了反而坏事——比如 draggable="true" 加在文字上,用户双击选词会直接触发拖拽,体验崩掉。这类细节,只看文档列不出来,得在真实交互里踩过才记得住。



















