对于有打印需求的网页,特别是文章的详情页,需要设置专门的打印样式来适配页面。CSS 打印样式允许你为网页设置专门用于打印的样式。文本就是专门介绍如何使用 CSS 打印样式为 Web 页面设置专业的打印机效果。

@media print

通过使用 @media print 媒体查询,你可以定义打印时使用的CSS规则。声明打印样式有两种方法:

使用 @media print 的媒体查询

@media print {
    .no-print {
        display: none;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

在 style 或者 link 标签使用 media=print 属性

<style media="print">...</style> 
<link rel="stylesheet" media="print" />
  • 1.
  • 2.

CSS 打印样式常见技巧

以下是一些常见的 CSS 打印样式设置的技巧:

隐藏不必要的内容

在打印时,一般都只需要显示页面中的正文内容,因此需要隐藏导航栏、广告等不需要打印的元素。

@media print {
    .no-print {
        display: none;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

设置打印友好的字体和颜色

打印机的显示和 Web 页面的显示还是有一定区别的。要知道,不是所有的浏览器默认的背景颜色都是白色,默认的字体颜色是黑色的。设置打样样式是需要使用简单的字体和明确指定白背景色和黑色文字颜色来确保打印的清晰度。

@media print {
    body {
        font-family: Arial, sans-serif;
        color: #000;
        background: #fff;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

!important 确保浏览器采用 print 的样式

上面的实例代码中都使用了 !important,这是因为在设置 print 的样式时,普通 Web 页面通用样式的层叠,可能会导致打印样式失效,这时需要特别采用 !important 来确保浏览器采用print下面的样式,例如:

@media print {
  .outline {
    &-message,
    &-toolbar {
      /* 隐藏不必要的内容 */  
      display: none !important;
    }
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

字体大小

在CSS打印样式中设置字体大小时,有几个关键点和建议可以帮助你确保打印输出的可读性和一致性。

使用相对单位

如果你的 Web 页面使用的是相对单位(如em、rem、%)。那么打印样式也应该保持一致,基础字体设置绝对大小,其它均用相对单位,可以使字体大小相对于父元素或根元素调整,确保打印时的比例一致。

@media print {
  body {
      /* 基础字体大小使用绝对值 */
      font-size: 12pt !important; 
  }
  
  h1 {
     /* 继承自body的2倍字体大小 */
      font-size: 2em !important; 
  }
  
  p {
      /* 与body相同的字体大小 */
      font-size: 1em !important; 
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

使用绝对单位

如果你的 Web 页面使用的是绝对单位(如px、in、cm),那么打印样设置时要使用 pt 单位设置基础文字大小,pt 值和 px 值要最好相等,以确保打印时的字体大小固定,不受屏幕大小或其他因素的影响。

@media print {
    /* 全局字体大小 */
    body {
         
    }
    
    /* 标题字体大小 */
    h1 {
        font-size: 14pt; 
    }
    
    /* 段落字体大小 */
    p {
         
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

pt 和 px 的关系

使用绝对值的时候,pt 的值怎么才能跟 Web 页面中的 px 对应呢?例如前文中希望在打印样式中使用的字体大小的绝对值与 Web 中的字体大小保持一致,要如何换算呢?

在 CSS中,pt(点)和 px(像素)是常用的单位,用于设置字体大小和其他尺寸。计算它们之间的转换可以帮助你在不同的环境中保持一致的样式。

标准屏幕分辨率(96 DPI)

1pt = 1/72 英寸

1英寸 = 96 像素

因此,1pt = 96/72 像素 ≈ 1.333px

公式

从pt转换为px:px = pt * 96 / 72

从px转换为pt:pt = px * 72 / 96

从 pt 转换为 px

12pt 转换为 px:12 * 96 / 72 = 16px

14px 转换为 px:10 * 96 / 72 ≈ 13.33px

从 px 转换为 pt

16px 转换为 pt:16 * 72 / 96 = 12pt

14px 转换为 pt:14 * 72 / 96 ≈ 14px

顺便说一下,设置打印样式的字体大小时,推荐的单位是 pt。

调整布局

在设置打印样式,由于受到打印显示区域的宽度显示,无法向 Web 页面那样在一个很宽的区域显示内容,在打印预览时很多除浮动和固定定位的内容会换行或者显示不正常。这是就需要调整布局,移除浮动和固定定位,使内容在打印时更加整齐。

@media print {
    .float-element {
        float: none !important;
    }
    .fixed-element {
        position: static !important;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

分页

控制分页符的位置,避免内容在打印时被不合理地分割。例如:

@media print {
  .page-break {
      /* 在元素之前插入分页符 */
      page-break-before: always !important; 
      /* 避免在元素内部插入分页符 */
      page-break-inside: avoid !important; 
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

需要说明的是,这个分页控制需要根据特定的页面内容来设置。不是一个通用的设置技巧,并且根据我的个人实践来说,一般都不会特意设置分页控制的打印样式。

链接和媒体处理

打印界面是无法显示 Web 页面中的视频和音频信息的,因此需要隐藏视频、音频等无法打印的媒体元素,并显示链接的 URL。

@media print {
  a:after {
      /* 技巧1:在链接文字后显示 URL 地址 */
      content: " (" attr(href) ")";
  }
  /* 技巧2:在链接文字显示下划线和高亮色显示 */
  a:link,
  a:visited:
  a:hover {
     text-decoration: underline;
     color: #507afe;      
  }
  video, audio {
      display: none !important;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

说明:bootstrap 之类的 CSS 库也会有一些打印样式的设置,如果你的 Web 页面使用第三方库的,需要看看打印效果。例如 bootstrap 就设置技巧1那样的额外显示 URL 地址的链接文字,如果你不需要,需要这样覆盖:

@media print {
  a:after {
      /* 技巧1:在链接文字后显示 URL 地址 */
      content: "" !important;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

表格打印优化

确保表格在打印时的边框和对齐方式清晰。

@media print {
  table {
      width: 100%;
      border-collapse: collapse;
  }
  th, td {
      border: 1px solid #000;
      padding: 8px;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

页眉和页脚

如果希望打印时显示页面的相关信息,还可以在打印样式中为每页添加页眉和页脚,用以显示标题、页码等信息,并且还可以设置打印的页边距。

@media print {
  @page {
    /* 设置打印的页边距 */
    /* 设置内容的上下边距,以避免页眉和页脚覆盖内容 */
    margin: 1in;
    
    /* 其它可选位置:@top-left @top-right */
    @top-center {
        /* 页眉左侧显示标题 */
        content: "Document Title"
    }
    
    /* 其它可选位置:@bottom-left @bottom-right */
    @bottom-center {
        /* 页脚右侧显示页码 */
        content: "Page "counter(page) " of "counter(pages); 
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

CSS 打印样式的应用实践

这里还是以我的 outline.js 项目为例,以下是使用了 outline.js 页面的原始界面:

使用 CSS 打印样式为 Web 页面设置专业的打印机效果_Web

这个是打印预览界面:

使用 CSS 打印样式为 Web 页面设置专业的打印机效果_网络_02

前文介绍的主要的打印页面的技巧在 outline.js 中基本都用到了。以下是完整的打印样式代码:

@media print {
  html,
  body {
    /* 打印的基础字体大小 */
    font-size: 12pt;
    /* 显示设置文字颜色和背景颜色 */
    background-color: @white;
    color: @primary_text_color;
    height: initial !important;
  }
  /* 设置链接样式 */
  a:link,
  a:visited,
  a:hover {
    text-decoration: underline !important;
    color: @primary_color;
  }
  /* 隐藏媒体标签 */
  video,
  audio {
    display: none !important;
  }
  /* 确保表格在打印时的边框和对齐方式清晰 */
  table {
    width: 100%;
    border-collapse: collapse;
  }
  th,
  td {
    border: 1px solid @primary_border_color;
    padding: 8px 20px;
  }
  .outline {
    &-message,
    &-toolbar {
      /* 隐藏了工具栏和信息提示框 */
      display: none !important;
    }
    &-reader {
      display: block !important;
      overflow: hidden;
      &__title {
        margin: 13.4pt 0 28pt !important;
        text-align: center !important;
        font-size: 32pt !important;
      }
      /* 取消了绝对定位 */
      &--reading {
        position: relative !important;
        height: auto !important;
        padding: 0 !important;
        background-color: @white;
        overflow: hidden !important;
      }
      /* 隐藏阅读进度条 */
      &__progress {
        display: none !important;
      }
      /* 打印时不显示正文 DOM 的阴影效果 */
      &__paper {
        box-shadow: none;
      }
      pre {
        padding: 1em !important;
        border: 1px solid @border_color !important;
        border-radius: 4px !important;
      }
      pre,
      code {
        background-color: @white !important;
      }
      table,
      img,
      svg {
        break-inside: avoid;
      }
      /* 所有文章内容 DOM 相关的邻居节点都隐藏了 */
      &_sibling {
        display: none !important;
      }
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.

设置打印样式的基础字体大小和文字和背景颜色:

@media print {
  html,
  body {
    /* 打印的基础字体大小 */
    font-size: 12pt;
    /* 显示设置文字颜色和背景颜色 */
    background-color: @white;
    color: @primary_text_color;
    height: initial !important;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

设置链接文字高亮显示

@media print {
  /* 设置链接样式 */
  a:link,
  a:visited,
  a:hover {
    text-decoration: underline !important;
    color: @primary_color;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

隐藏媒体标签(内容)

@media print {
  /* 隐藏媒体标签 */
  video,
  audio {
    display: none !important;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

确保表格在打印时的边框和对齐方式清晰

@media print {
  /* 确保表格在打印时的边框和对齐方式清晰 */
  table {
    width: 100%;
    border-collapse: collapse;
  }
  th,
  td {
    border: 1px solid @primary_border_color;
    padding: 8px 20px;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

隐藏了非正文 DOM 的所有其他内容

@media print {
  .outline {
    &-message,
    &-toolbar {
      /* 隐藏了工具栏和信息提示框 */
      display: none !important;
    }
    
    /* 隐藏阅读进度条 */
    &__progress {
      display: none !important;
    }
    
    /* 所有文章内容 DOM 相关的邻居节点都隐藏了 */
    &_sibling {
      display: none !important;
    }
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.