html中不存在“self-closing标签”概念,只有void elements(如)禁止闭合,而normal elements(如、)必须显式闭合,混淆会导致dom错乱或功能失效。

HTML 中没有“self-closing 标签”这个语义概念——它是个被误用的术语,源自 XHTML 习惯迁移到 HTML5 的混淆。真正起作用的是 HTML 规范定义的 void elements(空元素),它们语法上禁止出现结束标签,写 <img> 或 <img> 都是错的,唯一合法形式是 <img>。
void elements 为什么不能写 /> 或
HTML5 规范明确列出 14 个 void elements: <area>、<base>、<br>、<col>、<embed></embed>、<hr>、<img>、<input>、<link>、<meta>、<param>、<source></source>、<track></track>、<wbr></wbr>。这些元素天生无内容、无子节点,解析器遇到 <img src="x"> 就直接创建一个 DOM 节点并继续;若你写成 <img src="x">,斜杠会被忽略(容错),但若在某些模板引擎或 linter 中启用 XML 模式,它可能截断属性或报错;若写成 <img>,浏览器会把它当成两个标签:<img> 和孤立的 (后者被丢弃),后续文本可能意外成为 <img> 的子节点。
-
<img src="a.jpg">✅ 合法且推荐 -
<img src="a.jpg">⚠️ 容错可用,但非标准,工具链可能出问题 -
<img src="a.jpg">❌ 解析异常,DOM 结构错乱
<script></script> 和 <style></style> 必须显式闭合,哪怕为空
这两个标签属于 normal elements,即使不写内容也必须有结束标签。写成 <script></script> 或 <style></style> 是无效的——JS 不执行,CSS 不生效。浏览器不会自动补全,也不会报错,只会静默跳过。
-
<script>console.log(1);</script>✅ -
<script></script>✅(空脚本合法) -
<script></script>❌ 后续 HTML 全部被当作 script 内容解析,直到遇到下一个 -
<style>color: red;</style>✅ -
<style></style>❌ CSS 规则丢失,且后续 HTML 可能被当作文本渲染
<textarea></textarea> 和 <select></select> 看似能自闭合,实则不能
它们有内容模型(text node 或 <option></option> 子节点),依赖开始与结束标签之间的文本范围。写成 <textarea></textarea> 或 <select></select> 会导致初始值、占位符、选项全部丢失,DOM 中变成空元素。
-
<textarea>default</textarea>✅ 文本内容可编辑 -
<textarea name="t"></textarea>✅ 显式闭合,内容为空 -
<textarea name="t"></textarea>❌ 浏览器解析为无内容的空标签,placeholder 不显示,value 始终为空字符串 -
<select><option>A</option></select>✅ 正常渲染下拉 -
<select></select>❌ 渲染为空白控件,无选项,无法交互
最容易被忽略的不是“要不要加斜杠”,而是把 void element 当作“可选自闭合”的自由风格来用。规范只认两类:void elements(禁止闭合)和 normal elements(必须闭合)。工具链(如 Vue SFC、eslint-plugin-html、prettier)越来越严格按 Living Standard 校验,写错不是“看起来一样”,而是真实影响构建、测试和可访问性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











