自定义元素命名必须含短横线且全小写,如my-button;禁用mybutton、MyButton、my_button等写法,否则注册失败。

自定义元素命名必须带短横线,且不能只用纯字母
浏览器要求自定义元素名里至少含一个短横线(-),否则会直接拒绝注册。写成 mybutton 或 usercard 都会报错 CustomElementRegistry.define: "mybutton" is not a valid custom element name。
常见错误是把组件名当普通 class 用,比如 <my-button></my-button> 写成 <mybutton></mybutton>;或者用下划线 <my_button></my_button>,这在部分旧版 Safari 中不识别。
- 正确写法:
my-button、shop-product-card、data-table-row - 禁止写法:
mybutton、MyButton、my_button、123-card(不能数字开头) - 注意大小写:HTML 解析器默认转小写,
<my-button></my-button>实际等价于<my-button></my-button>,但 JS 里用customElements.define('My-Button', ...)会失败
class/id 命名不能和自定义元素名冲突
如果定义了 <user-profile></user-profile> 元素,就别再用 class="user-profile" 或 id="user-profile"。这不是语法错误,但会导致 CSS 选择器或 JS 查询歧义 —— 尤其当你用 document.querySelector('user-profile') 和 document.querySelector('.user-profile') 混用时,逻辑容易错乱。
更隐蔽的问题是:某些构建工具(如 Lit 的分析器)会扫描 class 名匹配组件名,触发误判或自动注入行为。
立即学习“前端免费学习笔记(深入)”;
- 推荐做法:组件名用 kebab-case,对应 class 前缀加项目标识,如
shop-user-profile、cms-article-header - 避免复用:哪怕只是视觉相似也不行,
article-card和<article-card></article-card>同时存在,后期改样式或加事件监听时极易漏掉某一处 - id 必须全局唯一:即使只用一次,也建议加前缀,如
id="shop-user-profile-123",防止 SSR 渲染多个实例时 ID 重复
HTMLHint 对自定义元素的校验要手动启用规则
默认配置下,htmlhint 不检查自定义元素合法性,也不会报 unknown-tag 错误。它把 <my-button></my-button> 当成普通标签放过,直到运行时才暴露问题。
必须在 .htmlhintrc 里显式开启 attr-unknown 和 tag-name-lowercase,并配合 custom-tags 白名单(如果用到非标准标签):
{
"rules": {
"tagname-lowercase": true,
"attr-unknown": true,
"attr-lowercase": true,
"attr-no-duplication": true,
"custom-tags": ["my-button", "shop-product-card"]
}
}
- 不加
custom-tags:HTMLHint 把所有自定义标签当错误标红,干扰真实问题定位 - 加了但没写全:漏掉的标签仍被当作未知标签报错,比如忘了加
data-table-row,结果 CI 流水线卡住 - 注意路径匹配:如果组件分散在不同目录,确保
"files": ["**/*.html", "!node_modules/**"]覆盖全部模板文件
嵌套结构里禁止用 <p> 包自定义块级元素
W3C 明确规定 <p> 的内容模型只能是“phrasing content”,而自定义元素默认是“flow content”。所以 <p><my-card></my-card></p> 在 W3C Validator 里会报 Element my-card not allowed as child of element p,即使渲染看起来正常。
这个问题在 SSR 场景尤其危险:服务端解析 HTML 时严格按规范处理,可能直接丢弃非法子节点,导致客户端 hydration 失败或 DOM 不一致。
- 替代方案:用
<div>或语义化容器如<section>、<article>替代<p> - 如果真需要段落语义,把自定义元素放
<p>外部,用<figure>+<figcaption>组合包裹图文卡片 - 检查方式:不只是看 DevTools 渲染结果,必须跑 W3C Validator 或用
htmlhint --rule "head-valid-content-model:true"扫描



















