使用 CSS 打印时,将内容添加到网页的边缘

发布时间:2024 年 10 月 30 日

从 Chrome 131 开始,您可以使用 CSS 在打印网页时向网页边距添加内容。本文介绍了分页媒体的页面模型,以及如何使用此功能来改进网页的打印输出。

CSS 包含处理分页媒体的规范,即 CSS 分页媒体模块CSS 分页媒体生成的内容。它们定义了仅在打印网页(包括打印为 PDF)时使用的功能。有些 user-agent 支持此 CSS,可让您通过 HTML 和 CSS 生成图书和其他印刷材料。不过,尽管我们经常需要从应用中打印或创建 PDF,但 Web 浏览器从未很好地支持过此功能。

Chrome 和 Firefox 支持 @page at 规则。此规则可让您定义打印到的页面大小以及内容周围的边距大小。从 Chrome 131 开始,您还可以通过定位相关的边距 at-rule,使用生成的内容向边距添加内容。

页面模型

分页媒体中使用的页面模型定义了页面框,即纸张。在页面框内,依次是页面边距页面边框页面内边距,最后是显示内容的页面区域。打印内容时,系统会根据需要将其分成多个页面。

然后,将页面边距拆分为 16 个框,每个框都有一个对应的 @ 规则。

  • @top-left-corner
  • @top-left
  • @top-center
  • @top-right
  • @top-right-corner
  • @left-top
  • @left-middle
  • @left-bottom
  • @right-top
  • @right-middle
  • @right-bottom
  • @bottom-left-corner
  • @bottom-left
  • @bottom-center
  • @bottom-right
  • @bottom-right-corner

边距框大小调整

顶部和底部框的高度以及左侧和右侧框的宽度由使用 @page 设置的边距大小定义。因此,边角框的大小由这些边距的交集决定,是固定的。不过,每个角之间的三个方框是灵活的。它们的行为方式与使用 flex: auto 的弹性布局中的盒子类似,因此它们会拉伸以填充空间,但如果您在一个盒子中放置长文本字符串,而在其他盒子中不放置任何内容,则包含文本的盒子会增长,而不是换行显示文本。

边距中显示了 16 个方框的页面。
页面区域被边距环绕,包含 16 个已命名的边距框。

向边注框添加内容

若要向边距框添加内容,请使用 CSS 生成的内容,就像使用 ::before::after 伪元素一样。在这种情况下,请使用与您要定位的盒子相关的 @ 规则。以下 CSS 会将文字“My book”添加到左下边距框或右侧页面。它还会设置相应文本的样式。

@page :right {
  @bottom-left {  
    content: "My book";  
    font-size: 9pt;  
    color: #333; 
  }
}

除了文本字符串,您还可以向边距添加页数计数器。预定义的 page 计数器包含当前网页。以下 CSS 会将其添加到右侧页面的右下角和左侧页面的左下角。

@page :right {  
  @bottom-right {  
    content: counter(page);  
  }
}

@page :left {
  @bottom-left {
    content: counter(page);
  }
}

还有一个 pages 计数器,始终包含总页数。

使用页边距时的注意事项

如果从浏览器进行打印,浏览器会自动添加一些页边距内容(如果有空间显示)。即使您已添加内容,系统也会执行此操作。您可以在打印对话框中关闭这些自动生成的页眉和页脚。

如果您将网页的边距设置为 0,或者设置为一个非常小的值,以致于没有空间容纳浏览器页眉和页脚,那么它们将不会显示。

由于 Chromium 中存在默认页面布局的概念,如果打印文档的第一页没有空间容纳自动生成的内容,即使后续页面有空间,也会导致浏览器内容无法显示在这些页面上。

分页媒体的未来可能性

分页媒体规范还包含其他多种功能,如需了解详情,请参阅使用 CSS 进行打印设计一文。 如果您有任何使用情形需要用到以下功能,请将其添加到关联的 bug 中。

设置字符串

图书通常会在页边空白处印上当前章节的标题。此标题无法硬编码到 CSS 中,因为随着您阅读本书,此标题会发生变化。借助 string-set 属性,您可以设置 HTML 中的值,然后在生成的内容中使用该值。以下 CSS 假定章节标题标记为 <h1>。它会获取每个 <h1> 的内容,并将其用在右侧页面的右上边距中。当达到下一个 <h1> 时,系统会更新该点之后的边距值。

h1 {
  string-set: doctitle content();
}

@page :right {
  @top-right {
    content: string(doctitle);
    margin: 30pt 0 10pt 0;
    font-size: 8pt;
  }
}

针对 string-setstring() 的 Chromium bug

交叉引用

文档打印后,对其他页面的引用通常会使用可找到引用的页码来表示。您可以使用 target-counter 创建这些交叉引用。当应用于链接时,该链接可用于跳转到网页上的参考内容;打印时,系统会显示页码。

<a class="xref" href="#ref1">my reference</a>
a.xref:after {
  content: " (page " target-counter(attr(href, url), page) ")";
}

交叉引用的 Chromium bug

脚注

脚注也是分页媒体规范的一项功能。在 HTML 中,使用类来标识应作为脚注的文本,例如:

<p>This is some text <span class=”fn”>this is a footnote</span>.</p>

然后使用 floatfootnote 值将此文本转换为脚注。打印文档时,它将从段落中移除,并显示为脚注。

.fn {
  float: footnote;
}

脚注的 Chromium bug