稳定性: 实验性
面向 CSS Grid 的保留模式布局(grid-template-areas)
可选启用的预览。 保留模式默认关闭。默认的
Streaming模式与一个从不知道该模式存在的构建字节完全一致。只为那些确实需要真正网格的文档开启它,并验证结果。
默认情况下,渲染器是单遍且流式的(参见 ADR-001)。一个用 grid-template-areas 声明的 CSS Grid 无法在一次前向遍历中放置,因此流式引擎会发出一个 HTML_GRID_REQUIRES_RETAINED 警告并回退到块流。保留模式就是用真正的布局取代该回退的可选开关:Config::withCssLayoutMode(CssLayoutMode::Retained) 会把一个确定列的 grid-template-areas 网格路由给 GridLayoutEngine,由它把子元素放入它们的命名单元格中。
composer require nextpdf/core:^3该布局模式随核心包一起分发。Config::withCssLayoutMode 这个可选开关是 @since 6.0.0。默认仍为 CssLayoutMode::Streaming。
概念总览
标题为“概念总览”的章节CssLayoutMode 是 Config 上的一个带类型枚举。Streaming 是默认值,也是一直以来的行为;Retained 把一份文档接入网格引擎。保留模式持有一个有界的保留节点集(retainedNodeBudget,默认 50,000,被钳制在 [5,000, 100,000]),使引擎能解析流式无法处理的网格——同时不放弃引擎的内存纪律。
当保留模式开启、且引擎遇到一个列为确定的 grid-template-areas 网格时,它会真正地把网格排布出来。确定列是固定长度、百分比,或针对内容宽度解析的 fr 单位。行会自动流动。子元素被指派到其区域名所选择的单元格中。
ADR-001 记录了流式不变量。对 ADR-001 的 2026-06-28 修订增加了一个保留-可选启用的豁免:流式默认未被触动,仍然是单遍模型;保留模式是针对网格情形的、显式有界的可选启用例外。
边界——保留模式排布什么,以及什么仍然回退
标题为“边界——保留模式排布什么,以及什么仍然回退”的章节保留模式处理确定列的 grid-template-areas 情形,且仅此一种。即便保留模式开启,其外的一切仍保留 HTML_GRID_REQUIRES_RETAINED 警告与块回退:
grid-auto-flow: column与grid-auto-flow: dense。subgrid。@container查询。- 自动或内在的列轨道(
auto、min-content、max-content)。
这些是被推迟的切片,而非沉默的缺口。一个依赖其中之一的网格会降级为块流并明确告知你。
Fail-closed 边界。 一处捕获宽度与引擎宽度不匹配——所测内容宽度与网格引擎据以解析的宽度不一致——会 fail closed,而不是产出一个错位的网格。保留模式还与 Safe CSS 渲染模式不兼容:CssRenderingMode::Safe 与 CssLayoutMode::Retained 组合时,会在配置校验阶段抛出 IncompatibleRenderingModeException。CssLayoutMode::Auto 为保留项,会抛出 NotImplementedException。
API 接口
标题为“API 接口”的章节| 符号 | 位置 | 角色 |
|---|---|---|
Config::withCssLayoutMode(CssLayoutMode $mode): self | src/Core/Config.php | 把一份文档接入 Streaming(默认)或 Retained 布局。 |
Config::withRetainedNodeBudget(int $budget): self | src/Core/Config.php | 限定保留节点集([5,000, 100,000],默认 50,000)。 |
Config::isRetainedMode(): bool | src/Core/Config.php | 报告该文档是否处于保留模式。 |
CssLayoutMode | src/Core/ | Streaming、Retained;Auto 为保留项(NotImplementedException)。 |
GridLayoutEngine | src/Html/ | 保留模式的网格放置引擎。 |
IncompatibleRenderingModeException | src/Exception/ | 当 Safe CSS 模式与保留模式组合时抛出。 |
代码范例——快速上手
标题为“代码范例——快速上手”的章节<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\CssLayoutMode;use NextPDF\Core\Document;
$config = (new Config())->withCssLayoutMode(CssLayoutMode::Retained);
$doc = Document::createStandalone($config);$doc->addPage();$doc->writeHtml( '<style>' . '.dashboard { display: grid; grid-template-columns: 1fr 2fr;' . ' grid-template-areas: "sidebar main"; }' . '.sidebar { grid-area: sidebar; } .main { grid-area: main; }' . '</style>' . '<div class="dashboard">' . ' <div class="sidebar">Navigation</div>' . ' <div class="main">Report content…</div>' . '</div>',);$doc->save(__DIR__ . '/grid.pdf');代码范例——正式环境
标题为“代码范例——正式环境”的章节在配置阶段检测不兼容模式的情形,并回读当前生效的模式,使路径明确。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\CssLayoutMode;use NextPDF\Core\Document;use NextPDF\Exception\IncompatibleRenderingModeException;
try { $config = (new Config()) ->withCssLayoutMode(CssLayoutMode::Retained) ->withRetainedNodeBudget(75_000); $config->validate();} catch (IncompatibleRenderingModeException $e) { // Safe CSS mode and retained mode cannot combine. Choose one. throw $e;}
$doc = Document::createStandalone($config);assert($config->isRetainedMode());
$doc->addPage();$doc->writeHtml($gridHtml);$doc->save($out);
// A grid that needs a deferred feature (column auto-flow, subgrid, @container,// or intrinsic columns) still emits HTML_GRID_REQUIRES_RETAINED and falls back// to block flow. Inspect the advisory channel.边界情况与陷阱
标题为“边界情况与陷阱”的章节- Streaming 仍为默认,且字节一致。 保留模式只为你显式接入的那份文档改变输出。
- 仅限确定列的
grid-template-areas。 列自动流动、密集打包、subgrid、@container与内在列仍保留HTML_GRID_REQUIRES_RETAINED警告与块回退。 - Safe 模式互斥。
CssRenderingMode::Safe加上CssLayoutMode::Retained会抛出IncompatibleRenderingModeException。 Auto为保留项。CssLayoutMode::Auto会抛出NotImplementedException;它目前还不是一个可用的第三选项。- 宽度不匹配会 fail closed。 一处捕获宽度与引擎内容宽度的不一致会被拒绝,而不是渲染错误。
保留模式持有的是一个有界的节点集,而非一棵完整的文档树;retainedNodeBudget(默认 50,000)为其设上限。网格放置在节点数与单元格数上呈线性。逐页的 performance_budget(wall_ms: 1500、peak_mb: 64)适用;当把节点预算朝其 100,000 上限提高时,大型网格应把该预算记在心上。
安全性注意事项
标题为“安全性注意事项”的章节保留模式不会扩大输入面。HTML 安全策略、CSS 属性允许清单与解析器上限均原样适用。保留节点预算本身就是一道资源耗尽边界:它为引擎为单份文档所持有的结构量设上限。
符合性
标题为“符合性”的章节| 主张 | 标准 | 条款 |
|---|---|---|
grid-template-areas 为网格单元格命名;命名区域放置项目。 | W3C CSS Grid Layout Module Level 1 | §7.3 |
显式的固定、百分比与 fr 轨道针对内容宽度确定尺寸。 | W3C CSS Grid Layout Module Level 1 | §7.2 |
这是一个确定列 grid-template-areas 子集的预览实现。逐属性的已验证状态记录在 CSS 支持矩阵中;此处不主张任何端到端符合性。未重制任何标准原文。