Перейти к содержимому

Стилизация HTML через CSS

В этом рецепте CSS применяется к HTML-содержимому. Используются встроенные атрибуты style и блок <style>. Вы также узнаете, как проверить, подтверждена ли поддержка свойства, прежде чем полагаться на него.

Окно терминала
composer require nextpdf/core:^3

Используйте это ограничение версии для пакета nextpdf/core. Пример работает на PHP 8.4.

Движок HTML вычисляет стили через каскад CSS. Каскад определяет, какой стиль победит, когда несколько правил применяются к одному и тому же элементу. Сначала движок читает входной блок <style>, затем встроенные атрибуты style. Он сопоставляет оба источника с элементами и вычисляет результат в порядке каскада. В матрице поддержки модуль CSS Cascading and Inheritance имеет статус Verified: поведение каскада и наследования покрыто отдельным набором фикстур.

Свойства оформления текста, такие как text-align, text-indent и letter-spacing, определены в таблице свойств модуля CSS Text W3C (W3C CSS Text Level 3). Выбор шрифта использует модель CSS Fonts. Сокращённая запись font одновременно задаёт font-style, font-variant, font-weight, font-size и font-family (W3C CSS Fonts Level 3).

Поддержка отслеживается по модулям W3C и проходит аудит достоверности. Свойство может быть реализовано, но не иметь отдельной фикстуры модуля; в этом случае оно получает статус “Claimed”, а не “Verified”. Статус “Claimed” означает реализацию по мере возможностей, поэтому проверяйте визуальный результат на своём содержимом. Статус “Verified” означает подтверждение проходящим набором фикстур.

Стилизацией вы управляете через HTML, который передаёте в writeHtml(string $html): static (NextPDF\Core\Concerns\HasTextOutput). Отдельного API для CSS нет; каскад работает внутри. Полная таблица PHPDoc генерируется из исходного кода.

<?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');

Этот самодостаточный пример можно запустить в тестовой среде. Он использует блок <style>, селекторы классов, встроенные стили, а также настройку семейства и насыщенности через 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";

Ожидаемый вывод в STDOUT:

Wrote style-with-css.pdf
  • Порядок каскада. В каскаде встроенный style побеждает селектор блока <style> при равной специфичности. Если видите неожиданный цвет, сначала проверьте, нет ли встроенного переопределения.
  • Claimed против Verified. text-align, text-indent и color отмечены в матрице как “Claimed”. Они реализованы, но не имеют отдельной фикстуры модуля. Они отрисовываются, однако визуальный результат следует проверить перед использованием в продакшене.
  • Нет сохраняемого дерева. Потоковый движок, описанный в записи об архитектурном решении (ADR-001), не хранит дерево документа, поэтому не может применить селектор, в котором последующий соседний элемент переопределяет стиль более раннего элемента. В результате ограничены селекторы, которые не зависят от порядка.
  • Неподдерживаемое свойство. Неподдерживаемое свойство игнорируется и не вызывает ошибку. Проверьте матрицу, прежде чем полагаться на него.
  • Цветовые пространства. Значения Lab, LCH и OKLab разбираются, но точность представления этих цветовых пространств в Portable Document Format (PDF) для этих функций не гарантируется (матрица: “Claimed” для CSS Color 4).

Разрешение каскада выполняется за один проход. Затраты остаются линейными по числу токенов, O(n). Бюджет составляет wall_ms: 1500, peak_mb: 96. Блок <style> добавляет разовые затраты на разбор селекторов, пропорциональные числу правил.

Выдержка из матрицы поддержки CSS (только строки Verified)

Заголовок раздела «Выдержка из матрицы поддержки CSS (только строки Verified)»

Эта выдержка показывает только строки Verified из матрицы поддержки CSS, прошедшей аудит достоверности.

Модуль W3CУровеньСтатусДоказательства
CSS Cascading and Inheritance (css_cascade_3) — каскад и наследование3Verified (подтверждено)src/Html/Cascade/, tests/Unit/Html/Cascade/
CSS Cascading (css_cascade_4)4Verified (подтверждено)Cascade/Layer/ + revert/layer тесты
CSS Cascading (css_cascade_5)5Verified (подтверждено)AtRule/Layer/ + Cascade/Layer/ наборы
CSS Fonts (css_fonts_3) — шрифты3Verified (подтверждено)src/Html/Font/, tests/Unit/Font/ + тесты FontResolver
CSS Fonts (css_fonts_4) — шрифты4Verified (подтверждено)src/Html/FontFace/, tests/Unit/Html/FontFace/

text-align, text-indent, color и background-color отмечены в матрице как “Claimed”. Таблица намеренно не включает их в строки со статусом Verified.

Ограничения однопроходной потоковой обработки (ADR-001)

Заголовок раздела «Ограничения однопроходной потоковой обработки (ADR-001)»

Каскад работает с потоковым списком токенов без объектной модели документа (DOM), поэтому селекторы разрешаются по контексту в порядке документа. Селекторы, которым нужно полное дерево, ограничены согласно ADR-006. Пишите CSS, который зависит только от порядка документа и контекста предков.

Разбор CSS относится к слою каскада, а диспетчеризация макета не должна напрямую читать необработанные значения $css[...]. Публичная поверхность — входной HTML. Поддерживаемого способа внедрить вычисленные стили в обход каскада нет.

Каскад хранит активный набор правил и стек стилей с операциями push и pop, а не дерево узлов. Контексты внутри контейнера подчиняются бюджету ADR-020 (5,000 узлов на контекст, активный потолок 50 MB). Большие таблицы стилей линейно увеличивают объём памяти для набора правил, поэтому ограничивайте число селекторов.

CSS в недоверенном HTML не может выполнять код, но может влиять на макет и ссылки на ресурсы, такие как background-image. Политика внешних ресурсов по умолчанию не загружает произвольные удалённые URL. Перед отрисовкой очищайте любой HTML и CSS, который собираете из пользовательского ввода.

УтверждениеСпецификацияРазделreference_id (идентификатор ссылки)
Свойства текста (text-align, text-indent, letter-spacing) определяются таблицей свойств CSS Text.W3C CSS Text Level 3 (модуль текста CSS)раздел css_text_3#x1.x24
Сокращённая запись font задаёт font-style, font-variant, font-weight, font-size и font-family.W3C CSS Fonts Level 3 (модуль шрифтов CSS)раздел css_fonts_3#x2.x6.x7.p2

Этот рецепт показывает, как NextPDF применяет поддерживаемое подмножество CSS; он не заявляет полную поддержку CSS. Подтверждённый статус по каждому модулю см. в матрице поддержки CSS.

Неприменимо.