Aller au contenu

Mettre en forme du HTML avec CSS

Cette recette applique du CSS à du contenu HTML avec des attributs style en ligne et un bloc <style>. Elle montre aussi comment confirmer le statut vérifié d’une propriété avant de t’en servir.

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

Cette contrainte cible le package nextpdf/core. L’exemple s’exécute avec PHP 8.4.

Le moteur HTML résout les styles au moyen de la cascade CSS. La cascade est le mécanisme qui détermine quel style l’emporte lorsque plusieurs règles ciblent le même élément. Le moteur lit d’abord le bloc <style> de l’entrée, puis les attributs style en ligne. Il associe ensuite les deux aux éléments et calcule le résultat dans l’ordre de la cascade. La matrice de prise en charge classe le module CSS Cascading and Inheritance comme « Vérifié », ce qui signifie qu’une suite dédiée de fixtures garantit le comportement de la cascade et de l’héritage.

Les propriétés de présentation du texte telles que text-align, text-indent et letter-spacing proviennent de la table des propriétés du module CSS Text (W3C CSS Text Level 3). Le choix de la police utilise le modèle CSS Fonts. La propriété raccourcie font définit conjointement font-style, font-variant, font-weight, font-size et font-family (W3C CSS Fonts Level 3).

La prise en charge suit chaque module W3C et fait l’objet d’un audit de véracité. Une propriété implémentée sans fixture de module dédiée est classée « Déclaré », pas « Vérifié ». Considère « Déclaré » comme une prise en charge au mieux, et valide le résultat visuel pour ton contenu. Considère « Vérifié » comme garanti par une suite de fixtures réussie.

Toute la mise en forme passe par le HTML que tu fournis à writeHtml(string $html): static (NextPDF\Core\Concerns\HasTextOutput). Il n’y a pas d’API CSS séparée, et la cascade s’exécute en interne. La table PHPDoc complète est générée à partir du code source.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->writeHtml(
'<style>.lead { color: #1E3A8A; text-align: center; }</style>'
. '<p class="lead">Styled with a style block.</p>'
);
$doc->save(__DIR__ . '/out.pdf');

Cet exemple est autonome et exécutable dans le harnais de test. Il couvre un bloc <style>, des sélecteurs de classe, des styles en ligne, ainsi que le chemin de résolution de la famille et de la graisse de la propriété font.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('CSS Styling');
$doc->addPage();
$html = <<<'HTML'
<style>
h1 { color: #1E3A8A; }
.lead { color: #D97706; font-size: 14px; }
.callout { background-color: #EFF6FF; padding: 8px; border: 1px solid #BFDBFE; }
.centered { text-align: center; }
</style>
<h1>Styling HTML with CSS</h1>
<p class="lead">This paragraph is styled through a class selector in a
style block.</p>
<p class="callout">This paragraph has a background, padding, and a border
from a class selector.</p>
<p class="centered" style="font-weight: bold;">Centered, with an inline
override for weight.</p>
<p style="color: #6B7280; font-size: 9px;">Inline style only.</p>
HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/style-with-css.pdf');
echo "Wrote style-with-css.pdf\n";

Sortie STDOUT attendue :

Wrote style-with-css.pdf
  • Ordre de la cascade. Dans la cascade, un attribut style en ligne l’emporte sur un sélecteur de bloc <style> de spécificité égale. Si tu vois une couleur inattendue, vérifie d’abord s’il existe une surcharge en ligne.
  • Déclaré ou Vérifié. text-align, text-indent et color sont classés « Déclaré » dans la matrice. Ils sont implémentés mais n’ont pas de fixture de module dédiée. Leur rendu fonctionne, mais valide le résultat visuel avant une validation de production.
  • Aucun arbre conservé. Le moteur en flux (ADR-001) ne conserve aucun arbre de document ; il ne peut donc pas appliquer un sélecteur où un frère ultérieur restyle un élément antérieur. Les sélecteurs indépendants de l’ordre restent contraints.
  • Propriété non prise en charge. Une propriété non prise en charge est ignorée ; elle n’est pas levée comme une erreur. Vérifie-la dans la matrice avant de t’en servir.
  • Espaces de couleur. Les valeurs Lab, LCH et OKLab sont analysées, mais la fidélité de l’espace de couleur PDF pour ces fonctions n’est pas revendiquée (matrice : « Déclaré » pour CSS Color 4).

La résolution de la cascade fait partie de la passe unique. Le coût reste linéaire par rapport au nombre de jetons, O(n). Le budget est wall_ms: 1500, peak_mb: 96. Un bloc <style> ajoute un coût ponctuel d’analyse des sélecteurs, proportionnel au nombre de règles.

Extrait de la matrice de prise en charge CSS (lignes « Vérifié » uniquement)

Section intitulée « Extrait de la matrice de prise en charge CSS (lignes « Vérifié » uniquement) »

Cet extrait reprend uniquement les lignes Vérifié de la matrice de prise en charge CSS auditée pour véracité.

Module W3CNiveauStatutPreuve
CSS Cascading and Inheritance (css_cascade_3)3Vérifiésrc/Html/Cascade/, tests/Unit/Html/Cascade/
CSS Cascading (css_cascade_4)4VérifiéCascade/Layer/ + tests revert/layer
CSS Cascading (css_cascade_5)5VérifiéAtRule/Layer/ + Cascade/Layer/ (suites)
CSS Fonts (css_fonts_3)3Vérifiésrc/Html/Font/, tests/Unit/Font/ + tests FontResolver
CSS Fonts (css_fonts_4)4Vérifiésrc/Html/FontFace/, tests/Unit/Html/FontFace/

text-align, text-indent, color et background-color sont « Déclaré » dans la matrice. Le tableau les exclut volontairement des lignes « Vérifié ».

La cascade s’exécute sur une liste de jetons traitée en flux, sans DOM ; les sélecteurs se résolvent donc par rapport au contexte de l’ordre du document. Les cas de sélecteurs nécessitant l’arbre complet sont contraints conformément à ADR-006. Écris du CSS qui dépend uniquement de l’ordre du document et du contexte des ancêtres.

L’analyse CSS appartient à la couche de cascade, et la répartition de la mise en page ne doit pas lire directement les valeurs $css[...] brutes. La surface publique est l’entrée HTML. Il n’existe aucun moyen pris en charge d’injecter des styles calculés en dehors de la cascade.

La cascade conserve l’ensemble de règles actif ainsi que la pile de styles utilisée pour les opérations d’empilement et de dépilement, pas un arbre de nœuds. Les contextes à portée de conteneur respectent le budget d’ADR-020 (5,000 nœuds par contexte, plafond actif de 50 Mo). Les grandes feuilles de style augmentent linéairement la mémoire de l’ensemble de règles, alors garde un nombre de sélecteurs borné.

Du CSS présent dans du HTML non fiable ne peut pas exécuter de code, mais il peut affecter la mise en page et les références de ressources (par exemple background-image). La politique de ressources externes par défaut ne récupère pas d’URL distantes arbitraires. Assainis tout HTML et tout CSS que tu assembles à partir d’une entrée utilisateur avant de le rendre.

ÉnoncéSpécificationClausereference_id
Les propriétés de texte (text-align, text-indent, letter-spacing) sont définies par la table des propriétés CSS Text.W3C CSS Text Level 3css_text_3#x1.x24
La propriété raccourcie font définit font-style, font-variant, font-weight, font-size et font-family.W3C CSS Fonts Level 3css_fonts_3#x2.x6.x7.p2

Cette recette montre comment NextPDF applique un sous-ensemble CSS pris en charge ; elle n’affirme pas une prise en charge CSS complète. Pour le statut vérifié de chaque module, consulte la matrice de prise en charge CSS.

Sans objet.