estabilidade: Experimental
Layout em modo retido para CSS Grid (grid-template-areas)
Visão geral
Seção intitulada “Visão geral”Pré-visualização opcional. O modo retido é desativado por padrão. O modo
Streamingpadrão é idêntico byte a byte à de uma compilação que nunca soube que esse modo existia. Ative-o somente para os documentos que precisam de uma grade real e valide o resultado.
Por padrão, o renderizador é de passada única e em streaming (consulte
ADR-001). Uma grade CSS Grid declarada com
grid-template-areas não pode ser posicionada em uma única passada para frente,
então o motor de streaming emite um aviso HTML_GRID_REQUIRES_RETAINED e recai
para o fluxo de blocos. O modo retido é o recurso opcional que substitui esse
fallback por um layout real: Config::withCssLayoutMode(CssLayoutMode::Retained)
roteia uma grade grid-template-areas de colunas definidas pelo
GridLayoutEngine, que posiciona os filhos em suas células nomeadas.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3O modo de layout é entregue no pacote core. O recurso opcional
Config::withCssLayoutMode é @since 6.0.0. O padrão permanece
CssLayoutMode::Streaming.
Visão geral conceitual
Seção intitulada “Visão geral conceitual”CssLayoutMode é uma enum tipada em Config. Streaming é o padrão e o
comportamento histórico; Retained opta um documento para o motor de grade. O
modo retido mantém um conjunto de nós retidos limitado (o retainedNodeBudget,
padrão 50,000, restringido a [5,000, 100,000]) para que o motor consiga
resolver uma grade que o streaming não consegue — sem abandonar a disciplina de
memória do motor.
Quando o modo retido está ativado e o motor encontra uma grade
grid-template-areas cujas colunas são definidas, ele dispõe a grade de verdade.
Colunas definidas são comprimentos fixos, porcentagens ou unidades fr
resolvidas em relação à largura do conteúdo. As linhas fluem automaticamente. Os
filhos são atribuídos às células que os nomes de suas áreas selecionam.
A ADR-001 registra a invariante de streaming. A emenda de 2026-06-28 à ADR-001 adiciona uma exceção opcional de modo retido: o padrão de streaming permanece intocado e mantém o modelo de passada única; o modo retido é uma exceção opcional, explicitamente limitada, para o caso de grade.
Limite — o que o modo retido dispõe e o que ainda recai
Seção intitulada “Limite — o que o modo retido dispõe e o que ainda recai”O modo retido trata o caso de grid-template-areas de colunas definidas e
somente esse caso. Tudo fora dele mantém o aviso HTML_GRID_REQUIRES_RETAINED e
o fallback de blocos, mesmo com o modo retido ativado:
grid-auto-flow: columnegrid-auto-flow: dense.subgrid.- consultas
@container. - Trilhas de coluna automáticas ou intrínsecas (
auto,min-content,max-content).
Estas são fatias adiadas, não lacunas silenciosas. Uma grade que depende de uma delas degrada para o fluxo de blocos e informa isso.
Limite de falha fechada. Uma divergência de largura entre captura e motor — a
largura de conteúdo medida discordando da largura contra a qual o motor de grade
resolve — falha fechada em vez de produzir uma grade mal posicionada. O modo
retido também é incompatível com o modo de renderização Safe CSS:
CssRenderingMode::Safe combinado com CssLayoutMode::Retained levanta
IncompatibleRenderingModeException na validação da configuração.
CssLayoutMode::Auto é reservado e levanta NotImplementedException.
Superfície da API
Seção intitulada “Superfície da API”| Símbolo | Localização | Função |
|---|---|---|
Config::withCssLayoutMode(CssLayoutMode $mode): self | src/Core/Config.php | Opta um documento por layout Streaming (padrão) ou Retained. |
Config::withRetainedNodeBudget(int $budget): self | src/Core/Config.php | Limita o conjunto de nós retidos ([5,000, 100,000], padrão 50,000). |
Config::isRetainedMode(): bool | src/Core/Config.php | Informa se o documento está em modo retido. |
CssLayoutMode | src/Core/ | Streaming, Retained; Auto reservado (NotImplementedException). |
GridLayoutEngine | src/Html/ | O motor de posicionamento de grade retida. |
IncompatibleRenderingModeException | src/Exception/ | Lançada quando o modo Safe CSS é combinado com o modo retido. |
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?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');Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Detecte o caso de modo incompatível no momento da configuração e leia de volta o modo ativo para que o caminho fique explícito.
<?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.Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”- O Streaming continua sendo o padrão e é idêntico byte a byte. O modo retido altera a saída apenas para o documento em que você opta por ativá-lo.
- Somente
grid-template-areasde colunas definidas. Auto-flow de coluna, empacotamento denso, subgrid,@containere colunas intrínsecas mantêm o avisoHTML_GRID_REQUIRES_RETAINEDe o fallback de blocos. - O modo Safe é mutuamente exclusivo.
CssRenderingMode::SafemaisCssLayoutMode::RetainedlançaIncompatibleRenderingModeException. Autoé reservado.CssLayoutMode::AutolevantaNotImplementedException; ainda não é uma terceira opção utilizável.- Divergência de largura falha fechada. Uma discordância de largura de conteúdo entre captura e motor é recusada, não renderizada de forma incorreta.
Desempenho
Seção intitulada “Desempenho”O modo retido mantém um conjunto de nós limitado em vez de uma árvore de
documento completa; o retainedNodeBudget (padrão 50,000) o limita. O
posicionamento de grade é linear na contagem de nós e células. O
performance_budget por página (wall_ms: 1500, peak_mb: 64) se aplica;
grades grandes devem ter o orçamento em mente ao elevar o orçamento de nós em
direção ao seu teto de 100,000.
Notas de segurança
Seção intitulada “Notas de segurança”O modo retido não amplia a superfície de entrada. A política de segurança HTML, a allowlist de propriedades CSS e os limites do parser se aplicam inalterados. O orçamento de nós retidos é, em si, um limite de exaustão de recursos: ele limita quanta estrutura o motor manterá para um único documento.
Conformidade
Seção intitulada “Conformidade”| Declaração | Especificação | Cláusula |
|---|---|---|
grid-template-areas nomeia células de grade; áreas nomeadas posicionam itens. | W3C CSS Grid Layout Module Level 1 | §7.3 |
Trilhas explícitas fixas, em porcentagem e fr dimensionam contra a largura do conteúdo. | W3C CSS Grid Layout Module Level 1 | §7.2 |
Esta é uma implementação de pré-visualização de um subconjunto de
grid-template-areas de colunas definidas. O status verificado por propriedade é
acompanhado na matriz de suporte CSS; nenhuma
conformidade de ponta a ponta é reivindicada aqui. Nenhum texto de norma é
reproduzido.