Aller au contenu
getnextpdf.com

stabilité: Expérimental

Indicateurs de prévisualisation CSS Paged-media (contenu courant GCPM, pages nommées, flottants de page)

Prévisualisation opt-in. Ces quatre fonctionnalités CSS sont désactivées par défaut. Lorsque l’indicateur est désactivé, le moteur produit une sortie octet pour octet identique à celle d’une build qui n’aurait jamais connu la fonctionnalité. N’activez une fonctionnalité que lorsque vous en avez besoin, et validez le résultat pour vos documents.

Le moteur de rendu HTML ajoute quatre fonctionnalités paged-media opt-in issues des modules CSS Paged Media et Generated Content for Paged Media (GCPM). Chacune est un indicateur distinct sur CssFeatureFlags. Chacune porte une frontière honnête de type fail-closed : une construction que le moteur à passe unique ne peut résoudre fidèlement est abandonnée ou dégradée avec un diagnostic nommé, jamais rendue de façon incorrecte.

FonctionnalitéIndicateurEffet lorsqu’elle est activée
Chaînes nommées (GCPM)runningStringsCapture string-set plus string() dans les boîtes de marge @page — en-têtes et pieds de page courants.
Pages nommées (Paged Media L3)namedPagesAdvanced@page <ident>, la propriété page: et :first / :left / :right / :blank — boîtes de marge et décoration par page.
Éléments courants (GCPM)runningElementsposition: running(<ident>) plus content: element(<ident>) — rejoue le texte d’un élément dans une boîte de marge.
Flottants de page (Page Floats L3)pageFloatsfloat: top | bottom | snap — déplace une boîte dans la bande supérieure ou inférieure de la page.
Fenêtre de terminal
composer require nextpdf/core:^3

Les indicateurs sont livrés dans le paquet core. La surface publique CssFeatureFlags est @since 6.1.0. La version du moteur (Version::VERSION) est inchangée ; ces fonctionnalités sont additives et désactivées par défaut.

Le moteur de rendu est à passe unique et en streaming (voir ADR-001). Il ne conserve aucun arbre de document et écrit la sortie une seule fois dans l’ordre du document. Cette contrainte façonne chaque fonctionnalité décrite ici. Chaque fonctionnalité résout ce qu’elle peut voir en une seule passe vers l’avant et échoue en mode fail-closed sur tout ce qui exigerait une seconde passe ou un arbre conservé. La frontière est documentée, pas cachée — savoir où une fonctionnalité s’arrête fait partie de son utilisation.

Vous activez une fonctionnalité en construisant CssFeatureFlags avec l’indicateur réglé sur true et en le passant à Config. Lorsqu’un indicateur est désactivé, le CSS correspondant est analysé puis ignoré exactement comme le serait une propriété non prise en charge, de sorte que la sortie est octet pour octet identique à une build sans la fonctionnalité.

string-set: <ident> content() enregistre une valeur au passage du moteur sur l’élément. Une référence string(<ident>) à l’intérieur d’une boîte de marge @page se résout alors vers la valeur la plus récente vue sur cette page. C’est le mécanisme standard pour un en-tête courant qui suit le chapitre ou la section en cours.

La résolution est de type « dernier vu sur cette page » en passe unique. Une référence string() se résout vers la dernière valeur que le moteur a enregistrée avant de mettre en page les boîtes de marge de cette page.

Frontière fail-closed. Avec l’indicateur désactivé, string() se résout vers la chaîne vide et la sortie reste octet pour octet identique. Une liste de contenu string-set malformée abandonne cette unique paire d’affectation et poursuit ; elle n’interrompt jamais le rendu.

La propriété page: <ident> affecte un élément à un contexte de page nommée, et une règle @page <ident> correspondante fournit les boîtes de marge et la décoration de page de ce contexte. Les pseudo-classes de page :first, :left, :right et :blank sélectionnent la première page, les pages recto et verso, et les pages intentionnellement blanches.

Cette fonctionnalité sélectionne les boîtes de marge et la décoration d’une page nommée ou pseudo. Elle ne modifie pas la géométrie de la page.

Frontière fail-closed. Une règle @page nommée ou pseudo qui tente de modifier la géométrie — size, rotate, ou une marge de boîte de contenu qui redimensionne la zone de page — échoue en mode fail-closed avec UnsupportedNamedPageException plutôt que de produire silencieusement une page mal alignée. Le canal de correspondance par pseudo-classe est la première tranche ; les cas de sélecteurs plus larges sont reportés et documentés.

position: running(<ident>) retire un élément du flux normal et le gare sous un nom. content: element(<ident>) dans une boîte de marge rejoue alors cet élément sur chaque page. Utilisez-le lorsqu’un en-tête a besoin du texte stylé complet d’un titre, et pas seulement d’une chaîne capturée.

Frontière fail-closed. Cette tranche rejoue uniquement le texte de l’élément courant. Le contenu riche — images, éléments remplacés, structure de bloc imbriquée — est abandonné, et le moteur émet un diagnostic HTML_RUNNING_ELEMENT_DEGRADED afin que la perte soit visible, pas silencieuse. Un élément running() qui se référence lui-même, un running() imbriqué, ou une capture qui dépasse le budget interne échoue en mode fail-closed. Avec l’indicateur désactivé, running() et element() sont inertes.

float: top, float: bottom et float: snap déplacent une boîte dans la bande supérieure ou inférieure de la page selon l’axe de bloc, en réservant la hauteur de la bande pour que le texte environnant se réagence autour de la région réservée.

float: bottom (et snap se résolvant vers la bande inférieure) est le cas que le moteur à passe unique gère directement : la boîte est capturée et placée dans la bande inférieure de la page à la fermeture de celle-ci. float: top se ramène à la bande supérieure de la page.

Frontière fail-closed. snap dans l’axe en ligne (snap-inline) n’est pas pris en charge. Une boîte qui porte un effet de bord non déplaçable — par exemple une annotation de lien, dont le rectangle est lié à sa position dans le flux — ne peut pas être relocalisée en toute sécurité, elle revient donc au flux normal et le moteur émet un diagnostic HTML_PAGE_FLOAT_* expliquant le repli. Avec l’indicateur désactivé, float: top | bottom | snap est traité comme une valeur non prise en charge et ignoré.

SymboleEmplacementRôle
CssFeatureFlagssrc/Html/CssFeatureFlags.phpEnsemble d’indicateurs opt-in immuable ; le constructeur prend runningStrings, namedPagesAdvanced, runningElements, pageFloats (tous false par défaut).
Config::withCssFeatureFlags(CssFeatureFlags $flags): selfsrc/Core/Config.phpAttache l’ensemble d’indicateurs à une configuration de document.
CssFeatureFlags::forMode(CssRenderingMode $mode, ?self $explicit = null): selfsrc/Html/CssFeatureFlags.phpRésout un ensemble d’indicateurs pour un mode de rendu (le mode Safe force chaque indicateur à désactivé ; le mode Normal utilise l’ensemble explicite, ou allEnabled() si aucun n’est fourni).
UnsupportedNamedPageExceptionsrc/Html/PagedMedia/UnsupportedNamedPageException.phpLevée lorsqu’une règle @page nommée/pseudo modifie la géométrie de la page.

Les codes d’avertissement de diagnostic remontent par le canal consultatif du résultat de rendu : HTML_RUNNING_ELEMENT_DEGRADED, la famille HTML_RUNNING_ELEMENT_*, et la famille HTML_PAGE_FLOAT_*.

Activez les chaînes nommées pour un en-tête courant qui suit le chapitre en cours.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\Document;
use NextPDF\Html\Css\CssFeatureFlags;
$config = (new Config())->withCssFeatureFlags(
new CssFeatureFlags(runningStrings: true),
);
$doc = Document::createStandalone($config);
$doc->addPage();
$doc->writeHtml(
'<style>'
. 'h2 { string-set: chapter content(); }'
. '@page { @top-center { content: string(chapter); } }'
. '</style>'
. '<h2>Introduction</h2><p>Body text…</p>',
);
$doc->save(__DIR__ . '/running-header.pdf');

Activez plusieurs indicateurs ensemble, et traitez le canal consultatif comme un signal indiquant qu’une construction a été dégradée. Les indicateurs sont indépendants ; n’activez que ceux que vous utilisez.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;
use NextPDF\Core\Document;
use NextPDF\Exception\UnsupportedNamedPageException;
use NextPDF\Html\Css\CssFeatureFlags;
$config = (new Config())->withCssFeatureFlags(new CssFeatureFlags(
runningStrings: true,
namedPagesAdvanced: true,
runningElements: true,
pageFloats: true,
));
$doc = Document::createStandalone($config);
$doc->addPage();
try {
$doc->writeHtml($html);
} catch (UnsupportedNamedPageException $e) {
// A named @page rule tried to change page geometry (size/rotate/margin).
// The engine fails closed rather than emit a misaligned page.
throw $e;
}
$doc->save($out);
// Inspect $doc's advisory channel for HTML_RUNNING_ELEMENT_DEGRADED and
// HTML_PAGE_FLOAT_* before treating the output as final.
  • Les quatre indicateurs sont indépendants et désactivés par défaut. Un indicateur désactivé produit une sortie octet pour octet identique. N’activez que ce que vous utilisez.
  • string() est vide lorsque runningStrings est désactivé, par conception. Il n’y a aucun avertissement pour le cas désactivé ; c’est le défaut documenté.
  • Les éléments courants rejouent uniquement du texte. Les images et les blocs imbriqués à l’intérieur d’un élément courant sont abandonnés avec HTML_RUNNING_ELEMENT_DEGRADED. Vérifiez le canal consultatif.
  • Les pages nommées ne peuvent pas modifier la géométrie. Une règle @page nommée/pseudo qui modifie la géométrie lève UnsupportedNamedPageException. Définissez la taille et la rotation de page via Config, pas via une règle @page nommée.
  • Les flottants de page conservent les liens dans le flux. Une boîte flottée qui contient une annotation de lien revient au flux normal avec un diagnostic HTML_PAGE_FLOAT_*, car le rectangle du lien est lié à sa position dans le flux.

Chaque fonctionnalité ajoute une quantité bornée de travail en passe unique : les chaînes nommées enregistrent une valeur par élément string-set ; les pages nommées ajoutent une résolution de boîte de marge par page ; les éléments courants capturent un tampon de texte par élément garé ; les flottants de page réservent une bande par page. Aucune ne conserve un arbre de document, de sorte que le modèle mémoire en O(profondeur d’imbrication) du moteur de rendu en streaming est préservé. Le performance_budget par page (wall_ms: 1500, peak_mb: 64) est inchangé.

Ces indicateurs n’élargissent pas la surface d’entrée. La politique de sécurité HTML, la liste d’autorisation des propriétés CSS, ainsi que les plafonds d’octets de feuille de style et d’imbrication s’appliquent sans changement. Le contenu de chaîne et d’élément capturé est échappé par le même chemin de sortie que tout autre texte. Les fonctionnalités ajoutent un comportement de mise en page, pas un nouveau canal d’ingestion.

ÉnoncéSpécificationClause
string-set enregistre une chaîne nommée ; string() la résout dans une boîte de marge de page.W3C CSS Generated Content for Paged Media§3
position: running() retire un élément du flux ; content: element() le rejoue.W3C CSS Generated Content for Paged Media§5
La propriété page et @page <ident> sélectionnent un contexte de page nommée.W3C CSS Paged Media Module Level 3§3
float: top | bottom | snap fait flotter une boîte selon l’axe de bloc vers une bande de page.W3C CSS Page Floats Level 3§5

Il s’agit d’implémentations de prévisualisation de fonctionnalités de modules de groupe de travail. NextPDF implémente un sous-ensemble à passe unique avec les frontières fail-closed documentées ci-dessus. 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.