真正稳定跨元素可用的核心全局属性只有id、class、data-*、title、lang、dir、style、tabindex(需显式设为"0"才参与焦点流);其余如contenteditable在上无效,hidden在中被忽略。

真正影响运行时行为的全局属性就那么几个,其余多数只是语法合法但无实际效果——加了也不起作用,还可能埋下可访问性或调试隐患。
哪些全局属性真正在所有元素上生效
不是所有标着“全局”的属性都真正通用。比如 contenteditable 在 <script></script> 上完全无效,hidden 放在 里浏览器会静默忽略(不报错,也不隐藏)。
真正稳定、跨元素可用的核心全局属性只有:id、class、data-*、title、lang、dir、style、tabindex(注意:必须显式写成 tabindex="0" 才参与焦点流)。
-
aria-*系列虽常被归为全局,但必须配合语义角色(如role="button")才有效;单独加aria-label到<div> 上,屏幕阅读器大概率跳过 <li> <code>draggable默认是"auto",不是true;图片和链接默认可拖,<p></p>默认不可拖,得显式写draggable="true" -
exportparts只对含 Shadow DOM 的自定义元素有意义,普通页面基本用不到 - 值为空字符串时,
dataset仍会返回该键;但若属性根本不存在,访问结果为undefined - 不要用
data-*存大量结构化数据(如 JSON 字符串),应改用JSON.parse(el.getAttribute('data-config'))显式解析 - 数字开头的 key 会被忽略:
data-1st-place="gold"在 dataset 中不可见;IE11 不支持带大写字母的转换(data-MyKey→mykey,而非myKey) - 只写
contenteditable="true"→ 元素不可键盘聚焦,WCAG 2.1 2.1.1 失败 - 加了
tabindex="0"后,才真正进入 tab 流,支持el.focus()编程聚焦 - 误设
tabindex="1"或更高正数 → 会打断自然阅读顺序,对屏幕阅读器用户不友好 -
title:鼠标悬停显示提示,但不保证一定出现——移动端 Safari 完全不支持,部分屏幕阅读器默认忽略;内容超过约 120 字符会被截断,且不支持换行、图标、富文本;若元素设置了pointer-events: none,title完全失效 -
lang:写错值(如lang="ja"但内容是中文)会让屏幕阅读器读成日语;未设置则拼写检查、语音合成、搜索引擎语义识别全部降级 -
hidden是布尔属性,写成hidden="false"依然隐藏——只要存在就生效,值无关;它等效于display: none,但不移除 DOM,也不触发重排重绘
data-* 属性命名和 JS 读取的典型翻车点
命名必须全小写,且只含字母、数字、连字符(-);data-userID 或 data-user_id 都无效。
HTML 中写 data-product-id="1001",JS 中必须用 el.dataset.productId(自动转驼峰),不能写 el.dataset["product-id"] —— 后者语法合法但永远返回 undefined。
contenteditable + tabindex 是硬绑定关系
contenteditable 看似开个开关就行,但实际项目里 80% 的失效都源于没配对 tabindex:
推荐写法:<div contenteditable="true" tabindex="0" spellcheck="false">文本区</div>,其中 spellcheck="false" 可避免拼写下划线干扰 UI。
hidden、title、lang 这类“隐形属性”的真实作用边界
它们不改样式、不触发行内逻辑,但缺失会导致具体问题:
最常被忽略的是语义与行为的隐式耦合:比如 contenteditable 必须配 tabindex,data-* 命名大小写错一点就取不到值,lang 错一位就让辅助技术彻底失焦——这些都不是“看起来没问题”,而是运行时直接失效。











