2026/04/13

CSS @pageルール完全ガイド|PDF用紙サイズ・余白・ヘッダー設定

CSS@pagePDF生成レイアウト

HTMLからPDFを生成するとき、用紙サイズや余白、ヘッダー・フッターの配置はどうやって制御するのか。その答えがCSS @page ルールです。

@page はCSS Paged Mediaモジュールの中核で、印刷やPDF出力に特化したスタイル指定ができます。この記事では @page の基本構文からページ擬似クラス、名前付きページ、マージンボックスまで、PDF生成に必要な知識を体系的に解説します。

FUNBREW PDFのPlaygroundを使えば、この記事のコード例をすぐに試せます。

@page の基本構文

@page ルールは、ページ全体に適用されるスタイルを定義します。最もよく使うのは sizemargin です。

用紙サイズの指定

/* A4縦 */
@page {
  size: A4;
}

/* A4横(landscape) */
@page {
  size: A4 landscape;
}

/* 具体的なサイズを指定 */
@page {
  size: 210mm 297mm;
}

/* レター(US Letter) */
@page {
  size: letter;
}

size プロパティで使えるキーワードは A3, A4, A5, B4, B5, letter, legal などです。幅と高さを直接 mm, cm, in で指定することもできます。

余白(margin)の設定

@page {
  size: A4;
  margin: 20mm;
}

/* 上下左右を個別に設定 */
@page {
  size: A4;
  margin: 25mm 20mm 30mm 20mm; /* 上 右 下 左 */
}

余白の設定はPDFのレイアウトに大きく影響します。請求書なら上下左右20mm程度、レポートなら上下25mm・左右20mmが一般的です。

ヒント: @pagemargin はHTML要素の margin とは独立しています。ページ余白の内側にコンテンツ領域が作られ、その中で通常のCSSが適用されます。

ページ擬似クラス ― :first, :left, :right, :blank

@page にはページの種類に応じたスタイルを適用できる擬似クラスがあります。

:first ― 最初のページだけ別レイアウト

表紙や請求書のヘッダー部分を特別扱いしたい場合に使います。

/* 全ページの基本設定 */
@page {
  size: A4;
  margin: 25mm 20mm;
}

/* 表紙は余白を大きく */
@page :first {
  margin: 40mm 30mm;
}

:left / :right ― 見開き(左右)ページ

冊子や書籍のように、左ページと右ページで余白を変えたいときに使います。

/* 左ページ(偶数) */
@page :left {
  margin-left: 30mm;
  margin-right: 20mm;
}

/* 右ページ(奇数) */
@page :right {
  margin-left: 20mm;
  margin-right: 30mm;
}

綴じ代(のどの余白)を確保するために内側の余白を広くとるのが一般的です。

:blank ― 空白ページ

break-before: leftbreak-before: right によって挿入された空白ページに適用されます。

@page :blank {
  @top-center {
    content: ""; /* ヘッダーを非表示 */
  }
}

名前付きページ ― 1つのドキュメントに複数レイアウト

page プロパティを使うと、要素ごとに異なるページ設定を割り当てられます。

/* 表紙用のページ定義 */
@page cover {
  size: A4;
  margin: 0;
}

/* 本文用のページ定義 */
@page content {
  size: A4;
  margin: 25mm 20mm;
}

/* 横向きの図表ページ */
@page landscape-chart {
  size: A4 landscape;
  margin: 15mm;
}

HTMLからは page プロパティで指定します。

.cover-page {
  page: cover;
}

.main-content {
  page: content;
}

.chart-section {
  page: landscape-chart;
}
<div class="cover-page">
  <h1>年次レポート 2026</h1>
</div>
<div class="main-content">
  <h2>第1章 概要</h2>
  <p>...</p>
</div>
<div class="chart-section">
  <img src="chart.png" alt="売上推移" />
</div>

名前付きページを使うと、表紙は余白なし、本文はA4縦、図表ページはA4横、というように1つのHTMLから複数のレイアウトを持つPDFを生成できます。

マージンボックス ― ヘッダー・フッター・ページ番号

@page ルールの中にマージンボックスを定義すると、ページの余白領域にコンテンツを配置できます。これがPDFのヘッダーやフッター、ページ番号を実現する仕組みです。

マージンボックスの位置

@top-left    @top-center    @top-right
┌──────────────────────────────────────┐
│                                      │
@left-top                    @right-top
│                                      │
@left-middle               @right-middle
│           コンテンツ領域             │
@left-bottom              @right-bottom
│                                      │
└──────────────────────────────────────┘
@bottom-left @bottom-center @bottom-right

全部で16箇所のマージンボックスが定義されています。

ページ番号の追加

@page {
  size: A4;
  margin: 25mm 20mm 30mm 20mm;

  @bottom-center {
    content: counter(page);
    font-size: 10pt;
    color: #666;
  }
}

/* 「3 / 12」形式 */
@page {
  @bottom-right {
    content: counter(page) " / " counter(pages);
    font-size: 9pt;
  }
}

counter(page) は現在のページ番号、counter(pages) は総ページ数を返します。

ヘッダーとフッターの例

@page {
  size: A4;
  margin: 30mm 20mm 25mm 20mm;

  @top-left {
    content: "株式会社サンプル";
    font-size: 8pt;
    color: #999;
  }

  @top-right {
    content: "社外秘";
    font-size: 8pt;
    color: #c00;
    font-weight: bold;
  }

  @bottom-left {
    content: "2026年4月発行";
    font-size: 8pt;
    color: #999;
  }

  @bottom-right {
    content: counter(page) " / " counter(pages);
    font-size: 8pt;
  }
}

/* 表紙にはヘッダー・フッターを出さない */
@page :first {
  @top-left { content: ""; }
  @top-right { content: ""; }
  @bottom-left { content: ""; }
  @bottom-right { content: ""; }
}

実践例 ― 表紙付き請求書

ここまでの知識を組み合わせて、表紙付きの請求書PDFを作ってみましょう。

/* === ページ設定 === */
@page {
  size: A4;
  margin: 20mm;

  @bottom-center {
    content: counter(page);
    font-size: 9pt;
    color: #888;
  }
}

@page cover {
  margin: 0;
  @bottom-center { content: ""; }
}

@page :first {
  @bottom-center { content: ""; }
}

/* === レイアウト === */
body {
  font-family: "Noto Sans JP", sans-serif;
  font-size: 10pt;
  line-height: 1.6;
  color: #333;
}

.cover {
  page: cover;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background: linear-gradient(135deg, #1a365d, #2563eb);
  color: #fff;
  text-align: center;
}

.cover h1 {
  font-size: 28pt;
  margin-bottom: 10mm;
}

/* 明細テーブル */
.invoice-table {
  width: 100%;
  border-collapse: collapse;
  break-inside: avoid;
}

.invoice-table th,
.invoice-table td {
  border: 1px solid #ddd;
  padding: 8px 12px;
}

.invoice-table th {
  background: #f5f5f5;
  text-align: left;
}

/* 合計行 */
.total-row {
  font-weight: bold;
  font-size: 12pt;
  break-before: avoid;
}
<div class="cover">
  <div>
    <h1>請求書</h1>
    <p>2026年4月度</p>
  </div>
</div>

<section class="invoice-body">
  <h2>ご請求明細</h2>
  <table class="invoice-table">
    <thead>
      <tr>
        <th>項目</th>
        <th>数量</th>
        <th>単価</th>
        <th>金額</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>PDF生成API(Standardプラン)</td><td>1</td><td>¥5,000</td><td>¥5,000</td></tr>
      <tr><td>追加リクエスト(100件)</td><td>2</td><td>¥1,000</td><td>¥2,000</td></tr>
    </tbody>
    <tfoot>
      <tr class="total-row"><td colspan="3">合計(税込)</td><td>¥7,700</td></tr>
    </tfoot>
  </table>
</section>

このHTMLとCSSをFUNBREW PDFのAPIに送信すれば、表紙付きの請求書PDFが生成されます。

複数セクションレポートの例

レポートのように、表紙・目次・本文・付録でレイアウトを変えたい場合の例です。

@page cover {
  size: A4;
  margin: 0;
}

@page toc {
  size: A4;
  margin: 30mm 25mm;
  @top-center {
    content: "目次";
    font-size: 9pt;
    color: #666;
  }
}

@page main {
  size: A4;
  margin: 25mm 20mm;
  @top-left {
    content: "月次レポート";
    font-size: 9pt;
    color: #666;
  }
  @bottom-right {
    content: counter(page);
    font-size: 9pt;
  }
}

@page appendix {
  size: A4 landscape;
  margin: 15mm;
  @bottom-center {
    content: "付録 - " counter(page);
    font-size: 8pt;
  }
}

.cover    { page: cover; }
.toc      { page: toc; }
.main     { page: main; }
.appendix { page: appendix; }

エンジンによる互換性の違い

@page ルールのサポート状況は、PDF生成エンジンによって大きく異なります。

機能 Chromium (Headless) wkhtmltopdf
size △(一部)
margin
:first ×
:left / :right ×
名前付きページ ×
マージンボックス △(部分的) ×
counter(page) ×
counter(pages) ×

Chromium ベースのエンジン

Chromium(Puppeteer、Playwright、FUNBREW PDFが使用)は @page の基本プロパティを幅広くサポートしています。ただし、マージンボックスのサポートは完全ではなく、Chrome 131以降で段階的に改善されています。

注意点: Chromiumの page.pdf()formatmargin オプションを指定すると、CSSの @page 設定が上書きされることがあります。@page で制御する場合は、API側のオプションを省略するか preferCSSPageSize: true を設定してください。

wkhtmltopdf

wkhtmltopdfはWebKitベースの古いエンジンで、@page のサポートは限定的です。size--page-size コマンドラインオプション、ヘッダー・フッターは --header-html / --footer-html オプションで代替するのが一般的です。

エンジンの違いについて詳しくは「wkhtmltopdf vs Chromium 徹底比較」をご覧ください。

よくある間違いと対処法

1. 余白が二重になる

/* NG: @page の margin と body の margin が加算される */
@page { margin: 20mm; }
body { margin: 20mm; }

/* OK: body の margin をリセット */
@page { margin: 20mm; }
body { margin: 0; padding: 0; }

@pagemargin がページ余白を確保するので、body に追加の margin を設定すると二重になります。

2. size が効かない

Chromiumベースのエンジンでは、APIの format オプションが @page { size } より優先されることがあります。

// NG: format 指定が @page を上書き
await page.pdf({ format: 'A4' });

// OK: CSS の @page に制御を任せる
await page.pdf({ preferCSSPageSize: true });

FUNBREW PDFでは、リクエストパラメータで preferCSSPageSize を指定できます。詳細はAPIドキュメントを確認してください。

3. ヘッダー・フッターが表示されない

マージンボックスはまだブラウザのサポートが限定的です。表示されない場合は以下の代替手段を検討してください。

/* 代替: position: fixed でヘッダー・フッターを実現 */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 15mm;
  font-size: 8pt;
  color: #999;
  border-bottom: 0.5pt solid #ddd;
}

.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 10mm;
  font-size: 8pt;
  text-align: center;
  color: #999;
}

@page {
  margin-top: 25mm;  /* ヘッダー分の余白を確保 */
  margin-bottom: 20mm; /* フッター分の余白を確保 */
}

position: fixed はChromiumで安定して動作し、すべてのページに繰り返し表示されます。

4. 名前付きページで改ページされない

名前付きページを切り替える要素は、フローの中で兄弟要素である必要があります。

<!-- NG: ネストされていると改ページが発生しないことがある -->
<div class="wrapper">
  <div class="cover-page">...</div>
  <div class="main-content">...</div>
</div>

<!-- OK: トップレベルで並べる -->
<div class="cover-page">...</div>
<div class="main-content">...</div>

まとめ

CSS @page ルールは、PDFの物理的なページを制御するための専用仕様です。

  • 基本: size で用紙サイズ、margin で余白を設定
  • 擬似クラス: :first, :left, :right でページごとに異なるスタイルを適用
  • 名前付きページ: 1つのドキュメント内でレイアウトを切り替え
  • マージンボックス: ヘッダー・フッター・ページ番号をCSS で配置

Chromiumベースのエンジンなら @page の主要機能がサポートされているため、CSSだけで高度なPDFレイアウトが実現できます。実際のCSSを試すにはPlaygroundが便利です。

PDFのCSS設計全般については「HTML→PDF CSS設計テクニック集」、PDF生成の全体像については「HTML to PDF完全ガイド」も参考にしてください。問題が起きた場合は「PDF生成トラブルシューティング」をご覧ください。

Powered by FUNBREW PDF