用 CSS 设置 HTML 样式
本篇 recipe(示例)会通过 inline style 属性和一个 <style> 块,将 CSS 应用到 HTML 内容。它也会演示如何在依赖某个属性之前,先确认它已通过验证。
composer require nextpdf/core:^3这个版本约束对应 nextpdf/core 包。这个示例在 PHP 8.4 上运行。
概念说明
标题为“概念说明”的章节HTML 引擎通过 CSS 阶层(cascade)解析(resolve)样式。阶层是一组规则;当多条规则指向同一个元素时,它会决定哪个样式胜出。引擎会先读取输入中的 <style> 块,再读取 inline style 属性。它会将两者都与元素匹配,并按照阶层顺序计算结果。支持矩阵将 CSS Cascading and Inheritance(阶层与继承)模块评为「Verified(已验证)」,这表示阶层与继承行为有一套专属的 fixture 测试套件支撑。
文本呈现属性,例如 text-align、text-indent 和 letter-spacing,来自 CSS Text 模块的属性表(W3C CSS Text Level 3)。字体选择采用 CSS Fonts 模型。font 简写会一次设置 font-style、font-variant、font-weight、font-size 和 font-family(W3C CSS Fonts Level 3)。
支持状态会跟随各个 W3C 模块,并经过真实性审核。已实现但没有专属模块 fixture 的属性,会被评为「Claimed(已声明)」,而不是「Verified」。请将「Claimed」视为尽力支持,并针对你的内容验证视觉结果。请将「Verified」视为有一套已通过的 fixture 测试套件支撑。
API 接口
标题为“API 接口”的章节你会通过传给 writeHtml(string $html): static 的 HTML 来驱动所有样式(NextPDF\Core\Concerns\HasTextOutput)。没有独立的 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');代码范例 — 正式环境
标题为“代码范例 — 正式环境”的章节这个示例是自包含的,可在 harness 中运行。它会演练一个 <style> 块、类选择器、inline 样式,以及 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 astyle block.</p>
<p class="callout">This paragraph has a background, padding, and a borderfrom a class selector.</p>
<p class="centered" style="font-weight: bold;">Centered, with an inlineoverride 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边界情况与陷阱
标题为“边界情况与陷阱”的章节- 阶层顺序。 按照阶层规则,inline
style会胜过具有相同特定性(specificity)的<style>块选择器。如果看到不符合预期的颜色,请先检查是否存在 inline 覆盖。 - Claimed 与 Verified 的差别。
text-align、text-indent和color在矩阵中评为「Claimed」。它们已实现,但没有专属的模块 fixture。它们会绘制出来,但在正式环境签核前,请验证其视觉输出。 - 没有保留树状结构。 串流引擎(ADR-001)不保留任何文档树,因此无法应用「由后面的兄弟元素重新设置前面元素样式」的选择器。与顺序无关的选择器会受到限制。
- 不支持的属性。 不支持的属性会被忽略,而不会引发错误。在依赖它之前,请先对照矩阵确认。
- 色彩空间。 Lab、LCH 和 OKLab 值会被解析,但这些函数的 PDF 色彩空间保真度尚未断言(矩阵中:CSS Color 4 为「Claimed」)。
阶层解析是单一处理流程的一部分。成本与 token 数量保持线性关系,为 O(n)。预算为 wall_ms: 1500, peak_mb: 96。<style> 块会增加一次性的选择器解析成本,这个成本与规则数量成正比。
CSS 支持矩阵摘录(仅 Verified 列)
标题为“CSS 支持矩阵摘录(仅 Verified 列)”的章节这份摘录仅列出经过真实性审核的 Verified 条目,这些条目来自 CSS 支持矩阵。
| W3C 模块 | 层级 | 状态 | 证据 |
|---|---|---|---|
CSS Cascading and Inheritance 阶层与继承(css_cascade_3) | 3 | 已验证 | src/Html/Cascade/、tests/Unit/Html/Cascade/ |
CSS Cascading 阶层(css_cascade_4) | 4 | 已验证 | Cascade/Layer/ 以及 revert/layer 测试 |
CSS Cascading 阶层(css_cascade_5) | 5 | 已验证 | AtRule/Layer/ 以及 Cascade/Layer/ 测试套件 |
CSS Fonts 字体(css_fonts_3) | 3 | 已验证 | src/Html/Font/、tests/Unit/Font/ 以及 FontResolver 测试 |
CSS Fonts 字体(css_fonts_4) | 4 | 已验证 | src/Html/FontFace/、tests/Unit/Html/FontFace/ |
text-align、text-indent、color 和 background-color 在矩阵中为「Claimed」。表格有意将它们排除在 Verified 条目之外。
单一处理流程的串流限制(ADR-001)
标题为“单一处理流程的串流限制(ADR-001)”的章节阶层会在一份串流 token 清单上运行,没有 DOM,因此选择器会根据文档顺序上下文进行解析。整棵树状结构相关的选择器场景受 ADR-006 限制。请编写只依赖文档顺序与祖先上下文的 CSS。
Layer 合约(ADR-010)
标题为“Layer 合约(ADR-010)”的章节CSS 解析属于阶层层,而版面配置分派不得直接读取原始的 $css[...] 值。对外公开的接口是 HTML 输入。没有任何受支持的方式可以越过阶层注入已计算的样式。
大型文档的内存预算
标题为“大型文档的内存预算”的章节阶层会保留当前生效的规则集,以及入栈与出栈的样式堆栈,而不是节点树。容器范围的上下文会遵守 ADR-020 的预算(每个上下文 5,000 个节点,作用中内存上限 50 MB)。大型样式表会使规则集内存线性增长,因此请将选择器数量控制在有限范围内。
安全性注意事项
标题为“安全性注意事项”的章节不受信任的 HTML 中的 CSS 无法执行代码,但它会影响版面配置与资源参照(例如 background-image)。默认外部资源政策不会抓取任意远程 URL。绘制之前,请先清理任何由用户输入组成的 HTML 与 CSS。
符合性
标题为“符合性”的章节| 陈述 | 规范 | 条款 | 参考 ID(reference_id) |
|---|---|---|---|
| 文本属性(text-align、text-indent、letter-spacing)由 CSS Text 属性表定义。 | W3C CSS Text Level 3(文本模块) | css_text_3#x1.x24(条款) | |
| font 简写会设置 font-style、font-variant、font-weight、font-size 与 font-family。 | W3C CSS Fonts Level 3(字体模块) | css_fonts_3#x2.x6.x7.p2(条款) |
这篇 recipe 演示 NextPDF 如何应用受支持的 CSS 子集;它并不声称支持完整的 CSS。如需查看各模块经验证的支持状态,请参阅 CSS 支持矩阵。
商业情境
标题为“商业情境”的章节不适用。