真正稳定跨元素可用的核心全局属性只有id、class、data-、title、lang、dir、style、tabindex(需显式设为tabindex="0");aria-需配合role才生效,draggable默认为"auto",exportparts仅适用于Shadow DOM。

HTML全局属性不是“所有标签都能用就等于都有效”,很多属性加在不合适的元素上会被浏览器静默忽略,甚至引发意料外的行为。
哪些全局属性真正在所有元素上稳定生效
真正跨元素、跨场景、无副作用的只有这几个:id、class、data-*、title、lang、dir、style、tabindex(注意必须写成tabindex="0"才可聚焦)。其他如contenteditable对<script>无效,hidden在<meta>或<head>里不触发渲染变化,draggable默认是auto而非true——<p>加了draggable也不会变可拖拽,得显式写draggable="true"。
常见误用包括:
- 给
<img>加contenteditable,以为能编辑 alt 文本,实际无效 - 在
<input>上写tabindex但漏掉值,tabindex本身是布尔属性,没值等同于tabindex="-1",会移出焦点流 - 用
data-user-id="123",却在 JS 里写dataset.userid或dataset.UserId,正确是dataset.userId(连字符转驼峰,首字母小写)
data-* 属性读写时的命名和类型陷阱
data-*看着简单,但 JS 访问时命名规则和类型处理极易出错:
立即学习“前端免费学习笔记(深入)”;
- HTML 中写
data-api-key="abc123"→ JS 里是dataset.apiKey,不是dataset.api-key或dataset.APIKey - 属性名含数字开头,如
data-1st-place="gold"→dataset.1stPlace非法,必须用dataset["1st-place"] - 值永远是字符串:
data-count="0"取出来是"0",需要Number(el.dataset.count)或parseInt()转换 - data-后只允许 ASCII 字母、数字、连字符
-、点.、下划线_;data-user:name会被浏览器直接忽略,不报错也不存
hidden 与 display: none 的行为差异
hidden不只是“换个写法的display: none”:
-
hidden(或hidden="")等价于display: none:不占布局、不渲染、不响应事件 -
hidden="until-found"是新行为(2026年已广泛支持),等价于content-visibility: hidden:仍参与布局计算,但内容被隐藏,直到首次被查找(如querySelector命中)才激活渲染 -
hidden是布尔属性,写成hidden="false"仍然生效(只要属性存在就隐藏),要取消得彻底移除该属性 - 对
<script>、<link>等非渲染元素加hidden,浏览器会忽略,但不会警告
id 和 class 在 DOM 查询中的性能与语义区别
选哪个做 JS 操作锚点,不能只看“能不能用”,要看场景:
-
document.getElementById("x")是 O(1) 哈希查找,快且稳定;document.querySelector("#x")走 CSS 引擎,稍慢,尤其在节点数超万时有可测延迟 -
class支持多值但空格敏感:class="btn primary"和class="btn primary"(两个空格)解析出的类数组是["btn", "", "primary"],导致el.classList.contains("primary")返回false - 重复
id不报错,但getElementById只返回第一个匹配项;验证器会警告,但 JS 不感知 - 用
classList比拼接className安全:el.classList.add("active")不会覆盖已有类,而el.className += " active"容易引入多余空格或重复
最常被忽略的一点:全局属性的价值不在“能加”,而在“加在哪、为什么加、加了之后 JS/CSS/辅助技术怎么响应”。比如lang不只影响 SEO,还决定屏幕阅读器的发音语种;dir不只控制文字方向,还影响text-align的默认行为。这些细节一旦漏掉,修复成本远高于初始设计。



















