Zum Inhalt springen
getnextpdf.com

Stabilität: Experimentell

Retained-Mode-Layout für CSS Grid (grid-template-areas)

Per Opt-in aktivierbare Vorschau. Der Retained-Modus ist standardmäßig aus. Der Standardmodus Streaming ist byte-identisch zu einem Build, der diesen Modus nie kannte. Schalten Sie ihn nur für die Dokumente ein, die ein echtes Grid benötigen, und validieren Sie das Ergebnis.

Standardmäßig arbeitet der Renderer single-pass und streamend (siehe ADR-001). Ein mit grid-template-areas deklariertes CSS Grid kann nicht in einem einzigen Vorwärtsdurchlauf platziert werden, sodass die Streaming-Engine eine HTML_GRID_REQUIRES_RETAINED-Warnung ausgibt und auf Block-Fluss zurückfällt. Der Retained-Modus ist das Opt-in, das diesen Fallback durch ein echtes Layout ersetzt: Config::withCssLayoutMode(CssLayoutMode::Retained) leitet ein grid-template-areas-Grid mit definiten Spalten durch die GridLayoutEngine, die Kinder in ihre benannten Zellen platziert.

Terminal-Fenster
composer require nextpdf/core:^3

Der Layout-Modus wird im Core-Paket ausgeliefert. Das Opt-in Config::withCssLayoutMode ist @since 6.0.0. Der Standard bleibt CssLayoutMode::Streaming.

CssLayoutMode ist ein typisiertes Enum auf Config. Streaming ist der Standard und das historische Verhalten; Retained aktiviert für ein Dokument die Grid-Engine. Der Retained-Modus hält eine begrenzte Menge gehaltener Knoten (das retainedNodeBudget, Standard 50,000, geklemmt auf [5,000, 100,000]), sodass die Engine ein Grid auflösen kann, das Streaming nicht kann — ohne die Speicherdisziplin der Engine aufzugeben.

Ist der Retained-Modus aktiv und trifft die Engine auf ein grid-template-areas-Grid, dessen Spalten definit sind, bricht sie das Grid echt um. Definite Spalten sind feste Längen, Prozentwerte oder fr-Einheiten, die gegen die Inhaltsbreite aufgelöst werden. Zeilen fließen automatisch. Kinder werden den Zellen zugewiesen, die ihre Bereichsnamen auswählen.

ADR-001 hält die Streaming-Invariante fest. Die Ergänzung vom 28.06.2026 zu ADR-001 fügt eine Retained-Opt-in-Ausnahme hinzu: Der Streaming-Standard bleibt unangetastet und das Single-Pass-Modell; der Retained-Modus ist eine explizit begrenzte, per Opt-in aktivierbare Ausnahme für den Grid-Fall.

Grenze — was der Retained-Modus umbricht und was weiterhin zurückfällt

Abschnitt betitelt „Grenze — was der Retained-Modus umbricht und was weiterhin zurückfällt“

Der Retained-Modus verarbeitet den grid-template-areas-Fall mit definiten Spalten und nur diesen Fall. Alles außerhalb davon behält die HTML_GRID_REQUIRES_RETAINED-Warnung und den Block-Fallback, selbst bei aktivem Retained-Modus:

  • grid-auto-flow: column und grid-auto-flow: dense.
  • subgrid.
  • @container-Queries.
  • Automatische oder intrinsische Spalten-Tracks (auto, min-content, max-content).

Dies sind zurückgestellte Teilmengen, keine stillen Lücken. Ein Grid, das von einer davon abhängt, degradiert zu Block-Fluss und teilt Ihnen das mit.

Fail-closed-Grenze. Eine Abweichung zwischen Erfassung und Engine bei der Breite — die gemessene Inhaltsbreite stimmt nicht mit der Breite überein, gegen die die Grid-Engine auflöst — schlägt fail-closed fehl, statt ein fehlplatziertes Grid zu erzeugen. Der Retained-Modus ist außerdem mit dem Safe-CSS-Rendering-Modus inkompatibel: CssRenderingMode::Safe kombiniert mit CssLayoutMode::Retained löst bei der Konfigurationsvalidierung IncompatibleRenderingModeException aus. CssLayoutMode::Auto ist reserviert und löst NotImplementedException aus.

SymbolOrtRolle
Config::withCssLayoutMode(CssLayoutMode $mode): selfsrc/Core/Config.phpAktiviert für ein Dokument das Layout Streaming (Standard) oder Retained.
Config::withRetainedNodeBudget(int $budget): selfsrc/Core/Config.phpBegrenzt die Menge gehaltener Knoten ([5,000, 100,000], Standard 50,000).
Config::isRetainedMode(): boolsrc/Core/Config.phpMeldet, ob das Dokument im Retained-Modus ist.
CssLayoutModesrc/Core/Streaming, Retained; Auto reserviert (NotImplementedException).
GridLayoutEnginesrc/Html/Die Retained-Grid-Platzierungs-Engine.
IncompatibleRenderingModeExceptionsrc/Exception/Wird geworfen, wenn der Safe-CSS-Modus mit dem Retained-Modus kombiniert wird.
<?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');

Erkennen Sie den Fall des inkompatiblen Modus zur Konfigurationszeit und lesen Sie den aktiven Modus zurück, damit der Pfad explizit ist.

<?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 bleibt der Standard und ist byte-identisch. Der Retained-Modus ändert die Ausgabe nur für das Dokument, das Sie per Opt-in aktivieren.
  • Nur grid-template-areas mit definiten Spalten. Spalten-Auto-Flow, dichtes Packen, Subgrid, @container und intrinsische Spalten behalten die HTML_GRID_REQUIRES_RETAINED-Warnung und den Block-Fallback.
  • Der Safe-Modus schließt sich gegenseitig aus. CssRenderingMode::Safe plus CssLayoutMode::Retained wirft IncompatibleRenderingModeException.
  • Auto ist reserviert. CssLayoutMode::Auto löst NotImplementedException aus; es ist noch keine nutzbare dritte Option.
  • Breitenabweichung schlägt fail-closed fehl. Eine Inhaltsbreiten-Abweichung zwischen Erfassung und Engine wird verweigert, nicht falsch gerendert.

Der Retained-Modus hält eine begrenzte Knotenmenge statt eines vollständigen Dokumentbaums; das retainedNodeBudget (Standard 50,000) deckelt sie. Die Grid-Platzierung ist linear in der Knoten- und Zellenzahl. Das performance_budget pro Seite (wall_ms: 1500, peak_mb: 64) gilt; bei großen Grids sollte man das Budget im Blick behalten, wenn das Knotenbudget in Richtung seiner Obergrenze von 100,000 angehoben wird.

Der Retained-Modus weitet die Eingabeoberfläche nicht aus. Die HTML-Sicherheitsrichtlinie, die Allowlist der CSS-Eigenschaften und die Parser-Limits gelten unverändert. Das Retained-Node-Budget ist selbst eine Schranke gegen Ressourcenerschöpfung: Es deckelt, wie viel Struktur die Engine für ein einzelnes Dokument halten wird.

AussageStandardKlausel
grid-template-areas benennt Grid-Zellen; benannte Bereiche platzieren Elemente.W3C CSS Grid Layout Module Level 1§7.3
Explizite feste, prozentuale und fr-Tracks dimensionieren gegen die Inhaltsbreite.W3C CSS Grid Layout Module Level 1§7.2

Dies ist eine Vorschau-Implementierung einer Teilmenge von grid-template-areas mit definiten Spalten. Der pro-Eigenschaft verifizierte Status wird in der CSS-Support-Matrix nachgehalten; hier wird keine Ende-zu-Ende-Konformität beansprucht. Es wird kein Standardtext wiedergegeben.