Стилизация 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” означает подтверждение проходящим набором фикстур.
Поверхность API
Заголовок раздела «Поверхность API»Стилизацией вы управляете через 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 astyle block.</p>
<p class="callout">This paragraph has a background, padding, and a borderfrom a class selector.</p>
<p class="centered" style="font-weight: bold;">Centered, with an inlineoverride 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) — каскад и наследование | 3 | Verified (подтверждено) | src/Html/Cascade/, tests/Unit/Html/Cascade/ |
CSS Cascading (css_cascade_4) | 4 | Verified (подтверждено) | Cascade/Layer/ + revert/layer тесты |
CSS Cascading (css_cascade_5) | 5 | Verified (подтверждено) | AtRule/Layer/ + Cascade/Layer/ наборы |
CSS Fonts (css_fonts_3) — шрифты | 3 | Verified (подтверждено) | src/Html/Font/, tests/Unit/Font/ + тесты FontResolver |
CSS Fonts (css_fonts_4) — шрифты | 4 | Verified (подтверждено) | src/Html/FontFace/, tests/Unit/Html/FontFace/ |
text-align, text-indent, color и background-color отмечены в матрице как “Claimed”. Таблица намеренно не включает их в строки со статусом Verified.
Ограничения однопроходной потоковой обработки (ADR-001)
Заголовок раздела «Ограничения однопроходной потоковой обработки (ADR-001)»Каскад работает с потоковым списком токенов без объектной модели документа (DOM), поэтому селекторы разрешаются по контексту в порядке документа. Селекторы, которым нужно полное дерево, ограничены согласно ADR-006. Пишите CSS, который зависит только от порядка документа и контекста предков.
Контракты слоёв (ADR-010)
Заголовок раздела «Контракты слоёв (ADR-010)»Разбор 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.
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»Неприменимо.