Pular para o conteúdo
getnextpdf.com

estabilidade: Experimental

Layout em modo retido para CSS Grid (grid-template-areas)

Pré-visualização opcional. O modo retido é desativado por padrão. O modo Streaming padrã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.

Terminal window
composer require nextpdf/core:^3

O modo de layout é entregue no pacote core. O recurso opcional Config::withCssLayoutMode é @since 6.0.0. O padrão permanece CssLayoutMode::Streaming.

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: column e grid-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.

SímboloLocalizaçãoFunção
Config::withCssLayoutMode(CssLayoutMode $mode): selfsrc/Core/Config.phpOpta um documento por layout Streaming (padrão) ou Retained.
Config::withRetainedNodeBudget(int $budget): selfsrc/Core/Config.phpLimita o conjunto de nós retidos ([5,000, 100,000], padrão 50,000).
Config::isRetainedMode(): boolsrc/Core/Config.phpInforma se o documento está em modo retido.
CssLayoutModesrc/Core/Streaming, Retained; Auto reservado (NotImplementedException).
GridLayoutEnginesrc/Html/O motor de posicionamento de grade retida.
IncompatibleRenderingModeExceptionsrc/Exception/Lançada quando o modo Safe CSS é combinado com o modo retido.
<?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');

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.
  • 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-areas de colunas definidas. Auto-flow de coluna, empacotamento denso, subgrid, @container e colunas intrínsecas mantêm o aviso HTML_GRID_REQUIRES_RETAINED e o fallback de blocos.
  • O modo Safe é mutuamente exclusivo. CssRenderingMode::Safe mais CssLayoutMode::Retained lança IncompatibleRenderingModeException.
  • Auto é reservado. CssLayoutMode::Auto levanta NotImplementedException; 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.

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.

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.

DeclaraçãoEspecificaçãoClá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.