はじめに
ページメディアには、長い印刷本の歴史の中で発展してきた特有の要件が数多くあります。ランニングヘッダーやフッターはナビゲーションの補助として機能します。ノートは脚注としてページ下部に表示されることがあります。ページ自体の特性は、その内容や文書内の位置によって変化する場合があります。リーダーは関連する内容を視覚的につなげます。相互参照には生成されたテキストが必要となることがあります。PDFのような一部のページメディア形式では、ナビゲーションのためにブックマークが使用されます。
このモジュールはこれらの技術をページメディアで利用できるよう、新しいプロパティと値を定義します。
値の定義
この仕様は、CSSプロパティ定義の慣例([CSS21])と、値定義シンタックス([CSS-VALUES-3])に従っています。 この仕様で定義されていない値型はCSS Values & Units [CSS-VALUES-3]で定義されています。 他のCSSモジュールと組み合わせて、これらの値型の定義が拡張される場合があります。
各プロパティ定義に記載されている固有値に加え、 この仕様で定義されるすべてのプロパティは CSS全体キーワードもプロパティ値として受け入れます。 可読性のため、ここでは繰り返し記載していません。
1. ランニングヘッダーとフッター
[CSS3PAGE] では、ランニングヘッダーやフッターに使用できる16個のページマージンボックスについて説明されていますが、それらのボックスにコンテンツを挿入する仕組みは記載されていません。このモジュールでは、2つの方法を提供します。名前付き文字列は、テキストをマージンボックスで再利用するためにコピーします。ランニング要素は、要素(スタイルや構造を含む)を文書からマージンボックスへ移動します。1.1. 名前付き文字列
string-setプロパティは、要素のテキストコンテンツを名前付き文字列としてコピーし、変数のように機能します。この名前付き文字列のテキストコンテンツは、string()関数を用いて取得できます。これらの変数はページごとに変化する可能性があるため、string()関数の第2引数で、どの値をページで使うか指定できます。1.1.1. string-setプロパティ
| Name: | string-set |
|---|---|
| Value: | [ <custom-ident> <content-list> ]# | none |
| Initial: | none |
| Applies to: | 全ての要素。ただし疑似要素は対象外 |
| Inherited: | no |
| Percentages: | N/A |
| Computed value: | 指定値 |
| Canonical order: | 文法順 |
| Animation type: | 離散 |
ユーザーエージェントは、非ビジュアルを含むすべてのメディアでこのプロパティをサポートすることが期待されます。
string-setプロパティは、カスタム識別子(名前付き文字列の名前)と<content-list>のペアからなり、名前付き文字列の値の構成方法を記述します。
<content-list>は、以下の値のいずれか1つ以上に展開されます。順序は任意です。
<content-list> = [ <string> | <counter()> | <counters()> | <content()> | <attr()> ]+
- <string>
- 文字列。[CSS21]で定義。
- <counter()>
- counter()関数。[CSS21]で記載。
- <counters()>
- counters()関数。[CSS21]で記載。
- <content()>
- 下記で解説されるcontent()関数。
- <attr()>
- attr()関数。[CSS-VALUES-3]で定義。
1.1.1.1. content()関数
content() = content([text | before | after | first-letter ])
- text
- 要素の文字列値。
white-space: normalが設定されたかのように取得。デフォルト値です。 - before
::before疑似要素の文字列値。white-space: normalが設定されたかのように取得。- after
::after疑似要素の文字列値。white-space: normalが設定されたかのように取得。- first-letter
- 要素の最初の文字。
::first-letter疑似要素で定義。
名前付き文字列の内容値は、その要素のコンテンツボックスが最初に作成された時点(またはdisplay値がnoneの場合でも作成されるはずだった時点)で割り当てられます。ページのエントリ値は前ページ終了時点の割り当て、エグジット値は現ページ終了時点の割り当てです。
要素の値が変化すると、名前付き文字列の値も更新されます。ユーザーエージェントは名前付き文字列の多数の値を記憶できなければなりません。string()関数は、過去・現在・未来の割り当て値を返すことができます。
HTML:
<h1>Loomings</h1>
CSS:
h1::before { content: 'Chapter ' counter(chapter); }
h1 { string-set: header content(before) ':' content(text); }
h1::after { content: '.'; }
「header」という名前付き文字列の値は “Chapter 1: Loomings” になります。
<section title="Loomings">
CSS:
section { string-set: header attr(title) }
「header」文字列の値は “Loomings” になります。
1.1.2. string()関数
string()関数は、contentプロパティを介して、名前付き文字列の値を文書にコピーするために使用します。この関数には、名前付き文字列の名前を指定する引数が1つ必要です。名前付き文字列の値はページ内で(新しい要素が現れるたびに)何度も変化する可能性があるため、第2引数でどの値を使うか指定できます。string()関数の第2引数には、以下のキーワードのいずれかを指定します:
- first
- ページ上で最初に割り当てられた値を使用します。ページ内に割り当てがない場合はエントリ値を使います。
firstがデフォルト値です。 - start
- 要素がページ先頭の場合は最初の割り当て値、そうでない場合はエントリ値を使用。要素がまだ現れていない場合、エントリ値は空になることがあります。
- last
- 名前付き文字列のエグジット値を使います。
- first-except
firstと同じですが、値が割り当てられたページでは空文字列を使います。
@page {
size: 15cm 10cm;
margin: 1.5cm;
@top-left {
content: "first: " string(heading, first);
}
@top-center {
content: "start: " string(heading, start);
}
@top-right {
content: "last: " string(heading, last);
}
}
h2 { string-set: heading content() }
下図は、様々なページにおける「heading」文字列のfirst、start、lastの割り当て例です。
1.2. ランニング要素
多くのヘッダーやフッターは、整形されていないテキストだけでは表現できません。例えば、ランニングヘッドとして本のタイトルが使われる場合、その中にイタリック体の語が含まれる場合もあります。要素をマージンボックス内に移動・コピーする仕組みが必要です。そのために、positionプロパティにrunning()値を、contentプロパティにelement()値を追加します。@page {
@top { content: element(header); }
}
h1 { position: running(header); }
この例では、h1要素が@topマージンボックスに、スタイルや子孫要素も含めて配置されます。通常の文書フローには表示されません。
1.2.1. running()値
position: running(custom-ident)は、その要素(および関連する::before, ::after疑似要素)を通常のフローから取り除き、element()を用いてページマージンボックスに配置できるようにします。要素は文書内の元の位置から継承されますが、そこには表示されません。
| Name: | position |
|---|---|
| New values: | <running()> |
running() = running( <custom-ident> )
HTML:
<p class="rh"><i>Miranda v. Arizona</i> in Context</p> <h2><i>Miranda v. Arizona</i> in Context</h2>
CSS:
@top-center {
content: element(heading);
}
p.rh {
position: running(heading);
}
p.rh::before {
content: counter(page) ' / ';
}

value()要素は、ページマージンボックス内でのみ使用できます。また、contentプロパティの他の値と組み合わせることはできません。
要素を移動だけでなくコピーもできれば、さらに有用になるでしょう。そうすれば、上記例のようなHTMLの重複を避けられます。
Bert Bosは、要素をランニングヘッドとして移動またはコピーできる代替シンタックスを提案しています。下記の例では、h2要素が文書内の通常位置に表示されると同時に、ランニングヘッドにもコピーされます。
h2 {
display: block;
running: chapter;
font-size: 18pt;
font-weight: bold;
}
h2:running {
display: inline;
font-size: 11pt;
font-weight: normal;
font-variant: small-caps;
letter-spacing: 1pt;
}
@page {
@top-center {
content: element(chapter);
}
}
| Name: | running |
|---|---|
| Value: | <custom-ident> |
| Initial: | none |
| Applies to: | 要素 |
| Inherited: | no |
| Percentages: | N/A |
| Computed value: | 指定値 |
| Canonical order: | 文法順 |
| Animation type: | 離散 |
ユーザーエージェントは、非ビジュアルを含むすべてのメディアでこのプロパティをサポートすることが期待されます。
1.2.2. element()値
element()値は、contentプロパティにおいて、running()によって通常フローから取り除かれた要素をページマージンボックスに配置します。要素の値が変更されるたびに、element()の値も更新されます。
string()と同様に、element()も、1ページ内で複数回割り当てがある場合にどの値を使うかを指定するキーワードをオプションで取れます。ユーザーエージェントは多数の値を記憶できなければなりません。element()は過去・現在・未来の値を返すことができるためです。
| Name: | content |
|---|---|
| New values: | <element()> |
element() = element( <custom-ident> , [ first | start | last | first-except ]? )
2. 脚注
付随コンテンツはページの下部や側面に移動されることがあります。脚注は、そのようなコンテンツがページ下部に移動され、参照指標が残るときに作成されます。2.1. 用語
脚注は複雑なオブジェクトです(脚注セクションおよび[dpub-latinreq]を参照)。以降を読みやすくするため、いくつかの用語を定義しておきます。

- 脚注要素
- 脚注の内容を含む要素で、フローから取り除かれ、脚注として表示されます。
- 脚注マーカー(脚注番号とも呼ばれる)
- 脚注本文の隣に配置される番号や記号で、特定の脚注を識別します。脚注マーカーは対応する脚注参照と同じ番号や記号を使用するべきですが、追加の句読点が含まれる場合もあります。
- 脚注本文
- 脚注マーカーは脚注要素の前に配置され、両者で脚注本文を構成し、脚注エリアに配置されます。
- 脚注参照(脚注リファレンスとも呼ばれる)
- 本文中に現れる番号や記号で、脚注本文を指し示します。
- 脚注エリア
- 脚注を表示するためのページ領域です。
- 脚注ルール(脚注セパレーターとも呼ばれる)
- 脚注エリアとページの残り部分を区切るために、横罫線がよく使われます。セパレーター(および脚注エリア全体)は、脚注の無いページには表示できません。
2.2. 脚注の作成
要素にfloat: footnoteを適用することで、その要素は脚注になります。これにより、以下の動作がトリガーされます:
- 脚注要素はフローから取り除かれ、その場所に脚注への参照となる
::footnote-call疑似要素が挿入されます。 - 脚注を識別する
::footnote-marker疑似要素が脚注要素の先頭に配置されます。これで脚注本文が構成されます。 - footnote counter(脚注カウンター)がインクリメントされます。
- 脚注本文はページ下部の脚注エリアに配置されます。同じページ内の脚注要素は文書順で脚注エリアに配置されます。
<p>Though the body was erect, the head was thrown back so that the closed eyes were pointed towards the needle of the tell-tale that swung from a beam in the ceiling.<span class="footnote">The cabin-compass is called the tell-tale, because without going to the compass at the helm, the Captain, while below, can inform himself of the course of the ship.</span></p>
CSS:
@page {
@footnote {
float: bottom;
}
}
span.footnote { float: footnote; }
なぜfootnoteエリアでfloat:bottomが使われているのか?脚注エリアに脚注をフロートさせ、その脚注エリア自体にもフロートを使うのは実装上ややこしそうです。実際、実装によっては脚注エリアを絶対位置で配置できるものもあります。
2.3. 脚注の種類
floatプロパティの以下の新しい値で、脚注要素が作成されます:| Name: | float |
|---|---|
| New values: | footnote |
- footnote
- 各脚注要素はページの脚注エリアに配置されます
footnote-displayプロパティは、脚注をブロック要素として表示するかインライン要素として表示するかを決定します。
| Name: | footnote-display |
|---|---|
| Value: | block | inline | compact |
| Initial: | block |
| Applies to: | 要素 |
| Inherited: | no |
| Percentages: | N/A |
| Computed value: | 指定値 |
| Canonical order: | 文法順 |
| Animation type: | 離散 |
- block
- 脚注要素が脚注エリアにブロック要素として配置されます
- inline
- 脚注要素が脚注エリアにインライン要素として配置されます
- compact
- 与えられた脚注要素をブロックかインラインかはユーザーエージェントが決定します。脚注エリア内で2つ以上の脚注が同じ行に収まりそうな場合は、インラインで配置されるべきです。
2.4. 脚注エリア
脚注を表示するためのページエリアは、ページコンテキストで@footnoteルールを使って記述されます。このルールは、脚注要素がそのページに現れる場合に、それら全てを含むボックスを定義します。
2.4.1. 脚注エリアの位置
脚注エリアの下マージン端はページエリアの下端に接するように配置されます。脚注エリアには脚注のみを含めることができます。マルチカラムテキストで脚注はどう動作すべきか?Princeはfloat: prince-column-footnoteを使って、カラムの下部に脚注を作成します。
脚注をサポートする実装は、通常float: bottomのようなページフロートもサポートします。ページフロートは脚注エリアより上に配置されるべきです。これはどう記述すべきでしょうか?
2.4.2. 脚注エリアのサイズ
max-heightプロパティを脚注エリアに指定することで、このエリアのサイズを制限できます(ただし文書最終ページなど、脚注だけのページでは除く)。
ページ全体が脚注だけになるのは望ましくないため、ユーザーエージェントはデフォルトで脚注エリアにmax-height値を設定してもよいです。
2.5. 脚注カウンター
footnote counterは脚注要素に紐付けられた定義済みカウンターです。その値は脚注を識別する番号や記号となります。この値は脚注参照と脚注マーカーの両方で使われ、各脚注ごとにインクリメントされるべきです。
2.5.1. 脚注カウンターの値
脚注カウンターは他のカウンターと同様、任意のカウンタースタイルが利用可能です。脚注では記号列がよく使われます。
::footnote-call { content: counter(footnote, symbols('*', '†', '‡', '§')); }
::footnote-marker { content: counter(footnote, symbols('*', '†', '‡', '§')) '. '; }
2.5.2. 脚注カウンターのリセット
脚注カウンターは各ページごとにリセットできます。
脚注カウンターの値は、最終的に配置される場所ではなく、文書ツリー内の脚注要素の位置に依存するべきです。脚注要素が呼び出しより後のページに配置される場合でも、同じカウンター値を使う必要があります。
2.6. footnote-call疑似要素
::footnote-call疑似要素は、脚注要素がフローから除去されたとき、その場所に挿入されます。デフォルトでは、この疑似要素の内容は脚注カウンターの値になり、上付きの数字としてスタイルされます。
::footnote-call {
content: counter(footnote);
vertical-align: baseline;
font-size: 100%;
line-height: inherit;
font-variant-position: super;
}
2.7. footnote-marker疑似要素
::footnote-marker疑似要素は、各脚注を識別する番号や記号である脚注要素のマーカーを表します。この疑似要素は[CSS3LIST]で定義される::marker疑似要素のように振る舞います。親要素の内容の先頭に配置され、デフォルトでインラインです。::footnote-markerは::marker要素同様にスタイルできます。デフォルトスタイルにはlist-style-position: insideを含むべきです。
2.8. 脚注の描画とfootnote policy
脚注の描画は複雑になることがあります。脚注がページ下部近くに現れる場合、脚注本文のための十分なスペースがページに無い場合があります。footnote-policyプロパティにより、困難なページの描画方法について著者が影響を与えることができます。
| Name: | footnote-policy |
|---|---|
| Value: | auto | line | block |
| Initial: | auto |
| Applies to: | 要素 |
| Inherited: | no |
| Percentages: | N/A |
| Computed value: | 指定値 |
| Canonical order: | 文法順 |
| Animation type: | 離散 |
- auto
- ユーザーエージェントが脚注の描画方法を選択し、脚注本文を脚注参照より後のページに配置する場合があります。脚注本文が脚注参照より前のページに配置されてはいけません。
- line
- もし脚注本文を現在のページに置けない場合、ユーザーエージェントは脚注参照を含む行の先頭で強制改ページを入れ、参照と脚注本文が次ページに揃うようにします。この際、widowやorphan設定も考慮し、場合によってはより前の行で改ページを入れる必要があります。
- block
- lineと同様ですが、脚注を含む段落の前で強制改ページを行います。
2.9. 今後の展望
次のレベルでは、サイドノート、カラム脚注、複数脚注エリアなども含まれる予定です。3. ページの選択
ページ分割文書はページの連なりで構成されます。[CSS3PAGE]は、文書の最初のページ、左・右ページ、空白ページなどを選択するページセレクターを定義しています。ここでは任意のページを選択できるよう、このページセレクターの考え方を拡張します。
3.1. ページセレクター
:nth()ページ疑似クラスにより、任意の文書ページを選択できます。この疑似クラスはAn + B形式の引数を取り、[CSS3SYN]で定義されています。デフォルトの@pageルールに適用すると、:nth()は引数に合致するインデックスの文書ページを選択します。:nth() = :nth( <an+b> [of <custom-ident>]? )
:nth()はページカウンターとは無関係です。ページカウンターはリセットされる可能性や様々な番号付け方式を持つためです。
:nth()セレクターが名前付きページに適用され、そのページがページグループの一部の場合(下記参照)、そのグループ内でn番目のページが選択されます。
3.2. ページグループ
多くのページ分割文書は、複数の章やセクション、記事などの繰り返し構造を持っています。各区分の最初のページは特別な扱いが必要ですが、[CSS3PAGE]には章ごとの最初のページ(文書全体の最初のページとは区別される)を選択する仕組みはありません。pageプロパティが強制改ページプロパティと共に要素に適用されると、ページグループが作成されます。ページグループは、その要素インスタンスによって作成されたすべてのページの集合です。新しいインスタンスがレンダリングされるたびに新しいページグループが開始されます。
ページは複数のページグループに属することもあります。あるページグループの祖先や子孫が別のページグループの一部となることもあるためです。
div {
page: A;
break-before: page;
}
child {
page: B;
break-before: page;
}
@page :nth(5 of A) /* 各<div>の5ページ目 */ @page :nth(1 of B) /* 各<child>の最初のページ */ @page :nth(5) /* 文書全体の5ページ目 */
次のHTMLを考えます:
<div class="chapter"> <h1>Chapter One</h1> <p>some text</p> <table class="broadside"> ... </table> ... </div> <div class="chapter"> <h1>Chapter Two</h1> <p>some text</p> ... <table class="broadside"> ... </table> ... </div>
そしてCSS:
div.chapter {
page: body;
break-before: page;
}
table.broadside {
page: broadside;
break-before: page;
}
この場合、各章ごとに別のページグループが形成されます。@page:nth(3 of body)は各章の3ページ目を選択します(たとえそのページが「broadside」ページ名を使っていても)。@page:nth(1)は文書全体の最初のページのみを選択し、@page:firstも同様です。
4. リーダー(移動済み)
現在は[CSS3-CONTENT]で説明されています
5. 相互参照(移動済み)
現在は[CSS3-CONTENT]で説明されています
6. ブックマーク(移動済み)
現在は[CSS3-CONTENT]で説明されています
付録A: 各セクションの移動先
2011年11月29日作業草案に含まれていた多くのセクションは他の仕様へ移動されました。ここでは移動先について簡単に記載します。
ページマークと裁ち落としエリア
このセクションはCSS Paged Media Module Level 3に移動しました。
CMYKカラー
このセクションはCSS Color Module Level 5に移動しました。
空白ページのスタイリング
このセクションはCSS Paged Media Module Level 3に移動しました。
ページ表示
このセクションはCSS Overflow Module Level 4に移動しました。
ページ間ナビゲーション
これはWHATWG CSS Booksで説明されています。
ページフロート
このセクションはCSS Page Floatsに移動しました。
カラムとページの選択
カラムの選択についての簡単な記載はWHATWG CSS Booksにあります。
付録B: デフォルトUAスタイルシート
この付録は参考情報であり、UA開発者がHTML用のデフォルトスタイルシートを実装する際の補助を目的としていますが、UA開発者は必要に応じて無視または変更しても構いません。
@page {
counter-reset: footnote;
@footnote {
counter-increment: footnote;
float: bottom;
column-span: all;
height: auto;
}
}
::footnote-marker {
content: counter(footnote);
list-style-position: inside;
}
::footnote-marker::after {
content: '. ';
}
::footnote-call {
content: counter(footnote);
vertical-align: super;
font-size: 65%;
}
@supports ( font-variant-position: super ) {
::footnote-call {
content: counter(footnote);
vertical-align: baseline;
font-size: 100%;
line-height: inherit;
font-variant-position: super;
}
}
h1 { bookmark-level: 1 }
h2 { bookmark-level: 2 }
h3 { bookmark-level: 3 }
h4 { bookmark-level: 4 }
h5 { bookmark-level: 5 }
h6 { bookmark-level: 6 }
付録C: 変更点
2014年5月13日作業草案以降の変更点:
- ブックマークはbookmark-levelプロパティでのみ作成できることを明確化。bookmark-labelのnone値を削除。
- 相互参照、リーダー、ブックマークの各セクションをCSS Generated Content Moduleへ移動。
- 誤ったbreak値を修正。Issue #3524参照。
- 新しい編集者を追加。
2013年9月24日編集者ドラフト以降の変更点:
- 新しい編集者を追加。
- 全テキストと例を全面的に書き直し。
- attr(<identifier>)値をstring-setプロパティに追加。PrinceとAntennaHouseの両方が対応。
- 難しい場合の脚注描画制御用にfootnote-policyプロパティを追加。
- インライン脚注用のfootnote-displayプロパティを追加。
- サイドノートセクションを削除。
- ページやカラム内の要素選択に関するセクションを削除。
- page-groupプロパティを削除、nth()ページ疑似クラスにオプション引数を追加しページグループ内選択を可能に。
2011年11月29日作業草案以降の変更点:
- ページマークと裁ち落としセクションをCSS Paged Media Module Level 3へ移動
- CMYKカラーセクションをCSS Colors Level 5へ移動
- 空白ページのスタイリングセクションを削除
- ページ表示セクションをCSS Overflow Module Level 3へ移動
- ページ間ナビゲーションをWHATWG CSS Booksへ移動
- ページフロートセクションをCSS Page Floatsへ移動
- 最初のページ疑似要素セクションを削除
- カラム・ページ選択セクションを削除
- string-setプロパティからenv()関数を削除
- リーダーのalignment値を削除
- leaderは1行のみ占有するよう指定
- target-textのcontent()値をcontent(text)に変更
- contentプロパティのtarget-pull()値を削除
WHATWG CSS Books仕様との相違点:
- attr(<identifier>)値をstring-setプロパティに追加。PrinceとAntennaHouseの両方が対応。
- CSS Booksにはfootnote-displayプロパティがありません。
- CSS Booksにはfootnote-policyプロパティがありません。
nth()ページ疑似クラスとページグループ概念の関係を明確化。これによりpage-groupプロパティは不要になる可能性。- 本仕様では
:firstページ疑似セレクターをページグループの最初のページに適用する再定義はしません。 -
本仕様では以下を考慮しません:
- 名前付きエリア
- ページ・カラム内の要素選択
range()ページ疑似クラス- カラム選択
- ベースラインリズム
- ボックスモデルの拡張
- 文字置換
- マイクロタイポグラフィ
プライバシーに関する考慮事項
この仕様に関して新たなプライバシー考慮事項は報告されていません。
セキュリティに関する考慮事項
この仕様に関して新たなセキュリティ考慮事項は報告されていません。
謝辞
この成果は、Håkon Wium Lie氏の多大な貢献なくしては実現できませんでした。Chris Lilley、Elika J. Etemad、Alan Stearns、L. David Baron、Bert Bos、Florian Rivoal、[$your_name, ", " ]+、Liam Quin 各氏より貴重なフィードバックをいただきました。