Ga naar inhoud
getnextpdf.com

stabiliteit: Experimenteel

Retained-mode lay-out voor CSS Grid (grid-template-areas)

Opt-in preview. Retained-modus staat standaard uit. De standaard Streaming-modus is byte-identiek aan een build die deze modus nooit heeft gekend. Zet hem alleen aan voor de documenten die een echt grid nodig hebben, en valideer het resultaat.

Standaard is de renderer single-pass en streaming (zie ADR-001). Een CSS Grid gedeclareerd met grid-template-areas kan niet in één voorwaartse pass worden geplaatst, dus geeft de streaming-engine een HTML_GRID_REQUIRES_RETAINED-waarschuwing af en valt terug op blokflow. Retained-modus is de opt-in die die terugval vervangt door een echte lay-out: Config::withCssLayoutMode(CssLayoutMode::Retained) routeert een grid-template-areas-grid met definite columns via de GridLayoutEngine, die kinderen in hun named cells plaatst.

Terminal window
composer require nextpdf/core:^3

De lay-outmodus wordt meegeleverd in het core-pakket. De Config::withCssLayoutMode-opt-in is @since 6.0.0. De standaard blijft CssLayoutMode::Streaming.

CssLayoutMode is een getypeerde enum op Config. Streaming is de standaard en het historische gedrag; Retained schakelt een document in voor de grid-engine. Retained-modus houdt een begrensde behouden node-set vast (de retainedNodeBudget, standaard 50,000, geklemd op [5,000, 100,000]) zodat de engine een grid kan oplossen dat streaming niet kan — zonder de geheugendiscipline van de engine los te laten.

Wanneer retained-modus aan staat en de engine een grid-template-areas-grid tegenkomt waarvan de kolommen definite zijn, maakt hij het grid echt op. Definite columns zijn vaste lengtes, percentages of fr-eenheden opgelost tegen de contentbreedte. Rijen stromen automatisch. Kinderen worden toegewezen aan de cellen die hun area-namen selecteren.

ADR-001 legt het streaminginvariant vast. Het amendement van 2026-06-28 op ADR-001 voegt een retained-opt-in-uitzondering toe: de streamingstandaard blijft onaangetast en behoudt het single-pass-model; retained-modus is een expliciet begrensde, opt-in-uitzondering voor het grid-geval.

Grens — wat retained-modus opmaakt, en wat nog terugvalt

Sectie met titel “Grens — wat retained-modus opmaakt, en wat nog terugvalt”

Retained-modus handelt het grid-template-areas-geval met definite columns af, en alleen dat geval. Alles daarbuiten behoudt de HTML_GRID_REQUIRES_RETAINED-waarschuwing en de blokterugval, zelfs met retained-modus aan:

  • grid-auto-flow: column en grid-auto-flow: dense.
  • subgrid.
  • @container-query’s.
  • Auto- of intrinsieke kolomtracks (auto, min-content, max-content).

Dit zijn uitgestelde delen, geen stille leemtes. Een grid dat van een ervan afhangt, degradeert naar blokflow en laat je dat weten.

Fail-closed-grens. Een mismatch tussen vastlegging en engine in de breedte — de gemeten contentbreedte die niet overeenkomt met de breedte waartegen de grid-engine oplost — faalt gesloten in plaats van een verkeerd geplaatst grid te produceren. Retained-modus is ook incompatibel met de Safe CSS-renderingmodus: CssRenderingMode::Safe gecombineerd met CssLayoutMode::Retained werpt IncompatibleRenderingModeException bij de configuratievalidatie. CssLayoutMode::Auto is gereserveerd en werpt NotImplementedException.

SymboolLocatieRol
Config::withCssLayoutMode(CssLayoutMode $mode): selfsrc/Core/Config.phpSchakelt een document in voor Streaming (standaard) of Retained lay-out.
Config::withRetainedNodeBudget(int $budget): selfsrc/Core/Config.phpBegrenst de behouden node-set ([5,000, 100,000], standaard 50,000).
Config::isRetainedMode(): boolsrc/Core/Config.phpMeldt of het document in retained-modus is.
CssLayoutModesrc/Core/Streaming, Retained; Auto gereserveerd (NotImplementedException).
GridLayoutEnginesrc/Html/De behouden grid-plaatsingsengine.
IncompatibleRenderingModeExceptionsrc/Exception/Gegooid wanneer de Safe CSS-modus met retained-modus wordt gecombineerd.
<?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');

Detecteer het incompatibele-modusgeval op configuratietijd, en lees de actieve modus terug zodat het pad expliciet is.

<?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 blijft de standaard en is byte-identiek. Retained-modus verandert de uitvoer alleen voor het document waarvoor je het inschakelt.
  • Alleen grid-template-areas met definite columns. Kolom-auto-flow, dense packing, subgrid, @container en intrinsieke kolommen behouden de HTML_GRID_REQUIRES_RETAINED-waarschuwing en de blokterugval.
  • Safe mode is wederzijds uitsluitend. CssRenderingMode::Safe plus CssLayoutMode::Retained gooit IncompatibleRenderingModeException.
  • Auto is gereserveerd. CssLayoutMode::Auto werpt NotImplementedException; het is nog geen bruikbare derde optie.
  • Breedtemismatch faalt gesloten. Een onenigheid in de contentbreedte tussen vastlegging en engine wordt geweigerd, niet verkeerd weergegeven.

Retained-modus houdt een begrensde node-set vast in plaats van een volledige documentboom; de retainedNodeBudget (standaard 50,000) begrenst die. Grid-plaatsing is lineair in het node- en celaantal. Het performance_budget per pagina (wall_ms: 1500, peak_mb: 64) geldt; grote grids moeten het budget in gedachten houden bij het verhogen van het node-budget richting het plafond van 100,000.

Retained-modus verbreedt het invoeroppervlak niet. Het HTML-beveiligingsbeleid, de CSS-eigenschappenallowlist en de parsercaps gelden onveranderd. Het behouden node-budget is zelf een grens tegen het uitputten van bronnen: het begrenst hoeveel structuur de engine voor één document zal vasthouden.

StatementSpecClause
grid-template-areas benoemt grid-cellen; named areas plaatsen items.W3C CSS Grid Layout Module Level 1§7.3
Expliciete vaste, percentage- en fr-tracks krijgen hun grootte tegen de contentbreedte.W3C CSS Grid Layout Module Level 1§7.2

Dit is een previewimplementatie van een grid-template-areas-subset met definite columns. De geverifieerde status per eigenschap wordt bijgehouden in de CSS-ondersteuningsmatrix; hier wordt geen end-to-end-conformiteit geclaimd. Er wordt geen standaardtekst gereproduceerd.