CSS生成コンテンツモジュール レベル3

W3C作業草案

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2025/WD-css-content-3-20251204/
最新公開バージョン:
https://www.w3.org/TR/css-content-3/
編集者草案:
https://drafts.csswg.org/css-content-3/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/css-content-3/
フィードバック:
CSSWG課題リポジトリ
仕様内インライン
編集者:
Elika J. Etemad / fantasai (Apple、旧Mozilla)
(BFO)
前編集者:
(Hachette Livre)
(Opera Software)
(Google)
この仕様への編集提案:
GitHub エディター
テストスイート:
https://wpt.fyi/results/css/css-content/

概要

このCSS3モジュールは、ドキュメントにコンテンツを挿入する方法について説明します。

CSSは、構造化されたドキュメント(HTMLやXMLなど)を 画面や紙などにレンダリングするための言語です。

この文書のステータス

このセクションは、公開時点での文書のステータスについて説明します。 現在のW3C出版物一覧や この技術報告の最新リビジョンはW3C標準・草案一覧で確認できます。

この文書は、CSS作業グループによって 作業草案として勧告トラックを用いて公開されました。 作業草案として公開されたことは、W3Cおよびその会員による 承認を意味するものではありません。

この文書は草案であり、 内容は随時、更新・置換・廃止されることがあります。 本文書を進行中の作業以外として引用するのは不適切です。

フィードバックは、GitHubでissueを提出(推奨)し、 タイトルに仕様コード "css-content" を含めてください(例:“[css-content] …コメント概要…”)。 すべてのissueおよびコメントはアーカイブされます。 または、(アーカイブあり)パブリックメーリングリスト www-style@w3.org まで送信も可能です。

この文書は、2025年8月18日 W3Cプロセス文書に基づいて管理されています。

この文書は、W3C特許ポリシーの下で活動するグループによって作成されました。 W3Cは公開特許開示リストをこのグループの成果物に関連して管理しており、 ページには特許開示手続きも記載されています。 実際に特許が存在し、それが必須クレームを含むと考える場合は、 W3C特許ポリシー6節に従って情報を開示してください。

この文書は非常に粗い草案であり、実装にはまだ適していません。

はじめに

著者は、ユーザーエージェントにドキュメントツリーからではないコンテンツを描画させたい場合があります。 よくある例としては、番号付き見出しがあります。 著者は番号を明示的にマークアップしたくはなく、 それらをユーザーエージェントに自動生成させたいと考えています。 このような効果を実現するために、カウンターやマーカーが使われます。

h1::before { content: counter(section) ": "; }

同様に、著者は図のキャプションの前に「図」と表示したり、 第7章のタイトルの前に「第7章」と表示することもあるでしょう。

chapter { counter-increment: chapter; }
chapter > title::before { content: "Chapter " counter(chapter) "\A"; }

他にも、要素を画像や他のマルチメディアコンテンツで置き換える効果がよく使われます。 すべてのユーザーエージェントがすべてのマルチメディア形式に対応しているわけではないため、 フォールバックの提供が必要となる場合もあります。

/* <logo>要素をサイトロゴに置き換え、UAがサポートする形式を使用 */
 * 
logo { content: url(logo.mov), url(logo.mng), url(logo.png), none; }

/* <figure>要素を参照先のドキュメントで置き換え、
 * alt属性があればその内容、なければ要素自身の内容で置き換え */
figure[alt] { content: attr(href url), attr(alt); }
figure:not([alt]) { content: attr(href url), contents; }
テスト

生成コンテンツの一般的なテスト


値の定義

この仕様は、CSSプロパティ定義の慣例と、値定義構文に従います。 仕様で定義されていない値型は、CSS Values & Units [CSS-VALUES-3]で定義されています。 他のCSSモジュールとの組み合わせにより、これらの値型の定義が拡張されることがあります。

定義内で挙げられているプロパティ固有の値に加えて、 この仕様で定義されるすべてのプロパティは、 CSS全体で使えるキーワードもプロパティ値として受け入れます。 可読性のため、繰り返し明示はしていません。

1. コンテンツの挿入と置換: contentプロパティ

名前: content
値: normal | none | [ <content-replacement> | <content-list> ] [/ [ <string> | <counter> | <attr()> ]+ ]?
初期値: normal
適用対象: すべての要素、ツリー順守疑似要素、ページマージンボックス
継承: no
パーセンテージ: 該当なし
算出値: 下記の説明を参照
標準順序: 構文通り
アニメーション型: 離散型
テスト

ユーザーエージェントは、視覚的でないものを含むすべてのメディアでこのプロパティへの対応が期待されています。

contentプロパティは、要素や疑似要素の内部で描画される内容を制御します。

要素の場合は、 通常通り描画するか、 要素を画像(および関連する「altテキスト」)で置き換えることのみ指定できます。

疑似要素とマージンボックスの場合は、 より強力な制御が行えます。 要素自体の描画有無の制御や、 画像で置き換えたり、 任意のインラインコンテンツ(テキストや画像)への置き換えが可能です。

normal
要素やページマージンボックスの場合、この値はcontentsに算出されます。

::before::afterの場合は、noneに算出されます。

::marker::placeholder、 そして::file-selector-buttonの場合は、 値そのもの(normal)に算出されます。

none
要素の場合は、normalとして振る舞います。

疑似要素の場合、その疑似要素の生成を抑制し、 display: noneと同じように扱われます。

どちらの場合も、当該要素や疑似要素を発生元要素として持つ他の疑似要素生成は妨げません。

<content-replacement>
同値:
<image>

要素や疑似要素置換要素とし、 指定された<image>で満たします。 通常の内容は抑制され、 box生成されません。display: none扱いです。

もし<image>不正な画像の場合、 幅・高さ0、透明黒で満たされた画像として扱います。

上記の不正な画像の挙動はChromeが採用しているものと同じです。 本当にこれでよいでしょうか? より良い挙動はあるでしょうか?

注: 置換要素は通常の要素と異なるレイアウト規則を持ちます。 (実質的にはHTMLの img 要素と同じになります。)

注: 置換要素には::before::after疑似要素は存在しません。 contentプロパティが内容全体を置換します。

この値は、 <content-list>として ::before::afterで扱われてきました。 Web互換性の要求があると思われるので、これらの疑似要素には例外が必要かもしれません。[Issue #2889]

<content-list>
要素の内容を、指定した値ごとに対応する複数の匿名インラインボックスに順番通り置換します。 通常の内容は抑制され、box生成されません。display: none扱いです。

各値は、要素内容にインラインボックスとして寄与します。 <image>の場合は匿名インラインの置換要素、 その他の場合は匿名インラインテキスト列となります。

<image>不正な画像を 表す場合、UAは以下のどちらかを行います:

  • <image>をスキップして何も生成しない

  • 表示不可であることを示す何らかのものをその<image>の位置に表示する (「壊れた画像」アイコンなど)

本仕様ではUAがどちらを使うべきかは定めませんが、どちらか一方を一貫して使う必要があります。

注: <content-list>の値が単一の<image>である場合は、<content-replacement>として解釈されます。

テスト
/ [ <string> | <counter> | <attr()> ]+
要素の「altテキスト」を指定します。 詳細は§ 1.2 アクセシビリティ用代替テキストを参照ください。 省略された場合、 要素には「altテキスト」はありません。
"altテキスト"で<counter>を未対応ブラウザでも正しく使いたい場合は、 contentプロパティを2回指定するのが望ましいです。 まずcounterなしのfallbackを指定し、 次にcounterありの"altテキスト"を指定します。
::before {
  content: "Chapter" counter(chapter);
  content: "Chapter" counter(chapter) / "Chapter" counter(chapter);
}

contentsキーワードをcontent()に置き換えるべきでしょうか?

1.1. 生成コンテンツのアクセシビリティ

生成されたコンテンツは検索可能で、選択可能であり、支援技術でも利用できるべきです。 contentプロパティは音声にも適用され、 生成コンテンツは音声出力時にもレンダリングされなければなりません。[CSS3-SPEECH]

CSS用のAAM策定作業を開始すること。

1.2. アクセシビリティ用の代替テキスト

視覚メディア向けのコンテンツは、音声出力や非視覚的メディア向けに代替テキストが必要になることがあります。 contentプロパティは、スラッシュ(/)の後に <content-list>を指定した後、代替テキストを受け入れることができます。 代替テキストが提供されている場合は、 音声出力の際にその代替テキストを使用しなければなりません。

これにより、例えば装飾的テキストのみを音声出力で省略したい場合(代替テキストを空文字列にすることで)や、画像やアイコン、テキスト化された記号などにより読みやすい代替を著者が指定できるようになります。

この場合、contentプロパティには画像が指定されており、alt値として代替テキストが必須です。
.new::before {
 content: url(./img/star.png) / "New!";
  /* またはDOMのローカライズ属性: attr("data-alt") */
}
疑似要素が純粋に装飾的でその機能が他で担保されている場合、altを空文字列に設定することで、その装飾的要素の読み上げを避けることができます。この例では、ARIA属性は「collapsed」として読み上げられます。alt値を空文字列にしなければ、「ブラック右向き三角」とも読み上げられることになります。
.expandable::before {
 content: "\25BA" / "";
/* または ► */
 /* aria-expanded="false" がすでにDOMにあるため
   この疑似要素は装飾目的 */
}

2. 生成コンテンツ値: <content-list>

<content-list>値はcontentで使用され、画像、文字列、カウンターの値、要素のテキスト値など、1つ以上の匿名インラインボックスで要素を満たすために使われます。 このセクションでは利用可能な内容種別を列挙します。

<content-list>の構文は以下の通りです:

<content-list> = [ <string> | <image> | <attr()> | contents | <quote> | <leader()> | <target> | <string()> | <content()> | <counter> ]+

2.1. 基本文字列: <string> および<attr()>

<string>
指定されたテキストで満たされた匿名インラインボックスを表します。

注: 空白文字は文字列リテラルと同じように処理され、 [CSS-TEXT-3]などで定義されたプロパティで制御されます。 特に、空白文字は文字列間でもまとめて折りたためます。 例えば content: "First " " Second"; の場合、デフォルトでは "First Second" (単語間に1つのスペース)と同様にレンダリングされます。

<attr()>
attr()関数表記は、 指定した属性の値として格納されている文字列を表します。 引数はCSS修飾名qname)で、 属性名と(あれば)名前空間を示します。 詳しくは[CSS3-NAMESPACE]を参照。

注: 属性セレクタと同様、 明示的な名前空間がない属性名はデフォルトの名前空間には関連付けられません。

2.2. 2D画像: <image>

<image>
指定された<image>で満たされた匿名インラインの置換要素を表します。

<image>不正な画像の場合、 この値は何も表さなくなります。 (要素にインラインコンテンツは追加されず、この値は「スキップ」扱いとなります。)

CSS2.1では UAが不正な画像の場合に「壊れた画像」アイコンなどで代替することを明示的に許していました。 しかし、どのブラウザもこれを実際に行っていないようです。 この削除は問題ないでしょうか?

2.3. 要素コンテンツ: contentsキーワード

contents
要素の子孫です。 これが1要素内で複数回使われることはできません (例えば子要素がプラグインやフォームコントロールの場合は複製できません)ので、 以下のように扱われます:
要素自体に設定した場合:

常に有効です。 初期値としてcontentnormalなので、 normalは要素上ではcontentsに算出されます。

要素の他の疑似要素に設定した場合:

下記の順序(深さ優先)で「前の」疑似要素に設定されていないか確認ください:

  1. 要素自体

  2. ::before

  3. ::after

疑似要素では空文字列と同様にすべきか?

すでに利用されていた場合は「none」と同じく何も評価されません。 実際に生成された疑似要素のみ確認されます。

以下の例の場合:
foo { content: normal; }  /* これは初期値 */
foo::after { content: contents; }

...この場合, 要素のcontentプロパティはcontentsに算出され、::after疑似要素には内容がなく (noneと同等) なので表示されません。

foo { content: none; }
foo::after { content: contents; }

この場合は、::after疑似要素にはfoo要素の内容が含まれます。

要素で内容を抑制し、疑似要素で利用するユースケース募集中。

注: 1つのcontentプロパティ内で contentsを2回指定しても無意味ですが、これは構文エラーではありません。 2回目の指定はすでに利用済みのため効果がありません。 また::marker疑似要素で使っても構文エラーではありませんが、レンダリング段階でnone扱いとなります。

marker擬似要素についての記述は本当に必要か?旧仕様の遺産では?

2.4. 引用符

quotesプロパティ(引用符システムを定義します)と、 contentプロパティで使う *-quote値を組み合わせることで、生成コンテンツとして対応する引用符を自動で挿入できます。 たとえばHTMLの q 要素などが該当します。

2.4.1. 引用符システム: quotesプロパティ

名前: quotes
値: auto | none | match-parent | [ <string> <string> ]+
初期値: auto
適用対象: すべての要素
継承: yes
パーセンテージ: 該当なし
算出値: キーワード none 、キーワード automatch-parent 、またはリスト(各項目は文字列のペア)
標準順序: 構文通り
アニメーション型: 離散型
テスト

ユーザーエージェントは視覚的でないメディアを含むすべてのメディアでこのプロパティをサポートすることが期待されています。

このプロパティは要素の引用符システムを指定し、 contentプロパティの open-quoteclose-quote値の挙動を定義します。 詳しくは§ 2.4.2 引用符の挿入: *-quoteキーワードを参照ください。 各値の意味は以下の通りです:

none
open-quoteclose-quote値は contentプロパティ上で 引用符を生成せず、 それぞれno-open-quoteno-close-quote と同じように振る舞います。
auto
タイポグラフィ的に適切な引用符システムが、 親のコンテンツ言語(なければ要素自身の言語)に基づき UAによって自動的に選択されます。

注: Unicode Common Locale Data Repository [CLDR]には タイポグラフィ的に適切な引用符に関する情報が掲載されています。 UAは他の情報源も利用できますが、 タイポグラフィの好みは多様性があり得るため、 Unicodeへの改善提案も歓迎されます。 (そうすればソフトウェア生態系全体の利益となります。)

match-parent
親と同じ引用符システムを指定します。 通常これは親の算出値継承と同等ですが、 autoの場合は 親が用いたコンテンツ言語を使って解決されます。

ここには2つのアプローチがあり、現在は後者を仕様化しています: a) これは関連する文字列値に算出され、そのまま継承される。 b) この値はキーワード+言語コードとして継承され、 つまりautoだが言語は親から引き継ぐ。

[ <string> <string> ]+
引用符システムは 指定された引用符ペア(開始と閉じ)リストとして定義されます。 最初のペアは最も外側の引用レベル、次のペアは埋め込みの次のレベル…というように表します。 ペア内では、 open-quote値は1つ目の <string>close-quoteは2つめに対応します。

2.4.2. 引用符の挿入: *-quoteキーワード

<quote> = open-quote | close-quote | no-open-quote | no-close-quote
テスト
open-quote
close-quote
これらの値は、quotesプロパティで定義された適切な文字列に置換されます。 open-quoteの場合は引用の入れ子レベルが増加し、 close-quoteの場合は入れ子レベルが減少します。
no-open-quote
no-close-quote
何も挿入しません(noneと同様)。 ただしno-open-quoteは引用深度を増加、 no-close-quoteは減少します。

引用符は、open-quoteおよびclose-quote値を contentプロパティに指定することで、 ドキュメントの適切な場所に挿入できます。 open-quoteclose-quoteの出現ごとに、 引用符システムで定義された引用符文字列に置換されます。 これはquotesプロパティで指定され、 入れ子(引用深度)により決定します。

どの引用符ペアを使うかは引用の入れ子レベル (引用深度)によります。 これは、該当箇所までの生成テキスト内のopen-quoteの総数から、 それまでに出現したclose-quoteの総数を引いたものです。 深度0なら最初のペア、深度1なら2番目のペア…という具合です。 ペア数を深度が超えた場合は最後のペアが繰り返し使われます。

注: 引用深度は ドキュメントや書式構造の入れ子に依存しません。 また、カウンターの継承と同じく、 [DOM]内の「フラット化要素ツリー」で動作します。

close-quoteno-close-quoteにより 引用深度が負になる場合はエラーとなり(レンダリング時に無視)、 深度は0のままで引用符は挿入されません (ただし、contentプロパティの他の値は挿入されます)。

いくつかのタイポグラフィでは、複数段落にわたる引用文で各段落の先頭に 開始引用符が必要ですが、閉じ引用符は最後の段落のみにつけます。 CSSでは「ダミー」閉じ引用符を挿入することでこれを実現できます。 no-close-quoteキーワードは 引用レベルを減じますが、引用符は挿入しません。

以下のスタイルシートはblockquote内の各段落の前に開始引用符を挿入し、 最後の段落にのみ閉じ引用符を挿入します:

blockquote p::before { content: open-quote }
blockquote p::after { content: no-close-quote }
blockquote p:last-child::after { content: close-quote }

対称性のためにno-open-quoteキーワードもあります。 これは何も挿入しませんが、引用深度を1増加させます。

注: 引用文が周囲の言語とは異なる場合、 引用符は引用文そのものの言語ではなく、周囲の言語に合わせたものを使うのが慣例です。

たとえば英語文中のフランス語の場合:
The device of the order of the garter is “Honi soit qui mal y pense.”

フランス語文中の英語:

Il disait: « Il faut mettre l’action en ‹ fast forward ›. »

例えば下記のようなスタイルシートでquotesプロパティを設定すれば、 open-quoteclose-quoteが すべての要素で正しく機能します。 これらは英語・フランス語で構成される文書用。 追加言語ごとにルールが必要です。 親要素の言語ごとに適切な引用符を設定するためには子要素結合子(">")を使います:

:lang(fr) > * { quotes: "\00AB\2005" "\2005\00BB" "\2039\2005" "\2005\203A" }
:lang(en) > * { quotes: "\201C" "\201D" "‘" "’" }

引用符はだれもが入力できる形でここに示しています。 直接入力できる場合は、次のように表示されます:

:lang(fr) > * { quotes: "« " " »" "‹ " " ›" }
:lang(en) > * { quotes: "“" "”" "‘" "’" }
例えば次のスタイルシートの適用時:
/* 2つの言語・2レベル用の引用符ペア指定 */
:lang(en) > q { quotes: '"' '"' "'" "'" }
:lang(no) > q { quotes: "«" "»" "’" "’" }

/* Q要素の内容前後に引用符挿入 */
q::before { content: open-quote }
q::after  { content: close-quote }

次のHTML片に適用すると:

<html lang="en">
  <head>
   <title>Quotes</title>
  </head>
  <body>
   <p><q>Quote me!</q></p>
  </body>
</html>

以下のような表示になります:

"Quote me!"

一方次のHTML片では:

<html lang="no">
  <head>
   <title>Quotes</title>
  </head>
  <body>
   <p><q>Trøndere gråter når <q>Vinsjan på kaia</q> blir deklamert.</q></p>
  </body>
</html>

このようになります:

«Trøndere gråter når ’Vinsjan på kaia’ blir deklamert.»

2.5. リーダー

リーダー(タブリーダーやドットリーダーとも呼ばれる)は、 水平方向にコンテンツを視覚的につなぐための繰り返しパターンです。 目次でタイトルとページ番号の間に最もよく使われます。 leader()関数を contentプロパティ値として使うことでCSSでリーダーが生成できます。 この関数は文字列(リーダー用パターン)を受け取り、パターンを繰返します。

2.5.1. leader()関数

leader( <leader-type> )
リーダーを挿入します。 詳しくはリーダーの節を参照ください。
leader() = leader( <leader-type> )
<leader-type> = dotted | solid | space | <string>

よく使うパターンを表す3つのキーワードがあります:

dotted
leader(".")と同等
solid
leader("_")と同等
space
leader(" ")と同等
<string>
課題: 定義が必要です。
ol.toc a::after {
  content: leader('.') target-counter(attr(href), page);
}

<h1>目次</h1>
<ol class="toc">
<li><a href="#chapter1">Loomings</a></li>
<li><a href="#chapter2">The Carpet-Bag</a></li>
<li><a href="#chapter3">The Spouter-Inn</a></li>
</ol>

このような表示結果になります:

目次

1. Loomings.....................1
2. The Carpet-Bag...............9
3. The Spouter-Inn.............13

リーダーは後続コンテンツが右揃え(右端揃え)であることを前提にしているか?

2.5.2. リーダーの描画

リーダーの前のコンテンツ(「前コンテンツ」)、リーダー、リーダー後のコンテンツ(「後コンテンツ」)を含む行を考えます。 リーダーは次の規則に従います:

  1. リーダー文字列は最低1回は完全に表示されなければなりません。

  2. リーダーはできるだけ長くするべきです。

  3. リーダー内の見える文字が可能なら縦に揃うべきです。

  4. リーダー文字列内の改行文字は無視されねばなりません。

  5. リーダー文字列内の空白は通常のCSS規則に従います。

  6. リーダーは開始コンテンツと終了コンテンツの間だけに表示されます。

  7. 開始コンテンツや終了コンテンツが別行であっても、リーダー自体は1行だけに表示されます。

  8. リーダーのみが1行に表示されることはありません。

2.5.3. リーダー描画手順

  1. 前コンテンツをレイアウトし、その終了する行まで進めます。

    BBBBBBBBBB
    BBB
    
  2. リーダー文字列は1つ以上のグリフからなり、インラインボックスです。 リーダーはこれらのボックスが行末から行頭まで並ぶものです。 前後コンテンツが重ならない箇所だけ表示されます。 この行でリーダー文字列を行末から反復して並べ、行頭までできるだけ多く表示します。

    BBBBBBBBBB
    ..........
    
  3. リーダー上に前コンテンツおよび後コンテンツを重ね表示します。 前コンテンツ後コンテンツがリーダー文字列ボックスのグリフと重なる場合、 そのグリフは表示されません。

    BBBBBBBBBB
    BBB....AAA
    
  4. リーダー文字列が1回も完全には表示できない場合:

    BBBBBBB
    BBBBBBA
    

    前コンテンツの後に改行を挿入し、次の行にリーダーを表示し、 その上に後コンテンツを重ね、 完全に表示できないリーダー文字列は隠す。

    BBBBBBB
    BBBBBB
    ......A
    

後コンテンツが行ボックスより幅広い場合どうすべきか?

リーダーは表レイアウトと完全には合わない。どう修正すべきか?

drawing leaders
リーダー描画手順
drawing leaders
1行で収まらない場合のリーダー描画手順

2.6. 相互参照

多くのドキュメントには内部参照が含まれています:

contentプロパティ用に3つの新しい値があり、これらの種類の参照を自動生成できます:target-counter()target-counters()target-text()です。 これらはリンク先から取得した情報を表示します。

<target> = <target-counter()> | <target-counters()> | <target-text()>

詳細は以下のセクションを参照ください。

2.6.1. target-counter()関数

target-counter() = target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )

target-counter()関数は、指定した名前の最も内側のカウンターの値を取得します。 必須引数はターゲットのURLとカウンター名です。 結果の書式指定用にcounter-style引数を追加できます(省略可能)。

これらの関数は現在の文書内の場所を指すフラグメントURLのみ受け付けます。 フラグメントがない場合、参照先IDが存在しない場合、またはURLが外部文書を指す場合、 UAはそれをエラーとして扱う必要があります。

エラー処理をどうするべきか?

当面は構文上ローカル参照のみに制限。

HTML:
…これは "#chapter4_sec2">ページで議論されます。

CSS:

a::after { content: target-counter(attr(href url), page) }

結果:

…これは 137ページで議論されます。
目次のページ番号も自動生成できます:

HTML:

<nav>
  <ol>
   <li class="frontmatter"><a href="#pref_01">序文</a></li>
   <li class="frontmatter"><a href="#intr_01">はじめに</a></li>
   <li class="bodymatter"><a href="#chap_01">第1章</a></li>
  </ol>
</nav>

CSS:

.frontmatter a::after { content: leader('.') target-counter(attr(href url), page, lower-roman) }
.bodymatter a::after { content: leader('.') target-counter(attr(href url), page, decimal) }

結果:

序文.............vii
はじめに.........xi
第1章.............1

2.6.2. target-counters()関数

この関数は、リンク先のすべての指定カウンター値を取得し、各カウンター値の間に指定した文字列を挿入してフォーマット表示します。

target-counters() = target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )
現時点では target-counters() の良い例が見つかっていません。

CSS仕様で良い例を発見。対応を検討中。

2.6.3. target-text()関数

target-text()関数は、URLで参照される要素のテキスト値を取得します。 省略可能な第2引数で、取得する内容を指定でき、これはstring-setプロパティと同じ値です。

target-text() = target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )

fantasaiによる簡易構文提案あり: https://lists.w3.org/Archives/Public/www-style/2012Feb/0745.html

…これは "#chapter_h1_1">後で説明します。

a::after { content: ", 「" target-text(attr(href url)) "」章で"; }

結果:…これは後で説明します、「Loomings」章で。

2.7. 名前付き文字列

このセクションでは名前付き文字列について説明します。 これはカウンターのテキスト相当で、カウンターとは独立した名前空間になります。 名前付き文字列もカウンターと同じ入れ子規則に従います。 string-setプロパティは contentプロパティと似た値を受け取れ、カウンター値の抽出も可能です。

名前付き文字列は、メタデータを文書から抜き出してヘッダーやフッターに入れる便利な方法です。 例えばHTMLでは、ドキュメントのHEAD内にMETA要素があり、 名前付き文字列の値を設定できます。 属性セレクタと組み合わせることで強力なメカニズムになります:

meta[author] { string-set: author attr(author); }
head > title { string-set: title contents; }
@page:left {
  @top {
   text-align: left;
   vertical-align: middle;
   content: string(title);
  }
}
@page:right {
  @top {
   text-align: right;
   vertical-align: middle;
   content: string(author);
  }
}

2.7.1. 名前付け: string-setプロパティ

名前: string-set
値: none | [ <custom-ident> <string>+ ]#
初期値: none
適用対象: すべての要素、疑似要素には適用されません
継承: no
パーセンテージ: N/A
算出値: キーワードnone、または各識別子+文字列値リストのリスト
標準順序: 構文通り
アニメーション型: 離散型

ユーザーエージェントは視覚的でないものも含め全てのメディアでこのプロパティに対応することが期待されます。

string-setプロパティは要素のテキスト内容を名前付き文字列にコピーし、 変数として機能します。 この文字列値はstring()関数で取得できます。 ページごとに変数値が変わる場合があり、 string()関数の第2引数でどの値を使うか指定できます。

none
この要素は名前付き文字列を設定しません。
[ <custom-ident> <string>+ ]#
要素は1つ以上の名前付き文字列を、リスト内の各コンマ区切りエントリにより確立します。

各エントリの<custom-ident>は文字列名です。 これに1つ以上の<string>値が続き、結合されて名前付き文字列の値となります。

要素がスタイル制御を持つ場合、 当該要素の子孫にはstring-setプロパティは効果を持ちません。

次の例は、この仮想文書で章名を表すH1要素の内容を取得しています。
H1 { string-set: chapter contents; }

H1要素が現れた時、chapter文字列にその要素のテキスト内容が代入され、 以前の値は上書きされます。

2.7.2. 名前付き文字列の挿入: string()関数

string() = string( <custom-ident> , [ first | start | last | first-except ]? )

string() 関数は、名前付き文字列の値をcontentプロパティ経由で文書に挿入するために使います。 この関数は1つ目の引数として文字列名が必要です。 ページ内で値が複数回変化する場合(文字列定義要素が複数現れる場合)、 省略可能な第2引数でどの値を使うか指定できます。

string()関数の第2引数は以下いずれかのキーワードです:

first
ページ内の最初の代入値を使用します。 ページ内に代入がない場合、entry valueが使われます。 第2引数を指定しない場合、これがデフォルト値です。
start
要素がページで最初の要素なら、最初の代入値を使用。 そうでなければentry valueを使用します。 entry valueは、名前付き文字列がまだ現れていなければ空になることがあります。
last
名前付き文字列のexit valueを使用します。
first-except
firstと同じですが、 代入されたページでは空文字列となります。

内容文字列全体を削除すべきかどうか検討中。

名前付き文字列の値は、要素の内容ボックスが初めて作成された時(display値がnoneでもボックスが作成されるはずなら)に代入されます。 ページのentry valueは前ページ終了時の代入値、 exit valueは当ページ終了時の代入値です。

CSS:
@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 の代入値を示しています。

start値は、ページ開始時点で文字列がまだ設定されていないため空です。
ページ冒頭がh2要素なので、start値はそのタイトル値になります。
このページ冒頭にh2がなければ、start値は前ページのexit valueになります。

2.7.3. content() 関数

content() = content( [ text | before | after | first-letter | marker ]? )
text
要素の文字列値。 content() で値が指定されない場合、 text が指定されたものとして扱われます。
before
::before 疑似要素の文字列値。
after
::after 疑似要素の文字列値。
first-letter
::first-letter 疑似要素に定義された要素の最初の文字。
marker
::marker 疑似要素の文字列値。
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” になります。

HTML:
<section title="Loomings">

CSS:

section { string-set: header attr(title) }

“header” 文字列の値は “Loomings” となります。

2.8. 自動カウンターと番号付け

CSS Lists 3 § 4 自動カウンターによる番号付け を参照してください。

この内容をCSS Contentに戻すべきか?

3. ブックマーク

一部のドキュメント形式(PDFなど)では、ナビゲーション支援として ブックマーク が使用できます。 ブックマークはドキュメント要素へのリンク一覧と、リンク用ラベルテキスト、レベル値を提供します。 ブックマークには3つのプロパティがあります:bookmark-levelbookmark-labelbookmark-state

ユーザーがブックマークを操作すると、UAはその参照点をユーザーに示す必要があります(フラグメントURLでその要素へ移動する場合と同様)。 この操作は :target 疑似クラスにも一致することになります。

要素が style containmentを持つ場合、 bookmark-levelbookmark-labelbookmark-state はその子孫には効果を持ちません。

3.1. ブックマーク設定: bookmark-level プロパティ

bookmark-levelプロパティはブックマークの生成有無とレベルを決定します。 このプロパティがない場合や値がnoneなら、 bookmark-labelやbookmark-stateの値に関係なく、ブックマークは生成されません。

名前: bookmark-level
値: none | <integer [1,∞]>
初期値: none
適用対象: すべての要素
継承: no
パーセンテージ: N/A
算出値: キーワード none または 指定した整数値
標準順序: 構文通り
アニメーション型: 算出値型による
<integer [1,∞]>
ブックマークのレベルを定義します。最上位は1(負および0は無効)。
none
ブックマークは生成されません。
section h1 { bookmark-level: 1; }
section section h1 { bookmark-level: 2; }
section section section h1 { bookmark-level: 3; }

注: ブックマークは厳密な階層構造にする必要はありません。

display: noneの要素にもブックマークを生成すべき?

3.2. ブックマークラベル付け: bookmark-label プロパティ

名前: bookmark-label
値: <content-list>
初期値: content(text)
適用対象: すべての要素
継承: no
パーセンテージ: N/A
算出値: 指定値
標準順序: 構文通り
アニメーション型: 離散型
<content-list>
<content-list> の定義は上記 string-set の節を参照。 <content-list> の値がブックマークラベルのテキスト内容になります。
HTML:
<h1>Loomings</h1>

CSS:

h1 {
bookmark-label: content(text);
bookmark-level: 1;
}

ブックマークラベルは “Loomings” になります。

3.3. 初期ブックマーク切替状態: bookmark-state プロパティ

bookmark-stateは open または closed です。ユーザーはブックマーク状態を切り替え可能である必要があります。

名前: bookmark-state
値: open | closed
初期値: open
適用対象: ブロックレベル要素
継承: no
パーセンテージ: N/A
算出値: 指定キーワード
標準順序: 構文通り
アニメーション型: 離散型
open
以降の高い bookmark-level のブックマークは全て表示され、同じレベルまたは低いbookmarkに到達するまで継続します。 以降のブックマークが closed の場合、そのブックマーク以降の表示も同じ判定になります。
closed
以降の高い bookmark-level のブックマークは表示されません。同じレベルまたは低いbookmarkに到達するまで非表示です。

初期状態はUAが適宜更新するもの?

4. 変更点

2019年8月2日作業草案以降の主な変更は以下の通りです:

過去の変更点は previous changes も参照。

謝辞

Stuart Ballard、 David Baron、 Bert Bos、Tantek Çelik、 James Craig から本仕様に役立つ貴重なご意見をいただきました。

プライバシーに関する注意事項

本仕様には新たなプライバシー面の懸念事項は報告されていません。

セキュリティに関する注意事項

本仕様には新たなセキュリティ面の懸念事項は報告されていません。

適合性

文書上の慣例

適合性要件は、記述的な主張とRFC 2119用語を組み合わせて表現されています。規範部分で使用されている「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、RFC 2119で説明されているように解釈してください。 ただし、可読性のため、この仕様ではこれらのキーワードをすべて大文字とはしていません。

この仕様のテキスト全体は、特に非規範(informative)と明記されているセクション、例、注記以外はすべて規範です。[RFC2119]

この仕様の例は「例えば」などで始まるか、以下のようにclass="example"で区別されて示されます:

これは情報例のサンプルです。

情報ノートは「注」から始まり、class="note"で区別されます。例:

注:これは情報ノートです。

助言(Advisement)は強調した規範セクションであり、<strong class="advisement">で区別されます。例:UAは必ずアクセシビリティ代替手段を提供しなければなりません。

テスト

この仕様内容に関するテストはこのような「テスト」ブロックで記載される場合があります。 このようなブロックはすべて非規範です。


適合クラス

この仕様への適合は次の3つのクラスで定義されます:

スタイルシート
CSSスタイルシート
レンダラ
UA(CSSスタイルシートの意味を解釈し、文書を描画するもの)。
オーサリングツール
UA(スタイルシートを生成するツール)。

スタイルシートがこの仕様に適合するためには、本モジュールで定義された構文を使用するすべての文が、CSS一般文法および各機能の個別文法に従って正しい必要があります。

レンダラがこの仕様に適合するためには、スタイルシートを該当仕様の定義通り解釈するだけでなく、本仕様で定められた機能をすべて正しく解析し、文書を適切に描画することです。ただし、UAがデバイスの制約から正しく描画できなくても、非適合とはなりません(例:UAがモノクロモニタの場合、色表示は必須ではありません)。

オーサリングツールが適合するためには、CSS一般文法および本モジュールの各機能の個別文法に従い構文的に正しいスタイルシートを書き、本モジュールで説明されている他の適合要件も満たす必要があります。

部分的な実装

著者がフォールバック値を指定して前方互換パース規則を活用できるよう、CSSレンダラは、サポートされていないatルール、プロパティ、値、キーワード、その他の構文を必ず無効として扱い(必要に応じて無視)、十分なサポートがないものは処理しません。特にUAは、単一のプロパティ宣言に複数値が指定された場合、未サポート値のみ部分的に無視することなく、1つでも無効(未サポート値は無効と見なす)なら宣言全体を無視しなければなりません

不安定・独自機能の実装

将来の安定CSS機能との競合を避けるため、CSSWGは将来対応策のベストプラクティスに従い、不安定機能や独自拡張の実装を推奨します。

非実験的な実装

仕様が勧告候補(Candidate Recommendation)段階に達した時点で、非実験実装が可能となり、実装者は仕様通りに正しく実装できるCRレベルの機能は非接頭辞で公開するべきです。

CSSの実装間で互換性を確保するため、CSS作業グループは、非実験CSSレンダラが未接頭辞の実装を公開する前に、その実装レポート(必要ならテストケースも)をW3Cへ提出するよう要請しています。W3Cに提出されたテストケースはCSS作業グループが確認・修正します。

テストケースや実装報告書の提出方法はCSS作業グループのWebサイト https://www.w3.org/Style/CSS/Test/ で確認ください。質問は public-css-testsuite@w3.org メーリングリストへ。

索引

本仕様で定義されている用語

参照で定義されている用語

参考文献

標準参考文献

[CSS-CASCADE-5]
Elika Etemad・Miriam Suzanne・Tab Atkins Jr.。CSS Cascading and Inheritance Level 5。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONTAIN-2]
Tab Atkins Jr.・Florian Rivoal・Vladimir Levin。CSS Containment Module Level 2。2022年9月17日。WD。URL: https://www.w3.org/TR/css-contain-2/
[CSS-COUNTER-STYLES-3]
Tab Atkins Jr.。CSS Counter Styles Level 3。2021年7月27日。CR。URL: https://www.w3.org/TR/css-counter-styles-3/
[CSS-DISPLAY-4]
Elika Etemad・Tab Atkins Jr.。CSS Display Module Level 4。2025年11月6日。WD。URL: https://www.w3.org/TR/css-display-4/
[CSS-IMAGES-3]
Tab Atkins Jr.・Elika Etemad・Lea Verou。CSS Images Module Level 3。2023年12月18日。CRD。URL: https://www.w3.org/TR/css-images-3/
[CSS-IMAGES-4]
Elika Etemad・Tab Atkins Jr.・Lea Verou。CSS Images Module Level 4。2025年9月30日。WD。URL: https://www.w3.org/TR/css-images-4/
[CSS-LISTS-3]
Elika Etemad・Tab Atkins Jr.。CSS Lists and Counters Module Level 3。2020年11月17日。WD。URL: https://www.w3.org/TR/css-lists-3/
[CSS-PSEUDO-4]
Elika Etemad・Alan Stearns。CSS Pseudo-Elements Module Level 4。2025年6月27日。WD。URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-TEXT-4]
Elika Etemad・他。CSS Text Module Level 4。2024年5月29日。WD。URL: https://www.w3.org/TR/css-text-4/
[CSS-VALUES-3]
Tab Atkins Jr.・Elika Etemad。CSS Values and Units Module Level 3。2024年3月22日。CRD。URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.・Elika Etemad。CSS Values and Units Module Level 4。2024年3月12日。WD。URL: https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.・Elika Etemad・Miriam Suzanne。CSS Values and Units Module Level 5。2024年11月11日。WD。URL: https://www.w3.org/TR/css-values-5/
[CSS2]
Bert Bos・他。Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification。2011年6月7日。REC。URL: https://www.w3.org/TR/CSS2/
[CSS3-NAMESPACE]
Elika Etemad。CSS Namespaces Module Level 3。2014年3月20日。REC。URL: https://www.w3.org/TR/css-namespaces-3/
[CSS3-SPEECH]
Léonie Watson・Elika Etemad。CSS Speech Module Level 1。2023年2月14日。CRD。URL: https://www.w3.org/TR/css-speech-1/
[HTML]
Anne van Kesteren・他。HTML Standard。リビングスタンダード。URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner。Key words for use in RFCs to Indicate Requirement Levels。1997年3月。Best Current Practice。URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad・Tab Atkins Jr.。Selectors Level 4。2022年11月11日。WD。URL: https://www.w3.org/TR/selectors-4/

参考情報

[CLDR]
Unicode Common Locale Data Repository。URL: https://cldr.unicode.org/
[CSS-TEXT-3]
Elika Etemad・Koji Ishii・Florian Rivoal。CSS Text Module Level 3。2024年9月30日。CRD。URL: https://www.w3.org/TR/css-text-3/
[DOM]
Anne van Kesteren。DOM Standard。Living Standard。 URL: https://dom.spec.whatwg.org/

プロパティ一覧

名前 初期値 適用対象 継承 %値 アニメーション型 標準順序 算出値
bookmark-label <content-list> content(text) 全要素 no N/A 離散型 構文通り 指定値
bookmark-level none | <integer [1,∞]> none 全要素 no N/A 算出値型による 構文通り キーワードnoneまたは指定した整数
bookmark-state open | closed open ブロックレベル要素 no N/A 離散型 構文通り 指定キーワード
content normal | none | [ <content-replacement> | <content-list> ] [/ [ <string> | <counter> | <attr()> ]+ ]? normal 全要素・ツリー沿い疑似要素・ページマージンボックス no n/a 離散型 構文通り 下記説明参照
quotes auto | none | match-parent | [ <string> <string> ]+ auto 全要素 yes n/a 離散型 構文通り キーワードnone、auto、match-parent、または各項目が文字列ペアのリスト
string-set none | [ <custom-ident> <string>+ ]# none 全要素(疑似要素は不可) no N/A 離散型 構文通り キーワードnoneまたは各id+文字列リストのリスト

課題一覧

上記の不正な画像の挙動はChromeが採用しているものと同じです。 本当にこれでよいでしょうか? より良い挙動はあるでしょうか?
この値は、<content-list>として ::before::afterで扱われてきました。 Web互換性の要求があると思われるので、これらの疑似要素には例外が必要かもしれません。[Issue #2889]
contentsキーワードをcontent()に置き換えるべきでしょうか?
CSS用のAAM策定作業を開始すること。
CSS2.1ではUAが不正な画像の時に「壊れた画像」アイコンで代替することを許していたが、どのブラウザもこれをしていないようです。 この削除は問題ないでしょうか?
疑似要素に対し空文字列同様に振る舞うべきか?
要素の内容を抑制し、疑似要素で利用するユースケース募集中。
marker擬似要素についての記述は本当に必要か?旧仕様の遺産では?
2つのアプローチがあり、現在は後者を仕様化しています: a) これは関連する文字列値に算出され、そのまま継承される。 b) この値はキーワード+言語コードとして継承され、つまりautoだが言語は親から引き継ぐ。
リーダーは後続コンテンツが右揃え(右端揃え)であることを前提にしているか?
後コンテンツが行ボックスより幅広い場合どうすべきか?
リーダーは表レイアウトと完全には合わない。どう修正すべきか?
エラー処理をどうするべきか?
当面は構文上ローカル参照のみに制限。
CSS仕様で良い例を発見。対応を検討中。
fantasaiによる簡易構文提案あり: https://lists.w3.org/Archives/Public/www-style/2012Feb/0745.html
内容文字列全体を削除すべきかどうか検討中。
この内容をCSS Contentに戻すべきか?
display: noneの要素にもブックマークを生成すべき?
初期状態はUAが適宜更新するもの?