真正稳定、跨元素可用的核心全局属性只有这几个:id、class、data-*、title、lang、dir、style、tabindex(注意:布尔值需显式设为tabindex="0"才可聚焦)。

能直接用在任意 HTML 元素上的属性,其实没几个真正“稳”。别被 MDN 列的 27 个吓住——很多要么有语义限制,要么浏览器支持不一,要么只对特定上下文生效。
哪些全局属性真能无脑用在任何标签上
真正跨元素、跨浏览器、跨场景稳定可用的,就这几个:id、class、data-*、title、lang、dir、style、tabindex(注意必须显式写 tabindex="0" 才可聚焦)。其他像 contenteditable、draggable、hidden 表面通用,实则受限:
-
contenteditable加了也不可编辑?大概率缺tabindex="0",或者子元素有user-select: none -
draggable默认是auto,不是true;<p>默认不可拖,得写draggable="true" -
hidden在<meta>或<script>上无效,浏览器直接忽略,不报错也不渲染
data-* 属性读写时最常踩的命名坑
HTML 里写 data-user-id="123",JS 里必须用 dataset.userId 访问——连字符自动转驼峰、首字母小写。大小写错一点就拿不到值:
-
dataset.userid→ undefined -
dataset.Userid→ undefined -
dataset["user-id"]→ ✅ 可用,但绕过驼峰转换
更隐蔽的是命名非法:比如 data-1st-place,JS 无法写成 dataset.1stPlace(变量名不能数字开头),只能用 dataset["1st-place"];data-user:name 中的冒号会被浏览器静默丢弃,值根本存不进去。
立即学习“前端免费学习笔记(深入)”;
id 和 class 在 DOM 查找性能上差一个数量级
document.getElementById("x") 是 O(1) 哈希查找,快得几乎感知不到;而 document.querySelector(".x") 或 document.getElementsByClassName("x") 要走 CSS 选择器引擎,遍历匹配节点——尤其在深层嵌套或上千节点的页面里,延迟明显。
- 同一个页面里
id重复?getElementById只返回第一个,HTML 验证器会警告,但 JS 不报错 -
class支持多值,但空格敏感:class="btn primary"和class="btn primary"(两个空格)会被解析为三个类名:["btn", "", "primary"],导致classList.contains("primary")返回false - 改类名优先用
classList.add()/classList.toggle(),别直接拼字符串:el.className += " active"容易引入多余空格或重复
tabindex 不是“让它能 tab 进去”的开关
它的数值直接影响焦点流语义和屏幕阅读器顺序,不是简单排序工具:
-
tabindex="-1":只能靠 JSel.focus()聚焦,不进自然 tab 流——适合弹窗打开后手动聚焦 -
tabindex="0":按 DOM 顺序加入 tab 流,95% 场景该用这个 -
tabindex="5"及正数:强制前置顺序,但会打乱屏幕阅读器逻辑,WCAG 明确不推荐
对 contenteditable 元素,tabindex 缺失 = 键盘不可达 = 直接违反 WCAG 2.1 2.1.1。哪怕只是加个 tabindex="0",也得同步考虑 spellcheck="false"(避免拼写下划线干扰 UI)和子元素样式是否阻断光标定位。



















