id必须全局唯一且符合规范:只能用小写字母开头加数字、连字符,禁用点号、冒号、下划线、驼峰、中文及特殊字符;服务端与客户端需一致,避免ssr hydration失败;优先用class或data-*替代id绑定js事件。

id必须全局唯一,重复会导致JS只取第一个
document.getElementById()遇到重复id时,永远只返回文档中第一个匹配元素;CSS的#my-id虽可能样式生效在多个元素上,但这是未定义行为,Chrome和Firefox渲染结果可能不一致。最典型的现象是:列表里多个delete-btn按钮,JS事件只绑在第一个上,其余点击无响应。
服务端模板或React/Vue组件循环中,绝不能写死id="item"——必须拼接唯一标识:id="item-{{id}}"(后端模板)或:id="`user-${userId}`"(Vue),确保每个实例id值不同。
- iframe内嵌页面也计入全局范围,主页和iframe里的id不能冲突
- SSR hydration阶段若服务端与客户端生成的id不一致,React会警告“Hydration failed”,Vue可能丢弃DOM节点
- 用
aria-labelledby或for关联时,目标id不存在或重复,会导致可访问性(a11y)工具读不出标签
命名只能用字母、数字、连字符,禁用点号和冒号
看似合法的id="user.email"或id="btn:submit"会在实际使用中崩掉:querySelector("#user.email")被解析成「id=user且class=email」;getElementById("user.email")能取到元素,但CSS无法匹配,for属性也失效。
安全写法只有小写字母开头 + 数字/连字符组合:id="search-input"、id="modal-confirmation"。纯数字开头如id="123"虽HTML5允许,但CSS里要写成#\31 23(转义),极易出错,直接避开。
- 下划线
_在旧版IE中有兼容问题,已少见但遗留系统仍可能踩坑 - 驼峰
userProfile易与JS变量混淆,且不符合CSS选择器习惯 - 中文、空格、斜杠、括号等字符一律禁止,哪怕HTML5语法允许,工程中就是埋雷
id不是class,别为JS绑定随便加id
给按钮写id="submit-btn"只为写document.getElementById("submit-btn").addEventListener(),属于反模式。它让CSS权重失控(#submit-btn比绝大多数class都高),且破坏组件复用性——同一组件多次渲染就撞id。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
现代做法是用语义化class或data-属性:class="js-submit"或data-action="submit",再用document.querySelector("[data-action='submit']")获取。id应留给真正需要唯一锚点的场景:
- 页面内跳转:
@#@#@#@#@#@#@#@#@#@0→<main id="main-content"></main> - 表单label关联:
<label for="email-field"></label>↔<input id="email-field" name="email-field"> - ARIA强绑定:
aria-labelledby="header-title"→<h1 id="header-title"></h1>
文件名、data-*、name属性也要统一kebab-case
很多人只注意class/id,却在其他地方破功:data-userid="123"在Alpine.js里无法被x-bind:data-userid识别;<input name="userEmail">提交到PHP后端,可能因服务器配置变成$_POST['useremail']或$_POST['userEmail'],导致取不到值。
全链路保持kebab-case是最省心的方案:data-shop-product-id、name="user-email"、for="user-email"、id="user-email"全部对齐。文件名同样:user-profile.html✅,user_profile.html❌(GitHub Pages可能404)。
真正容易被忽略的是:大小写敏感性。Windows本地开发时UserProfile.html能打开,部署到Linux服务器就404;Index.html不是首页,只有index.html才被Nginx/Apache/Vercel默认识别。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










