指南
Markdown 转公众号:为什么复制过去样式全丢了
Markdown 转公众号的难点不在转换,而在微信会清洗粘贴进来的 HTML。这篇文章说明 class、style 标签、flex/grid、position 为什么必然失效,并给出判断转换器是否可靠的三条标准和一份可自查的规则清单。
「Markdown 转公众号」指的是把 Markdown 源码渲染成一段带内联样式的 HTML,再粘贴进公众号后台,让排版在微信编辑器里保留下来。真正的难点不在转换本身——渲染 Markdown 是二十行代码的事——而在于微信会对粘贴进来的 HTML 跑一遍清洗。class、<style> 标签、display:flex、grid、position 定位都会被丢掉。所以判断一个转换器能不能用,看的不是它支持的语法多不多,而是它产出的 HTML 长得对不对。
为什么粘贴之后样式就没了
复制一段带样式的网页内容,剪贴板里存的是两样东西:一份纯文本,和一份 HTML 片段。公众号后台读的是后面那份 HTML,读完之后不直接保存,而是先清洗一遍。
清洗的规则大致是这样的:
| 被丢弃的写法 | 后果 |
|---|---|
class="..." 属性 | 依赖 class 的一切样式全部失效,因为 class 定义在哪儿它都拿不到 |
<style> 标签 | 整段丢弃,外部样式表和内嵌样式块都活不下来 |
display: flex / inline-flex / grid | 属性被剥掉,元素退化成块级,多列布局塌成一列 |
position: absolute / fixed / sticky | 被剥离,浮层、角标、叠加元素全部归位到文档流 |
writing-mode | 被过滤,竖排文字直接变成横排 |
<script> / <svg> | 元素整个移除,交互动效不可能保留 |
留下来的,基本只有内联 style 属性这一条路。所以一份能在公众号里活下来的排版产物,形态上必须满足:每个视觉元素自带内联样式,不依赖任何外部样式定义。
这就解释了那个最常见的问题:为什么在编辑器里看着好好的,粘过去就全乱了。编辑器里能看到效果,是因为浏览器认识 class 和 <style>;微信不认,所以只有它俩的产物会活下来。
判断一个转换器靠不靠得住,看三条
不需要读它的源码,把产物拿到微信后台粘一次就能验证。
第一条:关掉浏览器样式后还能看吗。 把产物另存成 HTML,用浏览器打开,在开发者工具里禁用所有外部样式(或者干脆看产物的源码里有没有 <style> 和 class)。如果样式全没了,说明它依赖外链样式,粘进微信也活不下来。
第二条:多列布局是表格还是 flex。 搜索产物里的 display:flex 和 <table。出现 flex 的多列,粘过去一定塌成一列;用 <table> 做的多列才是稳的。这一条在图片并排、数据卡并排、图文混排上最容易出问题。
第三条:有没有复制前的检查。 好的工具不会让你粘贴完才发现问题。它在复制那一刻就会扫描产物、把会失效的写法列出来。这一条是区分「能转换」和「能负责」的分水岭。
顺带一个反直觉的点:产物的样式越少越稳。 一个用了十几层嵌套 div 加 flex 的精美模板,粘进微信后大概率比一段朴素的内联样式更难看。排版强度应该花在字号、行距、留白和结构上,而不是花在布局技巧上——因为布局技巧正好是微信清理得最彻底的那一类。
本工具实际在拦哪些写法
LayoutAtlas 在点「复制到公众号」时会跑一遍自检,规则一共八条,全部来自微信清洗行为的实测与推导:
| 规则 | 为什么拦 |
|---|---|
内嵌 <style> 标签 | 微信会整体丢弃 |
出现 class | 微信会清掉,样式随之全部失效 |
使用 writing-mode | 微信过滤该属性,竖排要用表格逐字实现 |
使用 display: flex / grid | 公众号不支持,多列要改成表格布局 |
使用 position: absolute / fixed / sticky | 微信会剥离,浮层要去掉或改表格 |
使用 <mark> 标签 | 改用 <span style="background:…"> 更稳 |
用 text-decoration: underline 做下划线 | 改用 border-bottom,被 span 包裹后更可控 |
存在空 src 的图片 | 会显示裂图 |
自检发现问题不会禁止你复制,而是列出清单让你决定。有些写法在特定场景下值得赌一把——比如只有一句话的小字说明。工具负责把风险说清楚,不替你拍板。
常见问题
取决于转换器怎么处理。本工具会把连续的数据行转成数据卡组件(用表格实现),普通表格也走表格,所以不会塌。要注意的是表头分隔行必须存在,否则一段带竖线的普通文字会被误判成表格。
代码块依赖等宽字体和 white-space: pre。前者在微信里靠字体栈兜底,后者微信是保留的。真正会出问题的是超长行——微信正文宽度固定,不折行的长代码会被裁掉,所以换行位置要在源码里就处理好。
前者复制的是富文本,直接粘进公众号后台就能看到排版;后者复制的是 HTML 源码,适合粘进别的编辑器或者存档。发公众号用前者。
不会。微信的清洗是按元素逐个做的,与文章长度无关。但长文更容易在复制过程中触发浏览器的剪贴板截断,所以超长文章建议分段粘贴,或者用导出 HTML 的方式存档。
粘完之后在公众号后台按 Ctrl/Cmd + A 全选、再复制一次,粘回一个空白编辑器里看。这一步拿到的是微信清洗后的真实产物——比看文章预览页准确,因为预览页还会经过一层前台渲染。