Aller au contenu
getnextpdf.com

stabilité: Expérimental

Mise en page en mode conservé pour CSS Grid (grid-template-areas)

Prévisualisation opt-in. Le mode conservé est désactivé par défaut. Le mode Streaming par défaut est octet pour octet identique à une build qui n’aurait jamais connu l’existence de ce mode. Ne l’activez que pour les documents qui ont besoin d’une véritable grille, et validez le résultat.

Par défaut, le moteur de rendu est à passe unique et en streaming (voir ADR-001). Une grille CSS déclarée avec grid-template-areas ne peut pas être placée en une seule passe vers l’avant ; le moteur de streaming émet donc un avertissement HTML_GRID_REQUIRES_RETAINED et se replie sur le flux de bloc. Le mode conservé est l’opt-in qui remplace ce repli par une véritable mise en page : Config::withCssLayoutMode(CssLayoutMode::Retained) achemine une grille grid-template-areas à colonnes définies à travers le GridLayoutEngine, qui place les enfants dans leurs cellules nommées.

Fenêtre de terminal
composer require nextpdf/core:^3

Le mode de mise en page est livré dans le paquet core. L’opt-in Config::withCssLayoutMode est @since 6.0.0. La valeur par défaut reste CssLayoutMode::Streaming.

CssLayoutMode est une énumération typée sur Config. Streaming est la valeur par défaut et le comportement historique ; Retained fait entrer un document dans le moteur de grille. Le mode conservé maintient un ensemble borné de nœuds conservés (le retainedNodeBudget, par défaut 50,000, borné à [5,000, 100,000]) afin que le moteur puisse résoudre une grille que le streaming ne peut pas — sans abandonner la discipline mémoire du moteur.

Lorsque le mode conservé est activé et que le moteur rencontre une grille grid-template-areas dont les colonnes sont définies, il dispose la grille pour de vrai. Les colonnes définies sont des longueurs fixes, des pourcentages ou des unités fr résolus par rapport à la largeur de contenu. Les lignes s’enchaînent automatiquement. Les enfants sont affectés aux cellules que sélectionnent leurs noms de zone.

ADR-001 consigne l’invariant de streaming. L’amendement du 2026-06-28 à ADR-001 ajoute une exception opt-in en mode conservé : le défaut streaming est intact et reste le modèle à passe unique ; le mode conservé est une exception opt-in, explicitement bornée, pour le cas de la grille.

Frontière — ce que le mode conservé met en page, et ce qui retombe en repli

Section intitulée « Frontière — ce que le mode conservé met en page, et ce qui retombe en repli »

Le mode conservé gère le cas de la grille grid-template-areas à colonnes définies, et ce cas uniquement. Tout ce qui sort de ce cadre conserve l’avertissement HTML_GRID_REQUIRES_RETAINED et le repli en bloc, même avec le mode conservé activé :

  • grid-auto-flow: column et grid-auto-flow: dense.
  • subgrid.
  • Les requêtes @container.
  • Les pistes de colonnes auto ou intrinsèques (auto, min-content, max-content).

Ce sont des tranches reportées, pas des lacunes silencieuses. Une grille qui dépend de l’une d’elles se dégrade en flux de bloc et vous le signale.

Frontière fail-closed. Une discordance entre la capture et le moteur de largeur — la largeur de contenu mesurée divergeant de la largeur que le moteur de grille résout — échoue en mode fail-closed plutôt que de produire une grille mal placée. Le mode conservé est également incompatible avec le mode de rendu CSS Safe : CssRenderingMode::Safe combiné à CssLayoutMode::Retained lève IncompatibleRenderingModeException lors de la validation de la configuration. CssLayoutMode::Auto est réservé et lève NotImplementedException.

SymboleEmplacementRôle
Config::withCssLayoutMode(CssLayoutMode $mode): selfsrc/Core/Config.phpFait entrer un document en mise en page Streaming (par défaut) ou Retained.
Config::withRetainedNodeBudget(int $budget): selfsrc/Core/Config.phpBorne l’ensemble de nœuds conservés ([5,000, 100,000], par défaut 50,000).
Config::isRetainedMode(): boolsrc/Core/Config.phpIndique si le document est en mode conservé.
CssLayoutModesrc/Core/Streaming, Retained ; Auto réservé (NotImplementedException).
GridLayoutEnginesrc/Html/Le moteur de placement de grille conservé.
IncompatibleRenderingModeExceptionsrc/Exception/Levée lorsque le mode CSS Safe est combiné avec le mode conservé.
<?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');

Détectez le cas de mode incompatible au moment de la configuration, et relisez le mode actif afin que le chemin soit explicite.

<?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.
  • Le streaming reste la valeur par défaut et est octet pour octet identique. Le mode conservé ne change la sortie que pour le document que vous activez.
  • Uniquement grid-template-areas à colonnes définies. L’auto-flow de colonnes, le compactage dense, le subgrid, @container et les colonnes intrinsèques conservent l’avertissement HTML_GRID_REQUIRES_RETAINED et le repli en bloc.
  • Le mode Safe est mutuellement exclusif. CssRenderingMode::Safe plus CssLayoutMode::Retained lève IncompatibleRenderingModeException.
  • Auto est réservé. CssLayoutMode::Auto lève NotImplementedException ; ce n’est pas encore une troisième option utilisable.
  • Une discordance de largeur échoue en mode fail-closed. Une divergence de largeur de contenu entre la capture et le moteur est refusée, pas rendue de façon incorrecte.

Le mode conservé maintient un ensemble borné de nœuds plutôt qu’un arbre de document complet ; le retainedNodeBudget (par défaut 50,000) le plafonne. Le placement de la grille est linéaire en nombre de nœuds et de cellules. Le performance_budget par page (wall_ms: 1500, peak_mb: 64) s’applique ; les grandes grilles devraient garder le budget à l’esprit lors de l’élévation du budget de nœuds vers son plafond de 100,000.

Le mode conservé n’élargit pas la surface d’entrée. La politique de sécurité HTML, la liste d’autorisation des propriétés CSS et les plafonds de l’analyseur s’appliquent sans changement. Le budget de nœuds conservés est lui-même une borne contre l’épuisement de ressources : il plafonne la quantité de structure que le moteur conservera pour un seul document.

ÉnoncéSpécificationClause
grid-template-areas nomme les cellules de grille ; les zones nommées placent les éléments.W3C CSS Grid Layout Module Level 1§7.3
Les pistes fixes, en pourcentage et fr explicites se dimensionnent par rapport à la largeur de contenu.W3C CSS Grid Layout Module Level 1§7.2

Il s’agit d’une implémentation de prévisualisation d’un sous-ensemble grid-template-areas à colonnes définies. Le statut vérifié par propriété est suivi dans la matrice de prise en charge CSS ; aucune conformité de bout en bout n’est revendiquée ici. Aucun texte de norme n’est reproduit.