HTML5中14个void元素(area、base、br、col、embed、hr、img、input、link、meta、param、source、track、wbr)必须不写结束标签或斜杠,如<img src="a.jpg">;而<textarea>、<script>、<select>等非void元素必须显式闭合,否则DOM结构错乱、内容丢失或脚本不执行。

HTML 标签不是“写得差不多就行”,闭合方式错了一处,DOM 结构就可能歪掉——尤其是 <textarea>、<script>、<select> 这类看着像空标签、实则必须显式闭合的元素。
哪些标签根本不能写 </xxx> 或 />
HTML5 明确定义了 14 个 void elements(空元素),语法上禁止出现结束标签或自闭合斜杠。写了就是违反规范,哪怕浏览器容错,工具链也可能出事:
-
<img src="a.jpg">正确;<img src="a.jpg" />是 XHTML 遗留写法,在纯 HTML5 中无必要,且某些模板引擎(如旧版 Vue SFC)会把它当 XML 解析,导致属性截断 -
<input type="text">正确;<input type="text" />或<input type="text"></input>都非法,后者会让后续内容被误包进<input>节点里 - 同理,
<meta>、<link>、<hr>、<br>、<source>等都只允许写成单标签形式,不带斜杠也不带结束标签
哪些标签看着空,但必须写 </xxx>
<textarea>、<select>、<script>、<style>、<p>、<div> 这些都不是 void elements,它们的内容(文本、子节点、JS/CSS 代码)语义关键,靠开始与结束标签界定边界:
-
<textarea>默认值</textarea>→ DOM 的.value初始为"默认值";写成<textarea />→.value永远是空字符串,placeholder也不生效 -
<select><option value="a">A</option></select>才能渲染选项;<select />会让所有<option>被丢弃或解析失败 -
<script>console.log(1)</script>可执行;<script />会导致 JS 完全不加载
为什么 <img src="x"> 不报错,但还是得改
浏览器解析器对错误宽容,<img src="x" /> 会被当作 <img src="x"> 处理,斜杠被忽略——这不是“支持”,是容错。真正风险在开发流程中:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- ESLint +
eslint-plugin-html可能报void-element-with-closing-tag错误 - 某些静态站点生成器(如早期 Hugo 模板)把
/>当 XML 结束信号,导致 HTML 片段错位 - VS Code 的 Emmet 默认展开为
<img src="">,如果插件配置成输出/>,建议关掉或重配
DOCTYPE 和根结构不闭合,后果比单个标签更严重
<!DOCTYPE html> 必须是文档第一行;<html> 必须包裹整个文档,且必须有对应 </html>;<head> 和 <body> 同样不可省略闭合标签:
- 漏掉
</body>或</html>,浏览器会自动补全,但补全逻辑不可控——比如<script>可能被塞进<head>末尾,而你本意是在<body>底部执行 -
<head>里的<meta charset="utf-8">必须写成完整单标签,不能写<meta charset="utf-8" />(虽容错,但不符合 HTML5 void element 规范) - 所有标签统一用小写,这是 W3C 自 HTML4 起的强制推荐,现代工具链(如 Prettier)默认按此格式化
最常被忽略的不是“要不要闭合”,而是“为什么这个标签非得闭合”——<textarea> 里那行默认文本、<script> 里那句 console.log,都依赖标签边界存在。写错一次,调试时可能绕半天才意识到是 DOM 结构本身歪了。


















