id必须以字母开头,仅含小写字母、数字、连字符且全局唯一;id="123"导致css选择器非法,id="user.email"被queryselector误解析为class匹配,ssr hydration、aria关联、表单for绑定均会静默失败。

id 必须以字母开头,只能含小写字母、数字、连字符(-),全局唯一,且仅在真正需要锚点或 ARIA 关联等场景使用——其他情况一律用 class 或 data-*。
为什么 id="123" 或 id="user.email" 会出问题
浏览器解析时,id="123" 虽能被 getElementById("123") 取到,但 CSS 选择器 #123 是非法的,必须写成 #\31 23(转义形式),极易漏写或写错;id="user.email" 会让 querySelector("#user.email") 当作「id=user 且 class=email」来匹配,结果查不到元素。这两种写法在 SSR hydration、ARIA 关联、表单 for 绑定中都会静默失败。
常见错误现象:
-
document.getElementById("submit")返回null,但元素明明在 DOM 里 - 点击
<label for="email"></label>,光标没跳进对应输入框 - 页面内跳转
https://site.com/#section2不滚动,或滚动错位
id 命名必须满足的硬性条件
不是“建议”,是浏览器解析和 CSS/JS 工具链实际依赖的底线:
- 首字符必须是小写或大写 ASCII 字母(
a–z或A–Z),不能是数字、下划线、点、冒号 - 后续字符只允许小写字母、数字、连字符(
-)——这是三端(HTML/CSS/JS)都稳的唯一组合 - 禁止出现空格、中文、斜杠、括号、@、$、点号(
.)、冒号(:)、下划线(_) - 不能是 JS 保留字:
id="for"、id="class"、id="submit"在表单内可能覆盖原生方法
✅ 安全示例:search-input、modal-root、article-42、user-profile
❌ 危险示例:1st-section、user_name、btn:primary、nav-toggle(若项目约定全小写,NavToggle 就违规)
什么时候该用 id?什么时候坚决不用?
用 id 的场景极少,且必须满足「唯一 + 不可复用」两个特征:
- 页面内锚点跳转:
<h2 id="faq-section"></h2>+<a href="#faq-section"></a> - 表单控件与标签绑定:
<input id="email-field">+<label for="email-field"></label> - ARIA 引用目标:
aria-labelledby="title-desc"要求存在对应id="title-desc" - Canvas / SVG 等需 JS 精确单点控制的根容器:
<canvas id="game-canvas"></canvas>
坚决不用 id 的场景:
- 为 JS 绑定事件而加:
id="save-btn"→ 改用data-action="save"或语义化class="js-save" - 循环渲染列表项:
id="item"写死在模板里 → 必须动态拼接:id="item-{{id}}" - 组件多次实例化:
Vue子组件里写id="modal"→ 会冲突,应通过 prop 注入前缀 - 纯样式控制:
id="red-header"→ 违反语义原则,改用class="header--error"
最常被忽略的一点:服务端和客户端生成的 id 值必须完全一致。SSR hydration 阶段若 id="user-123" 在服务端是静态生成,客户端却因状态不同算出 id="user-456",React 会警告 “Hydration failed”,Vue 可能直接丢弃整个节点——这种 bug 很难定位,因为 DOM 看似正常,只是交互失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











