1. 为什么公众号排版这么折腾,以及我为什么干脆写了个在线工具
做技术写作的人大概都有这种体验:本地用 Typora、VS Code 或 Obsidian 把 Markdown 写得好好的,代码块、表格、加粗、列表全都舒服得很,一旦要发公众号,排版就变成了一场灾难。
公众号编辑器不识别 Markdown 语法,标题得手动调字号,代码块粘贴过去缩进全丢,表格干脆变成一团乱麻。更麻烦的是,如果文章里嵌了图片,你还得一张张上传,传完还要重新核对位置。我见过不少博主,写文章花 40 分钟,排版花 1 小时,这时间分配本身就很有问题。
后来市面出现了一些“Markdown 转公众号”的工具,比如 md.openwrite、mdnice 这类在线服务,确实解决了一部分问题。但它们大多是 SaaS 平台,你要注册登录、要绑定公众号、要把内容传到别人的服务器上。有些同事因为内容保密要求,根本不敢用这类在线服务;还有些人单纯嫌注册流程烦,或者担心哪天平台挂了、换域名了,自己积累的排版习惯就全废了。
所以我自己做了一个“在线一键 Markdown 文章转公众号文章”的小工具。逻辑很简单:选好主题样式,把 Markdown 内容粘贴进去,右侧实时预览,点一下“复制”,直接粘贴到公众号编辑器里就是排版好的效果。不需要注册,不需要上传到任何服务器,纯浏览器本地处理。这篇文章就把完整实现思路、技术选型、实操步骤和踩坑记录都分享出来。
先给不知道这东西能干嘛的朋友一个定位:它适合经常写公众号的技术博主、产品经理、运营同学,也适合那些公司内部有内容发布需求、但又不方便用外部 SaaS 平台的团队。只要你会写 Markdown,就能在 10 秒内得到一份排版合格的公众号文章。
2. 整体设计思路:为什么选纯前端方案,而不是架个后端服务
2.1 核心需求拆解
动手之前我先把需求列清楚,只有明确了边界,技术选型才不会纠结。
工具要解决的核心问题有三个:
- 把 Markdown 语法解析成 HTML,这是所有转换工具的基本功。
- 把 HTML 套上一层适合公众号展示的 CSS 样式,包括字体、行高、代码块配色、表格边框、引用块左侧色条等。
- 提供“复制到公众号”的能力。这一步比想象中麻烦,因为公众号编辑器对粘贴内容的过滤规则很严格,直接复制 HTML 源码是不行的,需要复制带格式的富文本内容。
除此之外,还有一些不那么起眼但实际使用中很重要的需求:图片怎么处理、代码高亮是否引入、表格是否支持、主题样式是否可切换、移动端预览效果是否正常。
2.2 技术选型:为什么不用后端
这个工具我一开始就没打算做后端,理由很实际:
- 不需要数据存储。用户粘贴 Markdown,得到 HTML,过程无状态,没有任何需要持久化的用户数据。
- 不需要账号体系。绑定公众号、保存文章这种功能本质上是为了平台留存用户,但对一个自用工具来说完全是负担。
- 不存在跨域问题。因为不调用任何第三方 API,所有解析和样式渲染都在浏览器里完成。
- 部署成本低到可以忽略。一个静态页面丢到 GitHub Pages 或者对象存储上就能用,没有服务器,也就没有维护成本。
纯前端方案的另一个好处是隐私性。文章内容从头到尾只在浏览器内存里走一遍,不会经过任何服务器。对很多公司内部文档来说,这是个非常实在的卖点。我在给团队内部做分享时就特意强调了这点:你贴进去的草稿不会出现在任何数据库里,关掉页面就什么都没了。
技术栈上我选择了 Marked + highlight.js + 手写 CSS 主题,而不是直接用现成的 mdnice 那套开源代码改。原因很简单:Marked 足够轻量,解析速度快,API 清晰;highlight.js 的代码高亮配色成熟,支持语言多;剩下的排版样式部分,自己写 CSS 反而更灵活,不受既有框架束缚。
2.3 方案对比:自研 vs 现有工具
市面上已有的 Markdown 转公众号工具不算少,我列个表格对比一下,方便你理解我在设计上的取舍:
| 对比维度 | 自研纯前端工具 | mdnice 等在线平台 | 手动在公众号编辑器排版 |
|---|---|---|---|
| 是否需要注册 | 不需要 | 多数需要 | 不需要(但受罪) |
| 内容是否经过服务器 | 否,纯本地 | 是 | 不适用 |
| 排版速度 | 秒级 | 秒级 | 10-30 分钟 |
| 主题可定制性 | 自己改 CSS,完全可控 | 受平台限制 | 完全可控但费时 |
| 代码高亮 | 支持 | 支持 | 几乎不支持 |
| 离线可用 | 可以 | 不行 | 不适用 |
| 长期可用性 | 静态页面,随时自托管 | 依赖平台存续 | 不适用 |
我并不是说现有平台不好,它们做得挺成熟。但“纯前端、零依赖、可自托管”这件事,对于喜欢掌控感的技术人来说,吸引力太大了。你想想:一个 HTML 文件存本地,双击打开就能用,不依赖任何外网资源,这感觉完全不一样。
3. 核心功能拆解:Markdown 解析、代码高亮、样式引擎
3.1 Markdown 解析器选型:Marked 为什么够用
Markdown 解析器有很多:marked、markdown-it、remark、showdown 等等。我最终选了 Marked,原因有三个。
第一,体积和速度。Marked 的压缩后体积只有几十 KB,解析速度在同类库里属于第一梯队。公众号文章单篇基本在几千到一万字,Marked 解析耗时可以忽略不计,实际测试中 1 万字的 Markdown 文档解析加渲染不超过 50 毫秒。
第二,配置足够灵活。Marked 支持自定义渲染器(renderer),这意味着我可以拦截特定节点的输出。比如图片节点,我可以在渲染时注入自定义处理逻辑;代码块节点,我可以决定是否交给 highlight.js 处理。
第三,生态成熟。Marked 的社区用户量大,遇到问题基本搜一下就有答案。相比 markdown-it 那种插件化架构,Marked 更轻,也更契合我这种“不太需要扩展、只要核心转换”的场景。
实际使用中,我用的是 marked 的经典用法:
import { marked } from 'marked'; marked.setOptions({ gfm: true, breaks: true }); const html = marked.parse(markdownContent);这里有两个选项要特别说明。gfm开启 GitHub 风格 Markdown,这样表格、删除线、任务列表这些语法都能被正确解析。breaks开启换行转换,这个对公众号写作非常重要,因为很多人在 Markdown 里习惯用单换行来分段,breaks: true后单个换行就会渲染成<br>,避免出现“写的时候明明换行了,渲染出来全挤在一起”的问题。
3.2 代码高亮:highlight.js 的接入细节
公众号文章的读者有很大比例会把代码块截图保存,所以代码高亮做得好不好,直接影响文章的观感。我选了 highlight.js,接入流程比较简单:
npm install highlight.js然后在入口文件里引入样式和注册语言:
import hljs from 'highlight.js'; import 'highlight.js/styles/github.css'; // 按需注册常用语言,没必要全量引入 import javascript from 'highlight.js/lib/languages/javascript'; import typescript from 'highlight.js/lib/languages/typescript'; import python from 'highlight.js/lib/languages/python'; import bash from 'highlight.js/lib/languages/bash'; import json from 'highlight.js/lib/languages/json'; hljs.registerLanguage('javascript', javascript); hljs.registerLanguage('typescript', typescript); hljs.registerLanguage('python', python); hljs.registerLanguage('bash', bash); hljs.registerLanguage('json', json);这里有个细节值得注意:全量引入 highlight.js 会加载所有语言包,体积一下多出几百 KB。对一个纯前端页面来说,这个体积虽然不算致命,但没必要。按需注册语言包,只留自己常用的几种,加载速度和页面性能都会更好。
关键的接入逻辑在 Marked 的自定义渲染器里,我拦截了code节点的渲染:
const renderer = { code(code, infostring, escaped) { const lang = (infostring || '').match(/\S*/)[0]; const validLang = hljs.getLanguage(lang) ? lang : 'plaintext'; if (validLang !== 'plaintext') { const highlighted = hljs.highlight(code, { language: validLang }).value; return `<pre class="hljs code-block"><code>${highlighted}</code></pre>`; } return `<pre class="hljs code-block"><code>${escapeHtml(code)}</code></pre>`; } }; marked.use({ renderer });这里要注意的坑是:如果代码块标注的语言 hljs 不认识,一定要 fallback 到plaintext,并且把代码内容做 HTML 转义。否则用户写了<div>这种标签,会直接被浏览器解析,页面上什么都看不清,甚至可能被注入脚本,这是安全红线。
3.3 样式引擎:一套 CSS 如何支撑多主题切换
工具支持多套主题样式切换,这是提升使用体验的一个重要功能。有人喜欢浅色简洁风格,有人喜欢深色酷炫风格,还有人喜欢类似知乎、掘金的特定配色。我的实现方式不是为每个主题写一套完整 CSS 文件,而是用 CSS 变量统一管理。
思路大概是这样的:
.theme-default { --primary-color: #2f80ed; --bg-color: #ffffff; --text-color: #333333; --code-bg: #f6f8fa; --border-color: #e1e4e8; --quote-bg: #f0f7ff; } .theme-dark { --primary-color: #58a6ff; --bg-color: #0d1117; --text-color: #c9d1d9; --code-bg: #161b22; --border-color: #30363d; --quote-bg: #1f2937; }然后在具体样式中引用这些变量:
.markdown-body { background-color: var(--bg-color); color: var(--text-color); } .markdown-body blockquote { background: var(--quote-bg); border-left: 4px solid var(--primary-color); } .markdown-body pre code { background: var(--code-bg); border: 1px solid var(--border-color); }切主题的时候,只需要切换根容器的 class 名,所有颜色自动变化。这个方案的优点是不用维护多份重复的 CSS 文件,改一个主题的配色只需要替换变量值,新主题的创建成本也低,加一组变量就行。
4. 实操过程:从搭建页面到完成复制到公众号的完整链路
4.1 页面布局与交互设计
页面布局我没有搞得很花哨,核心就是左右两栏结构:左边是 Markdown 输入区,右边是预览区。输入区放一个<textarea>,预览区放一个div,两者联动。
交互逻辑相当简单:
const textarea = document.getElementById('markdown-input'); const preview = document.getElementById('preview'); textarea.addEventListener('input', () => { const html = marked.parse(textarea.value); preview.innerHTML = html; });监听输入事件,每次内容变化都重新解析和渲染。由于 Marked 速度足够快,不需要做防抖也能流畅运行。实测输入过程中不会出现卡顿或闪烁。
顶部放了一排操作按钮:主题切换、复制到公众号、清空内容。这里最核心的是“复制到公众号”按钮,它的实现原理决定了整个工具能不能在公众号里真正用起来。
4.2 复制到公众号的浏览器兼容方案
这是整个工具里技术含量最高、坑最多的一部分。公众号编辑器本质上是一个富文本编辑器,它接受的是带格式的 HTML 粘贴。浏览器在复制富文本时,依赖的是ClipboardEvent里的clipboardData,我们手动触发复制时要用document.execCommand('copy')或者新版navigator.clipboard.write()。
要实现“复制富文本”,关键思路是:
- 把预览区的 HTML 内容放入一个隐藏的、可编辑的容器中。
- 选中这个容器里的内容。
- 执行复制命令。
- 浏览器会把选中内容的 HTML 格式一起放进剪贴板。
具体实现如下:
function copyToClipboard() { const previewContent = document.getElementById('preview'); const range = document.createRange(); range.selectNodeContents(previewContent); const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); const success = document.execCommand('copy'); selection.removeAllRanges(); if (success) { showToast('已复制,去公众号粘贴即可'); } else { showToast('复制失败,请手动选中预览区内容复制'); } }document.execCommand('copy')虽然已经被标记为废弃 API,但至今在 Chrome、Safari 里依然是复制富文本最可靠的方式。新版navigator.clipboard.write()想写入 HTML 格式会比较绕,需要构造ClipboardItem,而且对text/html的 MIME 类型支持在不同浏览器里不一致。
这里我踩过一个具体的坑:如果不把预览区内容放进一个富文本可编辑区域,而是直接选中普通div的内容,Chrome 复制出来的内容可能丢失部分格式。解决办法是给预览容器加上contenteditable="true"属性,但这样用户在预览区点击时就会触发编辑,又不好。最终我做了个折中:复制时临时给预览容器加上contenteditable,复制完立刻移除。
4.3 复制后的样式细节:微信的特殊处理逻辑
复制到公众号编辑器后,有几个细节是必须处理的,不然排版会出问题。
第一个是图片宽度。公众号编辑器对图片的默认样式有特殊要求,如果你在 HTML 里写了<img src="..." style="width: 100%">,粘贴后可能被过滤或变形。所以在渲染 Markdown 中的图片时,我额外加了一层包裹:
const renderer = { image(href, title, text) { return `<p class="img-container"><img src="${href}" alt="${text}" title="${title || ''}"></p>`; } };用<p>标签包裹图片,并设置了图片最大宽度 100%、高度自适应,这样在公众号里显示不会超出屏幕宽度。
第二个是字体族。公众号编辑器默认字体是系统字体,如果你不在 CSS 里指定,粘贴后可能显示异常。我在样式里明确设置了:
.markdown-body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; font-size: 15px; line-height: 1.75; word-break: break-word; }15px 字号是公众号阅读比较舒服的尺寸,行高 1.75 也是经过多次测试比较满意的值,太密读者看着累,太疏又显得浪费版面。
第三个是链接颜色。公众号默认链接是蓝色,但如果你文章里大量使用链接,最好在样式里统一指定颜色,避免某些主题下链接颜色和正文颜色区分度不够。我用了主题色变量控制:
.markdown-body a { color: var(--primary-color); text-decoration: none; }4.4 代码块的微信粘贴适配
代码块在公众号里是最容易出问题的部分。我实测过很多种方案,最终采用了“复制时保留高亮 + 背景色用内联样式”的组合策略。
公众号编辑器粘贴时,会保留大部分内联样式,但会丢失一些外部样式表里的规则。这就是为什么很多在线工具的代码高亮在预览时很好看,复制到公众号后却变成黑色纯文本。解决方案是:代码高亮之后的样式不能只依赖外部 CSS 类名,必须把关键颜色转成内联 style。
我在复制前做了一步预处理:遍历预览区里所有.hljs和.hljs-keyword、.hljs-string这类高亮 span,把对应的颜色值通过 JavaScript 计算出来,然后写入内联样式。
function inlineCodeStyles(container) { const codeSpans = container.querySelectorAll('span[class*="hljs-"]'); codeSpans.forEach(span => { const color = getComputedStyle(span).color; const bgColor = getComputedStyle(span).backgroundColor; if (color) span.style.color = color; if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)') span.style.backgroundColor = bgColor; }); const codeBlocks = container.querySelectorAll('pre code'); codeBlocks.forEach(block => { const bg = getComputedStyle(block).backgroundColor; block.style.backgroundColor = bg; }); }这一步非常关键,不加这个预处理,你辛辛苦苦选的代码主题在公众号里基本会失效。
5. 我在实战中踩过的坑和总结的排查技巧
5.1 Markdown 表格在公众号里的兼容性问题
Markdown 表格在公众号里是一个老大难。原因在于微信的富文本编辑器对<table>标签支持很差,粘贴后表格样式经常错乱,宽度一会儿撑破页面,一会儿又缩成一团。
我试过几种方案:纯table标签、div模拟表格、复制时转成图片。最终选择了兼容性最好的做法:渲染时给表格加固定结构:
<div class="table-wrapper"> <table> <thead><tr><th>列1</th><th>列2</th></tr></thead> <tbody><tr><td>数据</td><td>数据</td></tr></tbody> </table> </div>然后 CSS 里写:
.table-wrapper { overflow-x: auto; margin: 16px 0; } .table-wrapper table { width: 100%; border-collapse: collapse; font-size: 14px; } .table-wrapper th { background: #f0f0f0; font-weight: 600; padding: 8px 12px; border: 1px solid #dfe2e5; } .table-wrapper td { padding: 8px 12px; border: 1px solid #dfe2e5; }即使这样,在公众号里表格的表现也不能说完美,窄表格可能出现挤压。我的建议是:表格列数不要超过 5 列,数据内容尽量简短,这样在手机上浏览效果最舒服。如果有大量数据要展示,更建议做成截图图片。
另外,Markdown 表格转换成 Excel 这个需求我一开始没考虑,但后来有朋友问我能不能支持。这个从技术上说跟公众号排版完全两个方向,如果要实现得引入 SheetJS 之类库。我没在工具里做,但如果你有类似需求,思路是把 Markdown 表格先解析成二维数组,再用 SheetJS 生成 xlsx 文件,网上有现成项目可以参考。
5.2 图片路径问题:本地图片怎么处理
很多新手在本地写 Markdown 时,图片使用的是相对路径,比如。这种图片在本地预览没问题,但粘贴到公众号后,图片是显示不出来的,因为公众号编辑器的图片是上传到你公众号素材库后才有的 URL。
我在工具里对图片做了两种处理:
- 如果是完整的网络 URL,直接渲染显示。
- 如果是相对路径或本地路径,预览区显示一个占位提示,提示用户先上传图片到图床,或者把图片直接粘贴进公众号后再调整位置。
这个限制在纯前端方案里无法解决,因为浏览器出于安全限制,不能读取本地文件的完整路径并展示。我的经验是:正经写公众号文章的人,早晚都要用图床,比如七牛云、阿里云 OSS、腾讯云 COS,或者 GitHub + jsDelivr 这类免费图床。把图片传到图床拿到 URL,再写进 Markdown,整个流程就畅通了。
5.3 换行和段落间距的细节调整
Markdown 里换行规则经常让新用户困惑。GFM 里两个空格加换行才是真正的换行,而单独一个换行会被忽略。但公众号写作场景里,很多人根本没这个概念,他们就是习惯写完一行敲个回车。
这就是为什么我在 Marked 里开启了breaks: true,让单个换行也能渲染成<br>。但开启这个选项也会带来一个小问题:列表项里的换行会被额外拆分,导致列表看起来间距过大。
解决办法是在 CSS 中对列表项的段间距做归一化处理:
.markdown-body li > p { margin: 4px 0; }这样即使列表里包含换行,间距也不会失控。这个细节我自己用的时候才意识到,最初版本的列表排版间距确实有问题。
5.4 移动端预览和公众号手机端的对齐
写公众号的人必须考虑手机阅读体验,超过 70% 的用户是用手机打开的。所以我给预览区加了一个“移动端模式”开关,切换后预览宽度变成 375px,模拟手机屏幕。
这个功能实现起来很简单:
function toggleMobilePreview() { const previewWrap = document.getElementById('preview-wrapper'); previewWrap.style.maxWidth = previewWrap.style.maxWidth === '375px' ? '100%' : '375px'; previewWrap.style.margin = '0 auto'; }别小看这个功能,很多排版问题在电脑上看根本不明显,一切换到移动端立马暴露:表格超宽、代码块横向滚动、图片撑破容器、标题字太大。我在实际写文章时,几乎每次都要切到移动端预览检查一遍才敢复制去公众号。
5.5 常见问题速查
我把自己用这个工具过程中遇到的典型问题整理成一张表,方便你直接对照解决:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 复制到公众号后代码没有高亮 | 高亮颜色没有内联化 | 检查复制前是否执行了inlineCodeStyles()预处理 |
| 表格在公众号里错乱 | 表格列数太多或内容过长 | 限制列数在 5 列以内,内容尽量精简 |
| 图片显示不出来 | 使用了本地相对路径 | 换成图床 URL 或直接粘贴图片到公众号 |
| 换行全部消失 | 未开启breaks: true | 在 Marked 配置中开启breaks选项 |
| 复制时格式丢失 | 预览容器缺少contenteditable | 复制前临时添加contenteditable属性 |
| 深色主题下公众号页面异常 | 背景色被内联化到了整个容器 | 复制时仅内联代码块的背景色,不要内联容器背景色 |
| 代码块横向滚动条不出现 | 缺少overflow-x: auto样式 | 给pre添加overflow-x: auto,并设置white-space: pre |
5.6 离线可用和部署技巧
这个工具我最终打成了一个纯静态项目:HTML + CSS + JavaScript,所有依赖都通过 npm 打包进产物,没有使用 CDN 链接。这样做的最大好处是:文件下载到本地也能用,离线状态完全可用。
如果你也希望部署一份给自己团队用,我推荐三种方式:
- GitHub Pages:仓库 push 后自动发布,免费且稳定。
- 对象存储静态网站托管:阿里云 OSS / 腾讯云 COS 都有静态网站托管功能,要点是设置好 Index 文档为
index.html。 - 本地局域网:直接把
dist目录用python -m http.server 8080起个服务,团队内网就能访问。
如果你是纯个人使用,更简单:把打包后的index.html双击打开,浏览器直接运行。由于没有用到任何需要服务器环境的功能,这个工具天然支持 file:// 协议。
6. 这个工具还能怎么扩展
做完这个工具后,我意识到它的架构其实可以延展到很多方向。给你几个我验证过可行的扩展思路:
第一,接入更丰富的主题。目前我内置了四套主题:默认浅色、深色、知乎风格、极简风格。你完全可以根据自己公众号的视觉定位定制专属主题,改 CSS 变量就行。我建议至少准备两套,一篇技术文章用深色代码块主题,一篇行业观点文章用浅色简洁主题。
第二,增加“导出为图片”功能。公众号文章封面图、Twitter 分享卡片、朋友圈配图,这些场景都需要把文章部分内容转成图片。技术上可以使用 html2canvas 这类库,把预览区渲染成 canvas,再导出为图片。我试验过,效果还不错,但要注意长文章截图的性能问题,可以先对内容分页再逐页截图。
第三,接入 AI 辅助写作。最近大家都在用 AI 写文章,Markdown 格式天然适合作为 AI 输出的载体。你可以把 AI 生成的 Markdown 直接粘贴到这个工具里获得公众号排版,也可以用 Coze、Dify 这类工作流编排平台,把 Markdown 转 Word 或转公众号排版的步骤自动化。我看到不少关于“Markdown 转 Word 工作流”、“Dify Markdown 转 Word 自动编号”的讨论,本质上就是把这套转换逻辑嵌入到更大的流程里。
第四,增加字数统计和阅读时长估算。公众号后台有自己的统计,但写作时实时看到字数变化和预计阅读时长,对控制文章篇幅还是有帮助的。实现不算复杂,统计中文字符数和空白分隔的英文单词数,再按每分钟 300-400 字的阅读速度估算即可。
7. 关于 Markdown 编辑器的一点题外话
既然标题和热搜词里都出现了很多 Markdown 编辑器的相关内容,我也顺手聊几句自己的看法,毕竟这个工具的源头就是从 Markdown 写作场景来的。
Typora 是最流行的 Markdown 编辑器之一,所见即所得的特性让它上手几乎没有门槛。网上能找到所谓“Typora 中文破解版”的下载资源,但我的建议是:如果是常用的工具,几十块钱买份正版,省心也安全。“破解版”文件来源不明,插入恶意代码的风险不是没有,没必要为这点钱去赌。
其他我实际用过的编辑器里:VS Code 加 Markdown Preview Enhanced 插件适合程序员,支持 Mermaid 图表预览、导出 PDF、自定义 CSS,功能很强;Obsidian 适合做知识库和双链笔记,它的 Markdown 文件和插件生态都做得很成熟;Notion 虽然也支持 Markdown 语法输入,但底层并不是标准的 Markdown 文件系统,迁移性略差。
“对 deepseek 提问用自然语言还是 Markdown 更容易让 AI 明白指令”这个话题,也有不少人讨论。我的经验是:对于普通对话,自然语言足够;对于复杂的多步骤任务,Markdown 的结构化格式对 AI 理解约束条件有帮助,比如用标题、列表、表格清晰列出输入、约束、输出格式时,AI 犯迷糊的概率显著降低。这和写文章是一个道理——结构清晰的内容,解析端和消费端的体验都会更好。
我在实际使用这套工具时最大的体会是:排版的本质不是“把工具用熟”,而是“把写作和发布之间的摩擦降到最低”。当你不再需要为了换个字体大小或调个行间距打断思路,写作的流畅度完全不一样。这篇文章里分享的每一个细节,都是我自己从“临时用一下”到“每天离不开”的过程中踩出来的。你现在按着这个思路做,遇到的坑大概率会比我少一些。
最后再分享一个小技巧:复制到公众号之后,如果发现某些细节不对,别急着回到工具里改。先看看是不是公众号编辑器自身的样式覆盖问题——比如字体颜色、行间距、列表缩进这些,公众号编辑器有自己的默认规则。确认是样式被覆盖了,再回到工具里用内联样式调整,往往一次就能解决。排版这件事,很多时候差的就是这点耐心。