HTML5中绝对不能写结束标签的标签共14个:area、base、br、col、embed、hr、img、input、link、meta、param、source、track、wbr;它们是void elements,语法上禁止写/或结束标签,正确写法仅为<img src="a.jpg">等形式。

哪些标签绝对不能写结束标签
HTML5 明确规定了 14 个 void elements,它们语法上禁止出现 或 /,写了就是违反规范。浏览器会容错处理,但工具链(如 ESLint、Vue SFC 解析器、HTML 压缩器)可能直接报错或截断属性。
-
area、base、br、col、embed、hr、img、input、link、meta、param、source、track、wbr - 正确写法只有:
<img src="a.jpg">、<input type="text">、<meta charset="utf-8"> - 错误写法示例:
<img src="a.jpg" />(XHTML 风格,HTML5 中无必要)、<img src="a.jpg"></img>(非法,后续内容可能被吞进img节点)
哪些标签必须显式闭合
normal elements(如 div、p、section、article)必须成对出现,否则会导致 DOM 结构错乱——未闭合的标签会把后面所有内容“包裹”进去,直到遇到同级闭合标签或文档末尾。
-
<div>hello</div>✅;<div>hello❌(后续所有p、span都变成它的子节点) -
<script>console.log(1)</script>✅;<script />❌(JS 不执行) -
<style>body{color:red}</style>✅;<style />❌(CSS 不生效) -
<textarea>default</textarea>✅;<textarea />❌(.value永远为空,placeholder失效)
为什么 <textarea /> 和 <select /> 看似能用却不行
它们不是空容器,而是依赖开始与结束标签之间的文本或子节点来定义语义和行为。写成自闭合形式后,浏览器按 void element 规则解析,丢弃所有内部内容。
-
<textarea>初始值</textarea>→textarea.value === "初始值" -
<textarea />→textarea.value === "",且placeholder属性不触发渲染 -
<select><option value="a">A</option></select>→ 正常渲染下拉项 -
<select />→ 所有<option>被忽略或解析失败,DOM 中只剩一个空select节点
模板引擎和构建工具里最易踩的坑
浏览器宽容,但 Webpack、Vite 插件、Vue 单文件组件、Prettier、eslint-plugin-html 等工具往往按 XML 或严格 HTML 解析规则工作,/ 可能被当作结束信号,导致属性丢失、结构错位、甚至构建失败。
立即学习“前端免费学习笔记(深入)”;
- Vue SFC 中写
<img src="x" />,某些版本的@vue/compiler-sfc会把/>当作结束,后续属性被截断 - Prettier 默认格式化时若配置为
htmlWhitespaceSensitivity: "strict",可能把<input>改成<input />,引发 lint 报错 - 使用
html-minifier压缩时,<script />会被删掉全部内容,只留空标签 - VS Code 的 Emmet 默认输出
<img src="">是对的;如果插件输出<img src="" />,建议关掉或修改 Emmet 配置
/>,可能在 CI 流程里卡住整个构建。



















