
HTML全局属性不是“能加就加”的装饰项,而是有明确行为边界的控制开关——加错一个,document.getElementById选不到、dataset读不出、屏幕阅读器直接跳过,甚至让隐藏逻辑失效。
哪些全局属性真正影响运行时行为
别被“所有标签都能加”误导。真正起作用的只有少数几个,其余多数只是语法合法但无实际效果:
-
id和class:JS 用getElementById或querySelector依赖它们;CSS 选择器必须匹配才生效 -
data-*:只在 JS 中通过dataset读写有意义,HTML 和 CSS 不解析它 -
tabindex:值为0或正整数才参与 Tab 焦点流;负值仅禁用焦点,不改变顺序 -
hidden和contenteditable是布尔属性,存在即生效,值无关——hidden="false"依然隐藏,contenteditable="0"等同于true
class 和 id 的常见误用场景
这两个看似最简单,恰恰是动态渲染和调试中最容易翻车的地方:
- 多个元素用了相同
id:getElementById只返回第一个,后续逻辑全错;CSS 选择器仍会命中全部,造成样式覆盖混乱 -
class值含空格却没引号:<div class="btn" primary></div>实际只生效btn,primary被当作文本节点丢弃 - 动态拼接
class时没做去重:el.className += " active"多次执行导致active active active,CSS 仍生效但classList.contains("active")会出错 - 服务端模板中未转义
class名:class="{{ user.role }}"若user.role是"admin script",会意外引入非法class并可能触发 XSS
data-* 属性的读写边界与兼容性
data- 看似自由,但浏览器对它的处理有隐式规则:
立即学习“前端免费学习笔记(深入)”;
- 连字符自动转驼峰:
data-user-id="123"→ JS 中通过dataset.userId访问,不是dataset.user-id(语法错误) - 数字开头的 key 会被忽略:
data-1st-place="gold"在dataset中不可见 - IE11 支持
dataset,但不支持带大写字母的转换(data-MyKey→mykey,而非myKey) - 不要存大对象或函数:它只序列化为字符串,
JSON.stringify后再塞进去,取出来得自己JSON.parse - Vue/React 等框架中,
data-不会自动响应式更新,改了 DOM 属性,组件状态不会同步
hidden 属性与 display: none 的行为区别
hidden 是布尔属性,写成 hidden 或 hidden="" 效果一样,等价于 display: none;但 hidden="until-found" 是个特例,它等价于 content-visibility: hidden,元素仍参与布局,只是内容不可见。
关键差异在于:如果一个元素同时有 hidden 和 tabindex="0",它仍然可聚焦——这在无障碍测试中常被忽略,导致键盘用户卡在不可见元素上。



















