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

发布时间:2024 年 10 月 30 日

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

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

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

页面模型

分页媒体中使用的页面模型定义了页面盒,即一张纸。页面框内包含页边距页边框页边距,最后是用于显示内容的页面区域。内容在打印时会分割成所需的页数,以便容纳内容。

然后,页边距会拆分为 16 个框,每个框都有对应的 at-rule。

  • @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 的 Flex 布局中的盒子类似,因此它们会伸展以填充空间,但如果您在其中一个中放置一个长文本字符串,而在其他中放置任何内容,则包含文本的那个会增大,而不是换行显示文本。

页面边线中显示了 16 个框。
页面区域由边距环绕,其中包含 16 个命名边距框。

向边距框添加内容

如需向边距框添加内容,请使用 CSS 生成的内容,就像使用 ::before::after 伪元素一样。在这种情况下,请使用与要定位的框相关的 at 规则。以下 CSS 会将“我的图书”文本添加到左下角边线框或右侧页面。它还会设置该文本的样式。

@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 错误

脚注

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

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

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

.fn {
  float: footnote;
}

脚注的 Chromium bug