CSS 在网页打印中的最佳实践

CSS 网页打印

本文将为你介绍打印 HTML 页面时相关 CSS 知识的方方面面。

你在 Web 项目中编写一个了页面,该页面会被转换成 PDF 文件;或者,你只是希望你网站现有的页面在打印时有更好的表现(更好看)。

提示:如果你有格式化 CSS 代码的需求,可以使用本站提供的 CSS 代码格式化 工具,一键格式化 CSS 代码,十分方便。

@media 规则

如果你接触过响应式设计,那么,你一定知道 @media 规则。和各种不同的屏幕尺寸一样,@media 规则也支持 “print” 媒体查询。下面是一个例子:

@media print {
  /* 该样式仅用于页面打印时,或保存为 PDF 的时候 */
  h1 { font-size: 16pt; }
}

通过这条规则,你可以像平常一样使用标准的 CSS 代码,然后添加一些仅用于打印的自定义样式。

p { margin: 1em 0; }

@media print {
  /* 打印时隐藏相关文章板块 */
  .related-articles { display: none; }
}

如果你打算从头开始编写正常屏幕下的样式,你可以把针对屏幕的样式代码放在单独的 @media 规则下:

@media screen {
  /* 在这里编写标准样式代码 */
}

@media print {
  /* 在这里编写打印样式代码 */
}

分页属性

为了保证页面间内容的连贯性,你可能希望能够自己控制内容的换页。例如,在页面底部出现巨大的标题就显得很不雅观(你期望的是该标题出现在下一页的开头)。同样地,如果可能的话,你也希望避免一个表格跨越多页。

你可以使用 page-break-beforepage-break-afterpage-break-inside 这几个属性来控制内容的换页。这些属性都支持 alwaysavoid 2 个属性值。

h1 {
  /* 确保 h1 元素总是出现在一页的开头 */
  page-break-before: always;
}

section.city-map {
  /* 该部分内容独占当前页 */
  page-break-before: always;
  page-break-after: always;
}

table {
  /* 避免在多页分割表格内容(如果可能的话) */
  page-break-inside: avoid;
}

技巧:重复表头

如果文档中的表格跨越了多页,在打印时,除非在每一页的开头都带上表头,否则,表格内容将难以阅读。在每一页的开头添加表头是一件很轻松的事,只需在 table 中使用 theadtbody 元素。

<table>
  <thead>
    <tr>
      <th>City</th>
      <th>Population</th>
  </thead>
  <tbody>
    <tr>
      <td>Sydney</td>
      <td>4.627 million (2018)</td>
    </tr>
  </tbody>
</table>

这样,在打印时,表格看上去就像下面这样:

表格跨多页时重复表头
表格跨多页时重复表头

技巧:添加或删除内容

在某些情况下,你可能希望在打印时添加一些内容。比如,打印时一同打印链接的 URL。你可以通过 ::after 伪元素来实现:

@media print {
  a[href]::after {
    content: " (" attr(href) ")";
  }
}

在打印时,你也可能希望隐藏或显示某些元素。结合 @media 媒体查询和 display 属性,可以轻松达成这个目的:

/* 在正常屏幕下隐藏水印 */
.watermark {
  display: none;
}

@media print {
  /* 打印时隐藏导航栏 */
  nav {
    display: hide;
  }

  /* 打印时显示水印 */
  .watermark {
    display: initial;
  }
}

技巧:在开发阶段模拟 CSS 媒体查询

在开发阶段,为了即时预览效果,你可以把浏览器的显示设置为打印媒体类型。对于 Mac 版的 Chrome 浏览器,打开开发者工具,然后按下 command+shift+P 快捷键呼出“运行命令”,输入“模拟 CSS 打印媒体类型”,即可把浏览器切换到打印媒体类型。

在浏览器模拟 CSS 打印媒体
在浏览器模拟 CSS 打印媒体

其他浏览器的开发者工具中应该也有类似的功能。

遗憾的是,必须每次手动打印为 PDF 来观察分页效果。

高级技巧:使用 orphanswidows 属性

orphanswidows 属性用于控制元素中的文本在跨页时如何分割。有时候稍微调整一下这 2 个属性的属性值可极大提升打印文档的可读性。

p {
  /* 在换页前,如果未达到至少 3 行文本的条件,
     p 元素将会被移至下一页显示 */
  orphans: 3;
}

在下图的左边,orphans 属性的值为 2,因此,第二段内容在换页前显示(因为满足 2 行的条件);当把 orphans 设置为 3(下图的右边),第二段内容被强制在下一页才开始显示。

orphans 属性不同取值的效果
orphans 属性不同取值的效果对比

widows 属性的含义和 orphans 恰恰相反:它规定了在新的一页显示时需要的最小行数。

高级技巧:@page 规则

通过使用 @page 规则,你可以为特定的页面指定自定义边距。

@page:first {
  /* 第一页无边距 */
  margin: 0;
}

@page {
  /* 其他页面,边距设置为 2cm */
  margin: 2cm;
}

遗憾的是,浏览器对 @page 的支持非常有限,目前只能使用 :first:last:left:right:blank 这几个伪元素。

总结

现在你已经了解了在页面打印时关于 CSS 的几个重要属性,这些属性都得到了现代浏览器(如:Chrome、Firefox 以及 Safari)的支持。

但是,比较遗憾的是, CSS 对于高级打印布局的支持往往非常有限。例如,浏览器没有提供一种标准的方式利用 CSS 来添加自定义头部和底部。你可以使用 paged.js 提供的功能来弥补浏览器目前不支持的打印特性。

感谢阅读,希望对你有帮助!

分享