把技术文章保存为 PDF,不能只看第一页是否整齐。侧栏会占掉正文宽度,深色代码块可能耗墨,屏幕上可以横向滚动的长行,到了纸上也可能被截断。打印样式应先保证标题、正文、代码和引用完整,再考虑装饰。

先确认主题已有的能力

Waxy 已内置独立的 waxy-print.css,通过 media="print" 加载。打印时会隐藏导航、侧栏、Hero 和全站背景,正文展开为单栏;无论当前使用亮色还是暗色模式,纸面都采用黑字白底。代码块允许长行折行,图片限制在可打印区域内,主题收缩框也会自动展开。

下面的片段用来说明实现思路,文章中的代码不会自动修改本站样式,也不必再复制一遍才能启用打印。需要调整时,可在主题打印样式基础上定制。@media print 只影响打印与 PDF 输出,普通浏览界面保留原样。

@media print {
  .site-header, .layout__sidebar, .post-nav, .site-footer,
  .waxy-drawer, .waxy-drawer-overlay,
  .waxy-toc-float-btn, .waxy-toc-float-panel,
  #back-to-top, #waxy-navigation-progress,
  #waxy-site-background, #loading,
  .post-content .toolbar { display: none !important; }

  html, body, .post { background: #fff !important; }
  .post__title, .post-meta,
  .post-content, .post-content * {
    color: #111 !important;
    background: transparent !important;
    text-shadow: none !important;
  }
  html, body, .layout, .layout__main, .post {
    overflow: visible !important;
    max-height: none !important;
  }
  .layout { display: block; max-width: none; padding: 0; }
  .post { margin: 0; padding: 0; box-shadow: none; }
  .post__head--has-bg { margin: 0; padding: 0; }
  .post__head--has-bg::before { display: none; }
}

这里使用了主题实际的选择器。.post 原本会隐藏溢出内容,.layout 是双栏网格;只写一个 article { width: 100%; } 并不能解除这些约束。封面还带有负边距、顶部留白与伪元素背景,需要一起复位,否则可能留下空白大块,甚至把标题裁到页面外。

黑字白底是便于检查的基础方案,不代表所有语法颜色都必须删除。若要保留少量颜色,可缩小上面文字规则的范围,但不要让信息只靠浅色背景区分;浏览器关闭“背景图形”后,警告文字仍应读得清楚。

长代码需要换行,图片需要限宽

横向滚动条不会给纸张增加宽度。下面让代码保留换行与缩进,同时允许过长的单行折行;纸面先隐藏行号,避免屏幕上的行号高度与折行后的代码错位。

@media print {
  .post-content pre,
  .post-content pre code {
    white-space: pre-wrap !important;
    overflow-wrap: anywhere;
  }
  .post-content pre {
    overflow: visible !important;
    max-height: none !important;
    padding: 10pt !important;
    border: 1px solid #bbb;
  }
  .post-content .line-numbers-rows { display: none; }
  .post-content img {
    max-width: 100%;
    height: auto !important;
    filter: none !important;
  }
}

不要把所有代码块都设为禁止分页。短例子可以尽量放在同一页,超过一页的程序则应允许自然延续。特别宽的表格也不能靠缩小到极小字号解决,必要时改用横向纸张,或拆成两张表;调整后仍要检查列标题与内容是否对应。

让链接在纸上留下线索

纸张不能点击,给外部参考链接补上地址会更有用。规则仍要放在打印媒体中,避免普通浏览时每个链接后面都多出一串 URL。

@media print {
  .post__content a[href^="http"]:not([data-lightbox])::after {
    content: " (" attr(href) ")";
    font-size: 90%;
    overflow-wrap: anywhere;
  }
}

这个例子只补充绝对 HTTP/HTTPS 地址,并跳过灯箱图片链接。attr(href) 读取的是属性原值,不会把 /archives/2962/ 自动补成完整域名,也不会展开短链接的最终目的地。若纸面必须带上站内文章地址,可以在源稿中使用完整地址,或在构建阶段统一处理。

分页规则是约束,不是保证

@page 可设置页边距;纸张尺寸与方向仍可交给打印对话框选择。标题尽量不要孤零零地落在页尾,段落则保留几行上下文:

@page { margin: 16mm; }

@media print {
  .post-content h2, .post-content h3 { break-after: avoid-page; }
  .post-content p { orphans: 3; widows: 3; }
  .post-content img, .post-content tr { break-inside: avoid; }
}

break-inside: avoid 是尽量避免在盒子内部断开。元素本身比一页还高时,浏览器仍需寻找分页方式,所以不要把整篇文章或整个长表格包成不可拆分的大块。大图若超过一页高度,也应单独缩小或选用更合适的纸张。

最后用保存 PDF 预览验收

从文章页打开浏览器打印,先选择“保存为 PDF”,确认纸张、缩放与页边距,再逐页查看。至少检查长代码的右边缘、图片下方、表格跨页处、标题前后,以及文章最后一页。浏览器附加的日期、网址和页码通常由打印对话框里的页眉页脚选项控制,不能只靠正文 CSS 判断。

还应分别从浅色和深色模式进入预览,切换一次“背景图形”,确认正文不会变成白字白底,封面和浮层也没有遮住内容。PDF 预览能发现多数排版问题,但不等同于实际打印机的出纸验证;换浏览器、纸张或打印设置后仍应重新看一遍。

音视频播放器也不能当作纸面内容的替代。文章若把关键步骤放在视频中,最好同时提供文字步骤、封面说明和可访问的链接。这样即使读者只拿到一份离线打印件,也能知道媒体讲了什么、之后到哪里继续查看,而不是面对一个没有作用的播放按钮。

屏幕阅读的基础样式见正文排版,折叠块和提示框的用法见短代码引擎。主题自己的收缩框会在打印时展开;若文章嵌入第三方交互组件,仍应在打印预览中确认内容完整。