стабильность: Экспериментальная
Вёрстка с сохранением для CSS Grid (grid-template-areas)
Подключаемое превью. Режим с сохранением по умолчанию выключен. Режим
Streamingпо умолчанию даёт побайтово идентичный результат сборке, которая никогда не знала о существовании этого режима. Включайте его только для документов, которым нужна настоящая сетка, и проверяйте результат.
По умолчанию рендерер однопроходный и потоковый (см. ADR-001).
Сетку CSS Grid, объявленную через grid-template-areas, нельзя разместить за один
прямой проход, поэтому потоковый движок выдаёт предупреждение
HTML_GRID_REQUIRES_RETAINED и откатывается к блочному потоку. Режим с
сохранением — это подключаемая опция, которая заменяет этот запасной вариант
настоящей вёрсткой: Config::withCssLayoutMode(CssLayoutMode::Retained)
направляет сетку grid-template-areas с определёнными колонками через
GridLayoutEngine, который размещает дочерние элементы в их именованные ячейки.
Установка
Заголовок раздела «Установка»composer require nextpdf/core:^3Режим вёрстки поставляется в пакете core. Подключаемая опция
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 фиксирует инвариант потоковости. Поправка от 2026-06-28 к ADR-001 добавляет исключение для подключаемого режима с сохранением: потоковое поведение по умолчанию не затрагивается и остаётся однопроходной моделью; режим с сохранением — это явно ограниченное, подключаемое исключение для случая сетки.
Граница — что размещает режим с сохранением, а что по-прежнему откатывается
Заголовок раздела «Граница — что размещает режим с сохранением, а что по-прежнему откатывается»Режим с сохранением обрабатывает случай grid-template-areas с определёнными
колонками и только его. Всё за его пределами сохраняет предупреждение
HTML_GRID_REQUIRES_RETAINED и блочный запасной вариант даже при включённом
режиме с сохранением:
grid-auto-flow: columnиgrid-auto-flow: dense.subgrid.- Запросы
@container. - Автоматические или внутренние дорожки колонок (
auto,min-content,max-content).
Это отложенные слои, а не скрытые пробелы. Сетка, зависящая от одного из них, деградирует к блочному потоку и сообщает вам об этом.
Граница с отказом закрытием. Несовпадение ширины захвата и движка —
измеренная ширина содержимого не согласуется с шириной, относительно которой
разрешает сетку движок, — отказывает закрытием, а не выдаёт сетку со смещением.
Режим с сохранением также несовместим с режимом рендеринга 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; это пока не пригодный третий вариант.- Несовпадение ширины отказывает закрытием. Расхождение ширины содержимого между захватом и движком отклоняется, а не рендерится неверно.
Производительность
Заголовок раздела «Производительность»Режим с сохранением держит ограниченный набор узлов, а не полное дерево
документа; 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; сквозное соответствие
здесь не заявляется. Текст стандартов не воспроизводится.