data-*属性是唯一合法的html自定义属性,必须以data-开头、全小写加短横线命名(如data-user-id),浏览器通过dataset自动转驼峰,值恒为字符串,css选择器匹配时须加引号。

data-* 属性是唯一被允许的自定义属性
HTML 标准只认可 data-* 开头的属性作为合法自定义属性。其他如 my-id、status、is-active 都属于非标准写法,会导致 HTML 验证失败,且在部分严格模式解析器(比如某些 SSR 框架或 Linter 规则)中触发警告甚至报错。
团队协作中,统一用 data- 是底线。它不干扰语义,浏览器忽略但可被 JS 安全读取:element.dataset.userId 会自动转为驼峰(user-id → userId),而 getAttribute('data-user-id') 则保持原样。
- 命名全部小写,用短横线分隔(
data-api-endpoint,不是dataApiEndpoint) - 避免嵌套过深,如
data-form-step-validation-error-message建议拆成更聚焦的职责(data-validation-error+data-step="2") - 值尽量用字符串或布尔标志,别塞 JSON 字符串——那是
JSON.parse()的活,不是 HTML 属性的职责
role 和 aria-* 必须成对验证,不能“写了就安心”
role 和 aria-* 属性不是装饰品,它们直接参与无障碍树构建。常见错误是加了 role="button" 却没配 tabindex="0" 和键盘事件监听,导致屏幕阅读器认为它是可交互元素,但实际无法聚焦或响应空格/回车。
团队规范里应强制要求:只要出现 role,就必须检查对应 ARIA 实践是否完整。例如:
-
role="dialog"→ 必须有aria-modal="true"(或"false"),且焦点必须限制在模态框内 -
role="tablist"→ 子项需为role="tab"+role="tabpanel",并用aria-controls/aria-labelledby显式关联 -
aria-hidden="true"不要滥用在视觉可见但暂时隐藏的区域(如折叠菜单),它会让整个子树从无障碍树中消失
class 和 id 的命名需与组件边界对齐
class 和 id 虽然不属“全局属性”范畴,但它们是 CSS 和 JS 最常依赖的钩子,在协作中实际影响远超语义属性。问题常出在命名脱离组件上下文,比如在 <card></card> 组件里写 class="title",结果和 <header></header> 或 <modal></modal> 的 title 冲突。
推荐策略是采用 BEM 变体或作用域前缀:
- 组件级 class 统一加前缀:
card-title、card-actions、card__image - 避免纯功能类名(如
hidden、flex),除非团队明确约定为原子类且受 CSS-in-JS 或 Tailwind 管控 -
id必须全局唯一,慎用于 JS 查询;优先用data-+querySelector替代document.getElementById,降低冲突风险
lang、dir、translate 这三个冷门属性容易被忽略但影响真实场景
lang 不只是 SEO 配置项。浏览器拼写检查、语音朗读引擎、甚至某些字体回退逻辑都依赖它。中文页面写 lang="zh" 比 lang="en" 更准确;若含英文段落,应局部覆盖:<span lang="en">React</span>。
dir 控制文本方向,阿拉伯语、希伯来语等 RTL 场景下,仅靠 CSS direction 不足以让浏览器正确处理数字、括号、光标行为,必须用 HTML 层级的 dir="rtl"。
translate 是个隐形开关:设为 "no" 时,Google 翻译等工具会跳过该元素。适合人名、品牌词、代码片段——但别误设在整页 上,否则所有内容都无法被翻译。
这些属性不出错时不显眼,一旦出问题(比如多语言用户听到错误发音、RTL 页面日期显示颠倒),排查成本远高于初期加一行属性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











