文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
浏览器会静默修复非法嵌套(如p内含h2、ul等),导致dom结构改变而非css失效;需通过elements面板验证真实dom、用queryselectorall检查修复后节点、筛选孤立元素定位问题。

标签里塞
、这类块级元素,浏览器不会报错,但会立刻中断当前、把非法内容提到外面,再补空
收尾——你看到的“布局错乱”,其实是DOM结构被静默重排后的结果,不是CSS没生效,是选择器根本找不到目标节点。
怎么确认是不是
嵌套惹的祸
别信源码缩进,信 Elements 面板里的真实 DOM:
- 打开 Chrome DevTools → Elements 标签页,找一个疑似有问题的
,右键 → “Edit as HTML”,删个字符再回车:如果子元素突然“跳出去”或缩进变平,说明原始嵌套不合法
- 在控制台运行:
document.querySelectorAll('p > *').forEach(el => console.log(el.tagName)),如果输出里有DIV、H2、UL,那说明你查的是浏览器修复后的 DOM,不是你写的
- 查孤立节点:
[...document.querySelectorAll('*')].filter(el => !el.parentElement),被踢出来的div会直接出现在结果里
哪些标签在
里会触发强制闭合
只要不是 phrasing content(短语级内容),一律会被拒收。以下写法全部非法,效果等同于提前关掉
:
-
<p></p>
<h2>标题</h2> → 实际变成 <p></p>
<h2>标题</h2>
<p></p>
-
<p></p>
<ul><li>项</li></ul> → <p></p>
<ul><li>项</li></ul>
<p></p>
-
<p></p>
<p>嵌套段落</p> → 第二个<p></p>一出现,前一个就被强制闭合
-
<p><section>内容</section></p> → 同样被踢出,且section失去语义上下文
替换方案要按语义选,不是随便换标签
多数人改错的根源,是把<p></p>
<div>xxx</div>
改成<div><p>xxx</p></div>,看似“合法”了,但语义和结构问题还在:
- 需要图文卡片+说明文字?用
<article></article>或<section></section>作外层容器,<p></p>只包纯段落文本
- 只是想加边距或背景色?直接给内容块加 CSS:
margin、padding、background,别靠<p></p>撑结构
- 模板里动态渲染列表?先拼好所有
<p></p>,再整体包进<div class="content">,别在<code><p></p>标签内开for循环塞<div>
<li>必须保留视觉分组又不想污染语义?考虑<code>display: contents(注意 Safari 15.4+ 支持),让父容器不参与渲染流,只起逻辑作用
重构后最容易被忽略的验证点
改完别急着上线,三个硬指标必须过:
-
document.querySelector能否稳定命中?比如原p .btn现在是否得写成article .btn?如果是,说明语义分组不到位
- DOM 节点总数有没有明显下降?没降甚至更多,大概率只是把
div套p换成section套p,没解决根本问题
- 无障碍是否还正常?原
<p aria-live="polite"></p>迁移到新容器了吗?屏幕阅读器读出来的顺序是否和视觉一致?
真正难修的不是那一行错嵌套,而是它不报错、不警告,每次 JS 查不到、CSS 失效、SSR hydration 失败,都可能追溯到某个被浏览器悄悄拆掉的<p></p>
<div>上。</div>
、把非法内容提到外面,再补空
收尾——你看到的“布局错乱”,其实是DOM结构被静默重排后的结果,不是CSS没生效,是选择器根本找不到目标节点。
怎么确认是不是
嵌套惹的祸
别信源码缩进,信 Elements 面板里的真实 DOM:
- 打开 Chrome DevTools → Elements 标签页,找一个疑似有问题的
,右键 → “Edit as HTML”,删个字符再回车:如果子元素突然“跳出去”或缩进变平,说明原始嵌套不合法
- 在控制台运行:
document.querySelectorAll('p > *').forEach(el => console.log(el.tagName)),如果输出里有DIV、H2、UL,那说明你查的是浏览器修复后的 DOM,不是你写的 - 查孤立节点:
[...document.querySelectorAll('*')].filter(el => !el.parentElement),被踢出来的div会直接出现在结果里
哪些标签在
里会触发强制闭合
只要不是 phrasing content(短语级内容),一律会被拒收。以下写法全部非法,效果等同于提前关掉
:
-
<p></p> <h2>标题</h2>→ 实际变成<p></p> <h2>标题</h2> <p></p> -
<p></p> <ul><li>项</li></ul>→<p></p> <ul><li>项</li></ul> <p></p> -
<p></p> <p>嵌套段落</p>→ 第二个<p></p>一出现,前一个就被强制闭合 -
<p><section>内容</section></p>→ 同样被踢出,且section失去语义上下文
替换方案要按语义选,不是随便换标签
多数人改错的根源,是把<p></p>
<div>xxx</div>
<div><p>xxx</p></div>,看似“合法”了,但语义和结构问题还在:
- 需要图文卡片+说明文字?用
<article></article>或<section></section>作外层容器,<p></p>只包纯段落文本 - 只是想加边距或背景色?直接给内容块加 CSS:
margin、padding、background,别靠<p></p>撑结构 - 模板里动态渲染列表?先拼好所有
<p></p>,再整体包进<div class="content">,别在<code><p></p>标签内开for循环塞<div> <li>必须保留视觉分组又不想污染语义?考虑<code>display: contents(注意 Safari 15.4+ 支持),让父容器不参与渲染流,只起逻辑作用 -
document.querySelector能否稳定命中?比如原p .btn现在是否得写成article .btn?如果是,说明语义分组不到位 - DOM 节点总数有没有明显下降?没降甚至更多,大概率只是把
div套p换成section套p,没解决根本问题 - 无障碍是否还正常?原
<p aria-live="polite"></p>迁移到新容器了吗?屏幕阅读器读出来的顺序是否和视觉一致?
重构后最容易被忽略的验证点
改完别急着上线,三个硬指标必须过:
真正难修的不是那一行错嵌套,而是它不报错、不警告,每次 JS 查不到、CSS 失效、SSR hydration 失败,都可能追溯到某个被浏览器悄悄拆掉的<p></p>
<div>上。</div>










