id必须全局唯一,否则会导致getelementbyid返回首个匹配元素、label无法关联多个input、ssr hydration静默失败;class命名应语义化而非样式化,推荐kebab-case和bem结构,避免拼音缩写与样式词混用。

id 必须全局唯一,且只用于锚点或 JS 精确控制
重复的 id 不会触发浏览器报错,但后果很实在:document.getElementById("submit-btn") 永远只返回第一个匹配元素;<label for="email"></label> 无法正确关联到第二个 <input id="email">;SSR 渲染时 React/Vue 的 hydration 会静默失败。
这些场景才真正需要 id:
- 页面内锚点跳转:
<h2 id="faq-section">常见问题</h2>+@#@#@#@#@#@#@#@#@#@0 - 表单控件绑定:
<input id="user-email">与<label for="user-email"></label>配对 - ARIA 引用目标:
aria-labelledby="title-desc"要求存在<span id="title-desc"></span> - JS 高频单点操作:
<div id="modal-root">、<code><canvas id="game-canvas"></canvas>别把
id当成“带样式的 class”——id="btn-primary"或id="sidebar"在多实例组件里必然出问题。class 名必须语义化,禁用样式描述
class="red-text"看起来省事,但换主题后它既不是红色、也不再是文本重点,而你得在 CSS 和 JS 里到处搜替换。真正该写的是它「是什么」,而不是「长什么样」。✅ 推荐写法(功能/内容导向):
-
class="error-message"(而不是red-bold-text) -
class="search-input"(而不是rounded-blue-input) -
class="user-avatar"(而不是circle-img)
❌ 避免写法:
- 含样式词:
float-left、big-title、hidden-xs(除非是统一前缀的工具类,如u-hidden) - 含标签名:
div-header、p-content(限制了后续换成<section></section>或<header></header>的自由度) - 拼音或无意义缩写:
zhuye、box1、wrap
kebab-case 是唯一安全分隔符,BEM 仅在必要时展开
驼峰(
userAvatar)易和 JS 变量混淆;下划线(user_avatar)在旧版 IE 和部分 SSR 工具链中仍有兼容隐患。连字符是 HTML/CSS/JS 三端都稳的唯一选择。基础命名一律用
kebab-case:-
class="nav-main"、id="footer-copyright" -
class="product-card"、class="form-field"
BEM 不是强制模板,而是结构意识工具:
- 简单组件:直接
class="card"就够 - 有嵌套或状态时再加层级:
class="card__header"、class="card--loading" - 避免过度嵌套:
card__header__title--highlighted违反 BEM 原则,应为card__title--highlighted
特殊字符要小心:
id="user.email"在 JS 中必须写成getElementById("user\.email"),否则会被解析为 CSS 选择器。工具类需隔离前缀,data-* 属性也要带项目标识
纯行为类(隐藏、居中、截断)不能和业务语义混在一起,否则维护时分不清哪些能删、哪些动了会影响逻辑。
统一用
u-前缀声明工具类:-
class="u-hidden"、class="u-text-center"、class="u-truncate" - 禁止混用:
hide、is-hidden、hidden-sm—— 它们语义模糊且不可预测
data-属性同样要收敛:- 推荐:
data-app-id、data-product-sku - 避免:
data-id(太泛)、data-value(和原生属性冲突风险)
所有命名最终服务于一件事:让别人(包括三个月后的你自己)不用猜就能知道这个
id或class是干什么的,以及改它会不会牵一发而动全身。 -











