CSS:@media print 相關設定

記錄 @media print 功能,即 CSS 針對印表列印(print)的媒體設定。

好文章留存,並記錄關鍵訊息。

關於 @media print 的二三事

先來點題外話

一開始方向在想要怎麼用 javascript 產生出 PDF 文件,方案之一:

  • 使用 html2canvas 將網頁內容轉成 Canvas 畫布(可作為圖像)

  • 使用 jsPDF 建立一個空白 PDF,並將頁面的 Canvas 畫布轉為圖片格式置入,輸出即可下載

  • 補充:也可搭配 Print.js 來送印。

兩種撰寫 @media print 的方式

CSS 檔分為 screen 及 print 兩種模式:

<link href="screen.css" media="screen">
<link href="print.css" media="print">

CSS 多種模式統一寫在一起,屬於列印模式下的設定需用 @media print{} 包住:

body{
  background: #49c;
}
@media print{
  body{
    background: #fff;
  }
}

列印模式-頁面配置(@page)

@page 是列印模式下對頁面配置的特殊屬性,主要可設定頁面的 size, margin , orphans 和 widow。

  • size 可直接指定寬度與高度(搭配單位 mm 或 cm 皆可)、或是通用尺寸( A4、A5.. ),此外可設定頁面的呈現方向( portrait / landscape )

  • margin 就是一般頁面的邊距(常用 word 的人應該不陌生 :D )

  • orphans widow 這印刷術語取名滿妙.., orphans 是指頁面最後一個段落的行數、widow 則是頁面第一個段落的行數,初始值都是2,表示限制頁面頂部及底部的段落不能只顯示一行就被分頁。

@page{
  size: A4 portrait;
  margin: 0.5cm;
  orphans:4;
  widows:2;
}

列印模式-分頁斷點

page-break-after:元素後分頁

page-break-after : auto | always | avoid | left | right

page-break-before:元素前分頁

page-break-before : auto | always | avoid | left | right

page-break-inside:元素本身分頁

page-break-inside : auto | avoid

這三個屬性超重要!!!網頁內容無法預估長度的情況下,很難完美的呈現頁面布局,盡可能做到的就是避免顯示的元素被分頁切割。

下面是收集來的大神設定😋

h1, h2, h3, h4, h5, h6 {
  page-break-after:avoid;
  page-break-inside:avoid
}
h1+p, h2+p, h3+p {
  page-break-before: avoid;
}
a {
  page-break-inside:avoid
}
img{
  page-break-after: avoid;
  page-break-inside: avoid;
}
table, blockquote{
  page-break-inside: avoid;
}
ul, ol, dl {
  page-break-before:avoid;
}
/* 如架構本身用一組一組的 DIV 包住,也可強制設定每組 DIV 會各自切成一頁 */
div.pageBlock{
  page-break-before: always;
}

CSS單位:ptpx

直接下結論,若是用到營幕那就以px為主;若用到列印那就以pt為主。

在html設計字體的css樣式中,有些字體設置成14pt,而不是14px,那pt是什麼,和px又有什麼關係呢?

pt(point)是印刷行業常用的單位,等於1/72英寸,表示絕對長度。

px(pixel)指的是像素,是屏幕上顯示數據的最基本的點,表示相對大小。不同分辨率下相同長度的px元素顯示會不一樣,比如同樣是14px大小的字,在1366x768顯示屏下會顯示的小,在1024x768尺寸的顯示器下會相對大點。

px和pt轉換規則很簡單,默認的顯示設置中把文字定義為96DPI,由公式px=ptDPI/72,可得pt=px3/4。

但一般來說,你會使用不同的單位來在螢幕上顯示或在紙上列印。以下表格提供了推薦的用法:

推薦
偶爾使用
不推薦

螢幕

px, em, %

ex

pt, cm, mm, in, pc

列印

pt, em, cm, mm, in, pc, %

px, ex

CSS單位:EM, PX, PT,CM, IN
CSS單位:pt,px

其他通用設定

  • 字體大小的單位建議改成 pt 以符合印刷設定

  • 非必要列印的內容( nav、 video.. )就設 display: none

  • img 寬度設為 max-width: 100%

  • 容器寬度改為 100%、取消浮動、margin: 0

  • 顯示 a 連結的網址於畫面

  • 如屬性設定後沒反應,表示樣式的優先權不夠,那就招喚 !important 出場吧

header nav, footer, video, audio, object, embed {
  display: none;
}
body{
  width: 100%;
  margin: 0;
  float: none;
  line-height: 1.5;
  font-size: 12pt;
}
img {
  max-width: 100%;
}
a:link, a:visited, a {
  background: transparent;
  color: #222;
  font-weight: bold;
  text-decoration: underline;
  text-align: left;
  word-wrap: break-word; /*避免網址過長超出頁面*/
}
a[href^="http://"]:after, a[href^="https://"]:after {
  content: " (" attr(href) ") ";
}
thead{
  display: table-header-group; /* 表格即使分頁也會顯示表頭 */
}

為了列印 PDF 的特殊設定

因 chrome 列印模式下會清除部分樣式讓畫面變簡潔。下面指令可以強制設定列印模式時依然顯示背景圖的屬性:

body{
  -webkit-print-color-adjust: exact;
  background-image: url('...') !important; 
  /*如果背景圖沒顯示請加必殺技 !important*/
}

工作紀錄

之前的工作紀錄,事後檢查指令應該不是正確的指令,不過有作用並符合當時需求…所以就這樣了吧。

/* A4 size: 297mm x 210mm */
.page {
  page-break-before: always;
  display: block;
  position: relative;
  box-sizing: border-box;
  margin-left: auto;
  margin-right: auto;
  font-size: 12pt;
  height: 344mm;
  /*outline: dashed 2px red; */ /* 開發模式:顯示邊界 */
}

@media screen {
  .page {
    width: 228mm;  /* 開發模式:在螢幕栻式模擬紙張寬度 */
    height: 444mm; /* 開發模式:在螢幕栻式模擬紙張長度 */
  }
}

Last updated