浏览器依据html规范中的void element列表判断自闭合标签,共14个:area、base、br、col、embed、hr、img、input、link、meta、param、source、track、wbr;不在列表中的标签如div即使写成也会被解析为未闭合的开始标签。

怎么判断一个标签是不是自闭合标签
浏览器不靠“看有没有斜杠”来识别自闭合标签,而是查规范里定义的 void element 列表。HTML Living Standard 明确列出了 14 个(截至 2026 年): area、base、br、col、embed、hr、img、input、link、meta、param、source、track、wbr。只要标签名在这个列表里,它就是自闭合的——无论你写 <img>、<img> 还是 <img>,解析器都按空元素处理。
为什么 <div></div> 不是自闭合,但也不报错
因为 div 不在 void element 列表中,属于 normal element。HTML 解析器遇到 <div></div> 时,会把 / 当作非法字符直接丢弃,整段等价于 <div> —— 一个没闭合的开始标签。后续所有内容都会被塞进这个 <code>div 的子树里,直到遇到
或触发隐式闭合(比如下一个块级兄弟节点)。这不是容错,是确定性纠错。
-
<img src="x"> 合法:/ 被保留,语义不变
-
<div class="a"></div> 非法:/ 被丢弃,变成未闭合的 <div class="a">
<li>React/Vue 中用 <code>v-html 或 dangerouslySetInnerHTML 渲染这类字符串,同样走这套规则,框架不拦截
服务端解析器(如 Jsoup、jsdom)对自闭合更敏感
它们默认不模拟浏览器的容错逻辑,而是严格按规范解析。遇到 <div></div> 会直接抛 ParseException,或生成结构异常的 DOM 树。这不是 bug,是设计使然:早暴露问题,避免上线后因浏览器差异导致渲染不一致。
- jsdom 默认启用
strict 模式,<p>hello</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5117" title="HTML Extract"><img
src="https://img.php.cn/upload/skill/000/000/081/179033952939354.jpg" alt="HTML Extract" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5117" title="HTML Extract" class="overflowclass">HTML Extract</a>
<p class="overflowclass">使用 MinerU 从 HTML 页面和文件中提取内容,将 HTML 转换为保持标题、列表、表格及文本层次结构的干净、结构化 Markdown。F...</p>
</div>
<a rel="nofollow" href="/xiazai/skill5117" title="HTML Extract" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<div></div> 会立刻报错
- Jsoup 若不显式设置
Parser.xmlParser(),对 <input> 可能误判为未闭合
- 校验建议:开发阶段用
htmlhint + tidy-html5 自动格式化,比靠浏览器“猜”更可靠
常见误判场景和调试线索
DOM 结构跟写的不一样?别急着改 CSS 或 JS,先看 Elements 面板里有没有灰色斜体节点、Edit as HTML 后结构跳变、document.querySelectorAll('div') 返回数量远超预期——这些全是浏览器已执行纠错的痕迹。W3C Validator 是唯一能准确定位源头的工具,它报的 Element div not allowed as child of element p 必须直改源码,补救无效。
<p></p>
<div> → 浏览器强制隐式闭合 <code>p,再开 div,DOM 变成 <p></p><div></div>
@@##@@ → 控制台警告“end tag ignored”,但图片仍显示;严格校验工具会标红
- 粘贴外部 HTML 片段时带了冗余闭合(如
),编辑器自动补全可能雪上加霜
真正难的不是记住哪些标签能自闭合,而是理解:浏览器从不“修复 HTML”,它只按算法重排 DOM。你写的源码,只是输入;最终结构,由插入模式和开放元素栈决定。