真正影响运行时行为的全局属性极少,id须唯一、class需引号空格分隔,data-*属性通过dataset读写且命名受限,contenteditable需配tabindex="0",hidden和tabindex为布尔属性,值无效。

真正影响运行时行为的全局属性就那么几个,其余多数是“语法合法但无实际效果”——加了白加,还可能埋下可访问性或 JS 选择失败的坑。
id 和 class:JS 选不到、CSS 不生效,往往就因为这两个
它们不是“装饰”,而是运行时逻辑的锚点。id 必须唯一,class 值必须用引号包裹且空格分隔。
-
id重复会导致document.getElementById()只返回第一个,后续 JS 逻辑全错;CSS 选择器仍会命中全部,造成样式覆盖混乱 -
class="btn" primary实际只解析出btn,primary被当作文本节点丢弃——必须写成class="btn primary" - 动态拼接 class 时用
classList.add("active"),别用el.className += " active",否则重复添加导致冗余字符串 - 服务端模板中未转义
class值(如class="{{ user.role }}"),若user.role是"admin script",可能触发 XSS
data-* 属性:连字符自动转驼峰,数字开头直接被忽略
它只在 JS 中通过 dataset 读写才有效,HTML 和 CSS 完全不解析。浏览器有隐式转换规则,不按规则写就取不到值。
-
data-user-id="123"→ JS 中是element.dataset.userId,不是element.dataset.user-id(语法错误) -
data-1st-place="gold"在dataset中不可见——数字开头的 key 全部被忽略 - IE11 支持
dataset,但data-MyKey会转成mykey,不是myKey(大小写敏感降级) - 别存大对象:
data-config只存字符串,想塞 JSON 就得自己JSON.stringify()+JSON.parse()
contenteditable + tabindex:不是加个 true 就能编辑
这是唯一能让任意元素变编辑区的全局属性,但开错位置、漏掉 tabindex、忽略默认样式干扰,都会导致光标进不去、键盘失焦或可访问性失败。
-
contenteditable="true"后必须加tabindex="0",否则无法键盘聚焦 —— WCAG 2.1 2.1.1 直接不达标 -
contenteditable="plaintext-only"是无效值,所有浏览器都不支持;合法值只有"true"、"false"、空字符串 - 子元素带
user-select: none或pointer-events: none会阻断光标定位,编辑区看起来“点了没反应” - 建议补上
spellcheck="false",避免拼写红线干扰 UI,比如:<div contenteditable="true" tabindex="0" spellcheck="false"> <h3>hidden 和 tabindex:布尔属性的值根本不管用</h3> <p>它们是布尔属性,存在即生效,值无效。写成 <code>hidden="false"或tabindex="-1"看似“关掉”,其实行为完全相反。-
hidden="false"依然隐藏 —— 只要属性存在,就等价于display: none -
contenteditable="off"或contenteditable="0"都无效,只能用"true"/"false"字符串 -
tabindex="-1"表示“可编程聚焦但不参与 Tab 流”,tabindex="0"才是“按 DOM 顺序加入 Tab 流” -
tabindex="5"这类正数会破坏屏幕阅读器阅读流,仅限极特殊场景,日常禁用
最容易被忽略的是:全局属性不是“加了就有用”,而是有明确行为边界的控制开关。一个
id重复、一个data-命名违规、一个tabindex缺失,都可能让 JS 选不到、CSS 不生效、无障碍直接失效。 -











