将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
富文本编辑器中不能直接用嵌套,因为浏览器contenteditable会强制规范化dom结构,将非法嵌套拆解为扁平化节点(如文字块内容),导致样式丢失、js操作失败、css选择器失效。

富文本编辑器里
自动闭合
你在 TinyMCE、Quill 或原生 contenteditable 中写 <p>文字</p>
<div>块内容</div>
div、CSS 选择器 p > div 失效——这不是编辑器 bug,也不是你漏写了分号,而是浏览器解析器在初始化时就把它拆了:<p>文字</p>
<div>块内容</div>
<p></p>。这个过程不报错、不警告,但 DOM 已经和你写的完全两样。
富文本中插入块级内容必须绕开
容器
当你需要在段落中间插入卡片、引用块、代码块等块级结构时,别试图把它塞进 <p></p> 里。富文本编辑器的合法直接子节点只有: <p></p>、<h1></h1>~<h6></h6>、<ul></ul>、<ol></ol>、<pre class="brush:php;toolbar:false;"></pre>、<blockquote></blockquote> 等“可编辑块级元素”。<div> 不在此列,强行插入会被降级或移出。
<ul><li>用 <code><section></section> 或 <article></article> 替代外层 <div>,它们语义合法且允许作为 contenteditable 直接子元素
<li>若只是视觉分组,给 <code><p></p> 加 class(如 class="lead"),再用 CSS 控制 margin/padding,而非靠嵌套撑结构
<p>正文</p>
<div class="card">...</div>
<p>续文</p>),再整体插入,不要在 <p></p> 标签内开 <div>
<h3>TinyMCE/Quill 中连续插入导致嵌套的真相</h3>
<p>调用 <code>mceInsertContent 或 editor.insertEmbed() 多次时,如果光标还停在上一个插入的 <p></p> 内部,下一次插入大概率被吞进去,形成 <p>...</p>
<p>嵌套</p> 这类非法结构。这不是插件问题,是浏览器对 contenteditable 的强制规范化。
- 插入前手动把光标移到段落外:用
editor.selection.setCursorLocation()定位到<p></p>后或新行 - 批量插入时,改用数组 + 循环:把所有要插的内容预处理为独立 HTML 片段,逐个调用插入,并确保每次都在前一个节点之后
- 检查编辑器配置:TinyMCE 的
forced_root_block: false可禁用自动包裹<p></p>,但需配合valid_children显式放行你需要的组合
怎么一眼看出富文本输出是否已“被浏览器修过”
别信源码,看真实 DOM。打开 Chrome DevTools 的 Elements 面板,找到某个 <p></p> 节点,右键 → “Edit as HTML”,删一个字符再回车确认——如果里面原本写的 <div> 突然跳到外面、缩进变平、或者多出空 <code><p></p>,说明原始结构已被静默修正。
- 运行
document.querySelectorAll('p > *').forEach(el => console.log(el.tagName)),输出里出现DIV或H2?那一定是修复后的 DOM,不是你写的 - 查孤立节点:
[...document.querySelectorAll('*')].filter(el => !el.parentElement),被踢出来的<div> 就藏在这里 <li>服务端渲染(SSR)场景下,前后端 DOM 结构不一致极易触发 hydration error,这类问题十有八九源于某处 <code><p></p> <div> 的静默拆解 真正难的不是写对标签,而是在富文本编辑器这种“半托管环境”里,既满足用户所见即所得的直觉,又守住 HTML 规范的底线。每一次看似无害的 <code><p></p> <div>,都在悄悄松动结构的地基。</div>










