コンテンツにスキップ

CSS で HTML をスタイリングする

このレシピでは、インラインの style 属性と <style> ブロックを使い、HTML コンテンツに CSS を適用します。あわせて、プロパティの利用を前提にする前に、そのサポートが検証済みかを確認する方法も示します。

Terminal window
composer require nextpdf/core:^3

このバージョン制約は nextpdf/core パッケージに対応しています。この例は PHP 8.4 で動作します。

HTML エンジンは、CSS のカスケードによってスタイルを解決(resolve)します。カスケードとは、複数のルールが同じ要素を対象にする場合に、どのスタイルを優先するかを決める一連のルールです。エンジンは、まず入力内の <style> ブロックを読み取り、続いてインラインの style 属性を読み取ります。その両方を要素に照合し、カスケード順に結果を計算します。サポートマトリックスでは、CSS Cascading and Inheritance モジュールを Verified と評価しています。これは、専用のフィクスチャスイートがカスケードと継承の動作を裏付けていることを意味します。

テキスト表現プロパティ(text-aligntext-indentletter-spacing など)は、CSS Text モジュールのプロパティテーブル(W3C CSS Text Level 3)に由来します。フォントの選択には CSS Fonts モデルを使用します。font ショートハンドは、font-stylefont-variantfont-weightfont-sizefont-family をまとめて設定します(W3C CSS Fonts Level 3)。

サポート状況は各 W3C モジュールに沿って示され、事実に基づいて監査されています。実装済みでも専用のモジュールフィクスチャを持たないプロパティは、「Verified」ではなく「Claimed」と評価されます。「Claimed」はベストエフォートとして扱い、ご自身のコンテンツで表示結果を検証してください。「Verified」は、合格済みのフィクスチャスイートによって裏付けられているものとして扱ってください。

すべてのスタイリングは、writeHtml(string $html): staticNextPDF\Core\Concerns\HasTextOutput)に渡す HTML を通じて制御されます。独立した CSS API は存在せず、カスケードは内部で実行されます。完全な PHPDoc テーブルはソースから生成されます。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->writeHtml(
'<style>.lead { color: #1E3A8A; text-align: center; }</style>'
. '<p class="lead">Styled with a style block.</p>'
);
$doc->save(__DIR__ . '/out.pdf');

この例は自己完結型で、実行ハーネスから実行できます。ここでは、<style> ブロック、クラスセレクター、インラインスタイル、さらに font のファミリーとウェイトの処理パスを確認します。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('CSS Styling');
$doc->addPage();
$html = <<<'HTML'
<style>
h1 { color: #1E3A8A; }
.lead { color: #D97706; font-size: 14px; }
.callout { background-color: #EFF6FF; padding: 8px; border: 1px solid #BFDBFE; }
.centered { text-align: center; }
</style>
<h1>Styling HTML with CSS</h1>
<p class="lead">This paragraph is styled through a class selector in a
style block.</p>
<p class="callout">This paragraph has a background, padding, and a border
from a class selector.</p>
<p class="centered" style="font-weight: bold;">Centered, with an inline
override for weight.</p>
<p style="color: #6B7280; font-size: 9px;">Inline style only.</p>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/style-with-css.pdf');
echo "Wrote style-with-css.pdf\n";

想定される STDOUT:

Wrote style-with-css.pdf
  • カスケード順。 カスケード順では、同じ詳細度の場合、インライン style<style> ブロックのセレクターよりも優先されます。予期しない色が表示される場合は、まずインラインでの上書きがないか確認してください。
  • Claimed と Verified の違い。 text-aligntext-indentcolor は、マトリックスで「Claimed」と評価されています。これらは実装され、描画もされますが、専用のモジュールフィクスチャはありません。プロダクションで承認する前に表示出力を検証してください。
  • 保持されるツリーなし。 ストリーミングエンジン(ADR-001)はドキュメントツリーを保持しないため、後続の兄弟要素が先行する要素のスタイルを変更するようなセレクターは適用できません。順序に依存しないセレクターには制約があります。
  • 未サポートのプロパティ。 未サポートのプロパティは、エラーを発生させずに無視されます。使用を前提にする前に、マトリックスで確認してください。
  • 色空間。 Lab、LCH、OKLab の値は解析されますが、これらの関数に対する PDF 色空間での忠実度は保証されません(マトリックス:CSS Color 4 は「Claimed」)。

カスケードの解決はシングルパス処理の一部です。コストはトークン数に対して線形 O(n) のままです。バジェットは wall_ms: 1500, peak_mb: 96 です。<style> ブロックは、ルール数に比例する一回限りのセレクター解析コストを追加します。

この抜粋は、事実に基づいて監査された CSS サポートマトリックス から、Verified の行のみを再掲したものです。

W3C モジュールレベルステータスエビデンス
CSS Cascading and Inheritance (css_cascade_3)3Verifiedsrc/Html/Cascade/, tests/Unit/Html/Cascade/
CSS Cascading (css_cascade_4)4VerifiedCascade/Layer/ + revert/layer テスト
CSS Cascading (css_cascade_5)5VerifiedAtRule/Layer/ + Cascade/Layer/ スイート
CSS Fonts (css_fonts_3)3Verifiedsrc/Html/Font/, tests/Unit/Font/ + FontResolver テスト
CSS Fonts (css_fonts_4)4Verifiedsrc/Html/FontFace/, tests/Unit/Html/FontFace/

text-aligntext-indentcolorbackground-color は、マトリックスで「Claimed」となっています。 この表では、これらを意図的に Verified の行から除外しています。

カスケードは DOM を持たない、ストリーム化されたトークンリスト上で実行されるため、セレクターはドキュメント順のコンテキストに対して解決されます。ツリー全体を対象とするセレクターの扱いは、ADR-006 により制約されます。ドキュメント順と祖先コンテキストのみに依存する CSS を記述してください。

CSS の解析はカスケードレイヤーに属しており、レイアウトのディスパッチが生の $css[...] 値を直接読み取ってはなりません。公開サーフェスは HTML 入力です。カスケード後に計算済みスタイルを挿入する方法は、サポートされていません。

カスケードは、ノードツリーではなく、アクティブなルールセットと、プッシュおよびポップされるスタイルスタックを保持します。コンテナースコープのコンテキストは、ADR-020 のバジェット(コンテキストあたり 5,000 ノード、アクティブ時の上限 50 MB)に従います。大規模なスタイルシートはルールセットのメモリを線形に増加させるため、セレクター数は一定範囲に抑えてください。

信頼できない HTML 内の CSS はコードを実行できませんが、レイアウトやリソース参照(たとえば background-image)に影響を与える可能性があります。デフォルトの外部リソースポリシーでは、任意のリモート URL を取得しません。ユーザー入力から組み立てる HTML や CSS は、レンダリング前にサニタイズしてください。

記述仕様条項リファレンス ID
テキストプロパティ (text-align、text-indent、letter-spacing) は、CSS Text のプロパティテーブルで定義されています。W3C CSS Text Level 3css_text_3#x1.x24
font ショートハンドは、font-style、font-variant、font-weight、font-size、font-family を設定します。W3C CSS Fonts Level 3css_fonts_3#x2.x6.x7.p2

このレシピは、NextPDF がサポートする CSS のサブセットの適用方法を示すものであり、CSS の完全なサポートを主張するものではありません。モジュールごとの検証済みステータスについては、CSS サポートマトリックスを参照してください。

該当なし。