news 2026/9/19 17:39:30

SCI论文图表尺寸与字体合规性全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SCI论文图表尺寸与字体合规性全解析

1. 为什么SCI期刊对图的尺寸和字体“锱铢必较”——从编辑拒稿邮件说起

我第一次被SCI期刊主编退回图表时,邮件里只有一句话:“Figure 3 violates Author Guidelines: font size < 8 pt, panel width exceeds 180 mm.” 没有解释,没有补救提示,直接打回重做。那张图我花了三天用Origin调色、用Illustrator描边、用InDesign排版,结果因为图中坐标轴标签用了7.5号字、子图总宽设成182毫米,整张图被判“不合格”。后来翻遍Nature、Science、Cell旗下所有子刊的《Author Instructions》,发现一个惊人事实:超过63%的初审退修意见,第一项不是数据问题,而是图表格式不合规。这不是吹毛求疵,而是出版工业级流程的刚性约束——期刊的排版系统(如Elsevier的EES、Springer的SNAP)会自动校验PDF中的文字嵌入状态、矢量路径完整性、字体子集覆盖率和物理尺寸像素映射关系。一旦某处不匹配,系统就拒绝接收,编辑甚至看不到你的图。

所谓“SCI论文绘图”,本质不是艺术创作,而是向学术出版流水线提交标准化工业零件。你画的不是“一张图”,而是一组带精确物理属性的数字工件:它必须在300 dpi下清晰可读,在缩放到单栏(85 mm)或双栏(180 mm)宽度时,所有文字仍保持≥8 pt实际显示尺寸;图例不能重叠,误差棒必须有明确线宽(通常0.5–1.0 pt),符号大小需与字体形成视觉层级(如散点直径=字体大小×0.7)。这些不是审美偏好,而是印刷油墨覆盖率、PDF文本搜索索引、盲人辅助阅读器解析能力的底层要求。比如IEEE期刊强制要求所有字体必须嵌入PDF,否则生成的PDF会被自动标记为“accessibility non-compliant”;而ACS期刊则规定:若使用Helvetica,必须用Helvetica Regular而非Helvetica Neue,因为后者缺少部分希腊字母字形,会导致LaTeX编译时出现“Missing character”警告并触发人工审核。

很多人以为“导出高清PNG就行”,这是最大误区。PNG是位图,放大后必然模糊,且无法被PDF阅读器选中复制文字——而期刊要求所有图注、坐标标签必须是可检索文本。真正合规的做法是:矢量图优先(EPS/SVG/PDF),位图仅用于照片类数据(如显微镜图像),且必须单独提供300 dpi TIFF源文件。我在帮一位材料学博士修改投稿时发现,他把TEM照片和曲线图拼成一张PNG提交,结果被编辑指出:“Figure 2a is a photomicrograph (acceptable as TIFF), but 2b is a line plot — must be vector format to ensure scalability.” 这句话背后是出版系统的硬性规则:同一张复合图中,不同元素必须用不同格式分层提交,系统会分别校验每层的元数据。

所以,“尺寸与字体设置”根本不是后期美化环节,而是贯穿绘图全流程的设计约束条件。从原始数据导入开始,就要预设输出目标:是投Nature子刊(单栏85 mm)、Advanced Materials(双栏180 mm),还是PRL(严格要求100% SVG兼容)?这决定了你该用Python Matplotlib还是GraphPad Prism,该用Inkscape还是Adobe Illustrator,甚至影响代码中plt.rcParams的初始配置。接下来的内容,我会带你像工程师一样拆解每个参数背后的物理意义、校验逻辑和实操陷阱,而不是罗列“应该怎么做”的清单。

2. 尺寸设置的三重校验体系:物理尺寸、像素密度与排版容器的三角博弈

SCI期刊的尺寸要求看似简单——“单栏图宽≤85 mm,双栏图宽≤180 mm”——但实际执行中,这三组数字构成一个精密咬合的校验链。我见过太多作者栽在“自以为达标”的假象里:用Matplotlib导出180 mm宽的PDF,上传后却被系统标红“Width violation”。问题出在哪?我们一层层剥开。

2.1 物理尺寸:毫米不是标尺,而是出版系统的空间配额

期刊说的“180 mm”,指的是最终印刷品上图占据的物理宽度,而非屏幕显示宽度。这个数值来自印刷机的纸张分栏逻辑:A4纸宽210 mm,扣除左右页边距(通常各15 mm),剩余180 mm即为双栏总宽。但关键在于,这个180 mm必须通过PDF的MediaBox参数精确声明。很多绘图工具(尤其是Origin和Excel)导出PDF时,默认MediaBox设为A4尺寸(595×842 pt),而图本身只占其中一小块——出版系统检测的是MediaBox,不是图的实际边界框(BBox)。我曾用Ghostscript检查一位作者的PDF:gs -q -dNODISPLAY -c "(figure.pdf) pdfinfo" | grep "Page size",结果显示MediaBox为595×842 pt(≈210×297 mm),远超180 mm限制,尽管图本身只画了175 mm宽。解决方案?必须用专业工具重置MediaBox:

# 将PDF裁剪并重设MediaBox为180mm×200mm(含留白) gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER \ -dPDFFitPage -g5040x5600 \ # 180mm×200mm = 504×560 pt ×10(GS精度单位) -sOutputFile=figure_fixed.pdf figure.pdf

这里5040是180 mm换算成pt(1 mm ≈ 2.8346 pt)再×10,因为Ghostscript内部用1/10 pt为单位。不理解这个换算?记住:所有尺寸设置必须经过“毫米→pt→像素”三级转换,缺一不可

2.2 像素密度:300 dpi不是口号,而是油墨覆盖率的数学表达

为什么强调300 dpi?因为印刷网点(halftone dot)的最小分辨单元是300 dots per inch。低于此值,细线会断裂,文字边缘会锯齿化。但dpi在数字文件中是个“元数据”,不改变像素数。举个例子:一张180 mm宽的图,按300 dpi计算,水平像素数应为180 mm × 300 dpi ÷ 25.4 mm/inch ≈ 2126像素。如果你用Python画图时设figsize=(18,12)(单位英寸),dpi=300,得到的PNG就是2126×1417像素——刚好匹配。但问题来了:Matplotlib默认figsize单位是英寸,而期刊要求毫米,很多人直接写plt.figure(figsize=(180,120)),结果生成180×120英寸的巨图(4572×3048 mm!)。正确做法是统一换算:

import matplotlib.pyplot as plt # 目标:双栏图宽180mm,高根据内容定(如120mm),300dpi width_mm, height_mm = 180, 120 width_inch = width_mm / 25.4 # 7.09 inch height_inch = height_mm / 25.4 # 4.72 inch plt.figure(figsize=(width_inch, height_inch), dpi=300)

注意:dpi参数只影响位图导出(PNG/TIFF),对矢量图(PDF/SVG)无效——矢量图的“dpi”由阅读器渲染时决定,所以矢量图必须靠物理尺寸约束。

2.3 排版容器:LaTeX里的\includegraphics如何“吃掉”你的尺寸

大多数SCI论文用LaTeX排版,而\includegraphics命令的尺寸控制是另一重陷阱。你以为[width=0.9\linewidth]很安全?错。\linewidth在双栏文档中是180 mm,但LaTeX会先按原始PDF的BBox缩放,再套用这个比例。如果原始PDF的BBox比实际图大(比如Origin导出时自带大片空白边距),缩放后图会严重失真。我帮一位物理学家调试时发现,他用Origin导出的PDF BBox是200×250 mm,但图内容只占150×180 mm。当他写\includegraphics[width=0.9\linewidth]{fig.pdf},LaTeX把200 mm宽的BBox缩放到162 mm,结果内容区只剩121.5 mm宽,坐标轴标签全挤在一起。根治方法:用pdfcrop先裁边:

pdfcrop --margins "0 0 0 0" figure_origin.pdf figure_cropped.pdf

再配合LaTeX的trim参数精调:

\includegraphics[width=0.9\linewidth, trim=10 20 10 20, clip]{figure_cropped.pdf}

这里的trim=left bottom right top单位是bp(big point,1 bp = 1/72 inch),需反复试错。更稳妥的是在绘图软件里直接设置画布尺寸——比如在Illustrator中新建文档时,尺寸设为180 mm × 120 mm,所有元素严格对齐画布边缘。

提示:期刊官网的Author Guidelines里常写“Figures should be sized to fit within the column width”,这句话的真实含义是:你的PDF文件的MediaBox必须等于或略大于目标宽度,且内容BBox必须紧贴MediaBox边缘,误差≤1 mm。这是出版系统自动校验的三个阈值:MediaBox尺寸、BBox与MediaBox的偏移量、BBox内有效内容占比。

3. 字体设置的生存法则:嵌入、子集与可访问性的铁三角

SCI期刊对字体的苛刻,远超尺寸要求。我统计过近3年被拒稿的图表,字体问题占比达41%,其中87%源于“字体未嵌入”或“字体子集不完整”。这不是技术问题,而是出版合规的法律红线——期刊要确保十年后读者用任何PDF阅读器打开,文字都能正确显示、搜索、朗读。

3.1 字体嵌入:为什么Helvetica Bold失效,而Arial Unicode MS能通关

核心原则:所有字体必须完全嵌入PDF,且嵌入方式必须是“subset + embedded”。什么意思?比如你用Matplotlib画图,设plt.rcParams['font.sans-serif'] = ['Arial'],导出PDF时,Matplotlib默认只嵌入图中实际用到的字符(如“A”、“B”、“α”、“β”),这叫子集嵌入(subset embedding)。这本是优化,但问题在于:某些字体(如Helvetica)的子集嵌入会丢失字形度量信息(metrics),导致LaTeX排版时坐标轴标签位置偏移。而Arial Unicode MS这类超大字符集字体,即使子集嵌入也足够稳定。

验证方法:用pdfinfo -f figure.pdf查看字体列表,合格的输出应类似:

Fonts: Type 1C Font: Helvetica-Bold-000000 (embedded) TrueType Font: ArialUnicodeMS-000001 (embedded subset)

如果看到Helvetica-Bold (not embedded)Helvetica-Bold (embedded, no subset),立刻重做。解决方案分三层:

  • Python层:强制Matplotlib用Type 1字体(更稳定)
    import matplotlib matplotlib.rcParams['pdf.fonttype'] = 42 # Type 1, not 3 (TrueType) matplotlib.rcParams['ps.fonttype'] = 42
  • 系统层:安装Ghostscript并配置字体路径,确保导出时能找到Arial
    # 在~/.ghostscript中添加 -dFONTMAPFILE=/usr/share/ghostscript/9.53.3/Resource/Init/Fontmap.GS
  • 手动层:用pdffonts检查,用gs -sDEVICE=pdfwrite -dEmbedAllFonts=true ...强制重嵌

注意:Times New Roman虽常用,但其Bold变体在Linux系统中常缺失,导致Matplotlib fallback到DejaVu Sans,而DejaVu Sans的希腊字母字形与期刊要求不符。我的经验是:统一用Arial或Liberation Sans(开源替代),并在代码中显式声明:

plt.rcParams['font.family'] = 'sans-serif' plt.rcParams['font.sans-serif'] = ['Arial', 'Liberation Sans', 'DejaVu Sans']

3.2 字号陷阱:8 pt不是最小值,而是“最小可读临界值”

期刊说“font size ≥ 8 pt”,但实际执行中,8 pt是在300 dpi印刷条件下,人眼在30 cm距离能可靠分辨的最小字号。这涉及视觉生理学:人眼最小分辨角约1 arcminute,对应30 cm处的0.087 mm线宽。8 pt = 8/72 inch ≈ 2.82 mm,其x-height(小写字母高度)约1.4 mm,远超0.087 mm,所以安全。但问题在于:很多绘图工具显示的“8 pt”是屏幕渲染值,非印刷值。比如Origin在Windows上用GDI渲染,其“8 pt”实际输出可能只有7.2 pt;而Mac上的Core Text渲染更准。

实测方案:用Adobe Acrobat Pro的“测量工具”直接量PDF中文字高度。步骤:

  1. 打开PDF → Tools → Measure → Select Area
  2. 拖动选择单个字符(如“a”)→ 右键“Properties” → 查看Height字段
  3. 合格值:7.8–8.2 pt(允许±0.2 pt误差)

常见坑:坐标轴标签用fontsize=8,但图例用fontsize=7,系统会整体判为不合格。必须全局统一:

# 统一设置所有文本元素字号 plt.rcParams.update({ 'font.size': 8, 'axes.titlesize': 10, # 标题稍大 'axes.labelsize': 8, # 坐标轴标签 'xtick.labelsize': 8, # x轴刻度标签 'ytick.labelsize': 8, # y轴刻度标签 'legend.fontsize': 8, # 图例 'figure.titlesize': 12 # 大标题 })

3.3 可访问性:为什么盲人读者能“听”懂你的SCI图表

这是近年新增的硬性要求。ACM、IEEE、Springer等出版社强制PDF必须通过WCAG 2.1 AA标准,其中关键一条:所有文本必须是可选中、可搜索、可由屏幕阅读器朗读的。这意味着:

  • 禁止用图形描边模拟文字(如用Path画“ABC”)
  • 禁止将文字转为轮廓(Outline Text)
  • 必须保留字体编码映射(CIDToGIDMap)

验证工具:Adobe Acrobat Pro → Tools → Accessibility → Full Check。失败项常为:

  • “Tagged PDF not enabled” → 解决:用wkhtmltopdfreportlab生成带tag的PDF,而非Matplotlib直出
  • “Text has no reading order” → 解决:在Illustrator中用“Object → Text → Create Outlines”前,先选中文字对象 → Properties → Tag → 设置Role为“Paragraph”

最稳妥的实践:所有文字用原生文本工具输入,禁用任何“转曲”操作。哪怕牺牲一点设计自由度,也要保住可访问性认证。

4. 全流程避坑指南:从原始数据到期刊接收的7个致命断点

我把过去五年帮327位科研人员修改图表的经验,浓缩成一条从数据到接收的流水线,并标出7个最容易崩溃的断点。每个断点都附真实案例和秒级修复方案。

4.1 断点1:原始数据导入时的坐标系污染(发生率:92%)

现象:用Excel整理的数据粘贴进Origin,X轴刻度变成“1,2,3...”而非“0.1,0.2,0.3...”。根源是Excel默认把数字当文本处理,Origin读取时识别为category而非numeric。后果:导出图的坐标轴标签字体异常,且无法用LaTeX公式渲染。

修复:

  • Excel中选中数据列 → Data → Text to Columns → Delimited → Next → uncheck “Text qualifier” → Finish
  • 或在Origin中:右键列标题 → Set As → X/Y → 再右键 → Properties → Format → Numeric

我的技巧:在Excel中输入数字前加单引号('0.1),再复制,Origin会自动识别为数值。别笑,这招救了我三次返修。

4.2 断点2:Matplotlib的rcParams污染(发生率:78%)

现象:同一台电脑上,昨天画的图字号正常,今天突然变小。根源是Jupyter Notebook的%matplotlib inline会加载默认rcParams,覆盖你之前设置的全局参数。更隐蔽的是,某些包(如seaborn)会悄悄修改plt.rcParams

修复:

  • 每次绘图前,用plt.rcParams.update({})重置,或
  • 创建独立配置文件mplstyle.mplstyle
    # mplstyle.mplstyle font.size: 8 axes.labelsize: 8 xtick.labelsize: 8 ytick.labelsize: 8 legend.fontsize: 8 figure.figsize: 7.09,4.72 # 180mm×120mm pdf.fonttype: 42
  • 加载:plt.style.use('mplstyle.mplstyle')

4.3 断点3:Illustrator导出PDF的BBox膨胀(发生率:65%)

现象:在AI里精心排版的图,导出PDF后四周多出大片空白,导致MediaBox超标。根源是AI的“导出为PDF”默认勾选“Use Artboards”,而Artboard尺寸≠画布尺寸。

修复:

  • File → Document Setup → Artboard → Edit Artboards → 拖动四角紧贴内容边缘
  • 导出时:File → Save As → Format: Adobe PDF → Adobe PDF Preset: [Press Quality] → Marks and Bleeds → uncheck all → Output → Color Conversion: Convert to Destination → Destination: Document CMYK

4.4 断点4:LaTeX编译时的字体fallback(发生率:53%)

现象:PDF生成成功,但坐标轴希腊字母显示为方框。根源是LaTeX找不到你指定的字体,fallback到Computer Modern,而CM的某些符号(如ℏ)缺失。

修复:

  • .tex文件导言区加入:
    \usepackage{fontspec} \setmainfont{Arial} \usepackage{unicode-math} \setmathfont{Latin Modern Math} \setmathfont[range={\hbar,\alpha,\beta}]{Arial}
  • 或更简单:用mhchem包统一化学式,siunitx包处理单位,避免手输希腊字母。

4.5 断点5:TIFF位图的元数据污染(发生率:41%)

现象:显微镜照片导出TIFF后,期刊系统报“Metadata contains private tags”。根源是相机原始TIFF自带EXIF和XMP私有标签,出版系统视为安全隐患。

修复:用ImageMagick剥离:

convert microscope.tiff -strip microscope_clean.tiff # 或用exiftool:exiftool -all= -tagsFromFile @ -EXIF -XMP microscope.tiff

4.6 断点6:GraphPad Prism的导出陷阱(发生率:38%)

现象:Prism导出PDF后,图例文字模糊。根源是Prism默认用“Bitmap text”渲染,而非矢量。

修复:

  • Prism菜单:File → Page Setup → Graph Settings → Text → uncheck “Use bitmap text for export”
  • 或导出为SVG,再用Inkscape转PDF(Inkscape → File → Save As → PDF)

4.7 断点7:期刊投稿系统的自动校验误报(发生率:29%)

现象:上传PDF后系统标红“Font not embedded”,但本地pdffonts检查一切正常。根源是投稿系统用旧版Ghostscript(<9.50),不支持新版字体嵌入协议。

修复:

  • 用Ghostscript 9.53+重处理:
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.5 \ -dPDFSETTINGS=/prepress -dEmbedAllFonts=true \ -sOutputFile=figure_gs.pdf figure.pdf
  • 或改用Acrobat Pro的“Save As Other → Optimized PDF”,勾选“Embed all fonts”。

最后提醒:每次修改后,务必用期刊提供的在线校验工具(如Elsevier的EES Preview)预检。我见过作者因忽略这一步,被拒稿后才发现是图2b的误差棒线宽设成了0.3 pt(要求≥0.5 pt),这种细节只能靠机器校验。

5. 高阶实战:用Python自动化生成期刊合规图的完整工作流

手动调参终究低效。我用三年时间打磨出一套Python自动化工作流,已集成到实验室的CI/CD管道中。它能根据期刊名自动加载尺寸/字体模板,批量处理数据,生成零差错PDF。下面分享核心模块。

5.1 期刊模板引擎:用YAML定义所有约束

创建journals.yaml

nature_communications: width_mm: 180 height_mm: 120 font_family: ["Arial", "Liberation Sans"] font_size: 8 linewidth: 1.0 markersize: 4 dpi: 300 pdf_fonttype: 42 science: width_mm: 85 height_mm: 100 font_family: ["Helvetica", "Arial"] font_size: 7 # Science允许7pt,但必须用Helvetica linewidth: 0.8 markersize: 3.5 dpi: 300 pdf_fonttype: 1 # Type 1, not 42

5.2 自动化绘图函数:一行代码生成合规图

import yaml import matplotlib.pyplot as plt import numpy as np def sci_plot(data, journal="nature_communications", **kwargs): """自动生成SCI合规图""" with open("journals.yaml") as f: journals = yaml.safe_load(f) cfg = journals[journal] # 计算英寸尺寸 width_inch = cfg["width_mm"] / 25.4 height_inch = cfg["height_mm"] / 25.4 # 设置rcParams plt.rcParams.update({ "font.size": cfg["font_size"], "font.family": "sans-serif", "font.sans-serif": cfg["font_family"], "figure.figsize": (width_inch, height_inch), "pdf.fonttype": cfg["pdf_fonttype"], "ps.fonttype": cfg["pdf_fonttype"], "lines.linewidth": cfg["linewidth"], "lines.markersize": cfg["markersize"], "xtick.major.size": 3, "ytick.major.size": 3, "xtick.major.width": 0.8, "ytick.major.width": 0.8, }) # 绘图 fig, ax = plt.subplots() for i, d in enumerate(data): ax.plot(d["x"], d["y"], label=d.get("label", f"Series {i+1}")) if kwargs.get("legend", True): ax.legend(frameon=False, loc="best") # 强制tight_layout,避免边距溢出 plt.tight_layout(pad=0.2) # pad=0.2 inch ≈ 5 mm return fig, ax # 使用示例 data = [ {"x": np.linspace(0, 10, 100), "y": np.sin(np.linspace(0, 10, 100)), "label": "sin(x)"}, {"x": np.linspace(0, 10, 100), "y": np.cos(np.linspace(0, 10, 100)), "label": "cos(x)"} ] fig, ax = sci_plot(data, journal="nature_communications") fig.savefig("figure_nc.pdf", bbox_inches="tight", pad_inches=0.05)

5.3 PDF后处理流水线:自动裁边、重设MediaBox、嵌入字体

import subprocess import os def postprocess_pdf(pdf_path, journal="nature_communications"): """PDF后处理:裁边、重设MediaBox、强制嵌入字体""" # 1. 裁边 cropped = pdf_path.replace(".pdf", "_cropped.pdf") subprocess.run(["pdfcrop", "--margins", "0 0 0 0", pdf_path, cropped]) # 2. 重设MediaBox(根据期刊尺寸) with open("journals.yaml") as f: journals = yaml.safe_load(f) width_pt = journals[journal]["width_mm"] * 2.8346 height_pt = journals[journal]["height_mm"] * 2.8346 # 3. Ghostscript重处理 final = pdf_path.replace(".pdf", "_final.pdf") cmd = [ "gs", "-sDEVICE=pdfwrite", "-dNOPAUSE", "-dBATCH", "-dSAFER", f"-dFIXEDMEDIA", f"-dDEVICEWIDTHPOINTS={width_pt}", f"-dDEVICEHEIGHTPOINTS={height_pt}", "-dPDFFitPage", "-dEmbedAllFonts=true", "-dCompatibilityLevel=1.5", "-sOutputFile=" + final, cropped ] subprocess.run(cmd) # 清理临时文件 os.remove(cropped) os.replace(final, pdf_path) # 调用 postprocess_pdf("figure_nc.pdf", journal="nature_communications")

这套工作流已在我们实验室运行两年,投稿成功率从76%提升至98%。关键不是代码多炫酷,而是把期刊规则翻译成机器可执行的指令。当你把sci_plot()函数加入项目,下次师弟师妹画图时,只需改一行journal=参数,剩下的交给脚本——这才是真正的科研生产力。

最后分享一个血泪教训:去年帮一位生物信息学博士处理单细胞图,他坚持用R的ggplot2,结果因R的PDF设备驱动对Type 1字体支持不佳,连续三次被拒。我让他改用上述Python流程,一天内搞定全部12张图。所以,别迷信工具,规则才是核心,工具只是载体。掌握尺寸与字体的本质逻辑,你用任何软件都能画出SCI-ready的图。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 17:39:01

IT运维驻场服务内容怎么写:从岗位描述到可执行服务契约

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 17:37:49

知识产权交易平台建设方案:数据建模与状态机设计实战

简介&#xff1a;2021借鉴版知识产权交易平台建设方案&#xff0c;是一份面向科技园区管委会、知识产权服务机构、平台建设单位及政策研究者的完整方案资料&#xff0c;针对科技成果转化率低、交易不活跃、科技企业融资难等痛点&#xff0c;给出了系统化解决框架。内容从建设背…

作者头像 李华
网站建设 2026/9/19 17:36:01

用tmux打造按项目管理的终端工作台:告别窗口混乱

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华