O que vai em um arquivo theme.json do WordPress
Veja o que incluir no arquivo WordPress theme.json, como settings e styles geram variáveis CSS e como funcionam predefinições, CSS personalizado e temas filhos.
Um arquivo theme.json do WordPress é um arquivo JSON, localizado na raiz de um tema de blocos, que declara uma única vez os design tokens do tema (cores, tamanhos de fonte, famílias de fontes, espaçamentos e larguras de layout). Assim, o editor de blocos e o front-end leem os mesmos valores.
Se você já trabalhou com pipelines de design tokens, o arquivo vai parecer familiar. Isso muda quando você tenta encontrar o CSS que ele gera ou entender por que um tema filho apagou metade da paleta. Este artigo percorre cada parte do arquivo, mostra o CSS que o WordPress gera a partir dele, explica como usar essas variáveis na sua própria folha de estilos e indica onde o CSS escrito à mão ainda é necessário. Todos os exemplos usam a versão 3 do schema, introduzida no WordPress 6.6.
Principais conclusões
- O
theme.jsontem duas chaves principais de nível superior.settingsdefine quais controles e presets o editor oferece.stylesaplica valores padrão à página, aos elementos HTML e a blocos individuais. - Todo preset, exceto os filtros de duotone, vira uma CSS custom property chamada
--wp--preset--{category}--{slug}. Por exemplo, uma cor da paleta com o sluginkfica disponível comovar(--wp--preset--color--ink)em qualquer folha de estilos. - Os valores em
settings.customviram propriedades--wp--custom--*. O camelCase é convertido para kebab-case, e cada nível de aninhamento é separado por um hífen duplo. - O
theme.jsonde um tema filho é mesclado sobre o do tema pai, mas qualquer lista de presets declarada nele substitui por completo a lista do tema pai.
O que é o theme.json?
O theme.json é o arquivo de design tokens de um tema de blocos. Você declara nele, uma única vez, cores, tipografia, espaçamentos e larguras de layout. O WordPress usa esses valores para montar os controles do editor e gerar a folha de estilos do front-end. O nível superior é enxuto: $schema, version, settings e styles. Há também customTemplates, templateParts e patterns, que servem para registrar templates, template parts e patterns do Pattern Directory.
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {},
"styles": {}
}
Apontar $schema para o schema do theme.json no trunk ativa o preenchimento automático e a validação no VS Code.
Por que o theme.json existe?
O theme.json substitui três coisas que antes acabavam ficando dessincronizadas: as flags add_theme_support() em PHP, a configuração do editor e o CSS do front-end. O guia de configurações globais do Block Editor Handbook mapeia cada flag antiga de add_theme_support para uma chave do theme.json. Se um tema define a mesma configuração nos dois lugares, o valor do theme.json prevalece.
| add_theme_support | Equivalente no theme.json |
|---|---|
editor-color-palette | settings.color.palette |
editor-font-sizes | settings.typography.fontSizes |
disable-custom-colors | settings.color.custom: false |
custom-units | settings.spacing.units |
appearance-tools | settings.appearanceTools: true |
O que vai em settings?
settings controla o que o editor oferece: quais presets aparecem nos seletores e quais controles livres são permitidos. Os presets são arrays de objetos, cada um com um slug, um valor e um name de exibição.
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
"color": {
"custom": false,
"customGradient": false,
"defaultPalette": false,
"palette": [
{ "slug": "ink", "color": "#1b1f24", "name": "Ink" },
{ "slug": "accent", "color": "#3b5bdb", "name": "Accent" }
]
},
"typography": {
"customFontSize": false,
"defaultFontSizes": false,
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "large", "size": "1.5rem", "name": "Large" }
],
"fontFamilies": [
{ "slug": "system", "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", "name": "System" }
]
},
"spacing": { "blockGap": true, "units": ["px", "rem", "%"] },
"layout": { "contentSize": "720px", "wideSize": "1100px" },
"custom": { "radius": { "card": "12px" } }
}
}
Definir color.custom, customGradient e customFontSize como false remove os seletores livres, de modo que os editores só podem escolher entre os seus presets.
O defaultFontSizes: false faz diferença na versão 3. A dev note da versão 3 do theme.json explica que um tema v3 só pode reutilizar os slugs padrão de tamanho de fonte e de espaçamento do core quando defaultFontSizes ou defaultSpacingSizes está definido como false. Tanto small quanto large são slugs do core.
O appearanceTools: true ativa um grupo de ferramentas de design listadas na referência viva do theme.json. Se você estiver carregando web fonts para fontFamilies, veja como hospedar Google Fonts localmente no WordPress.
Cada tipo de preset gera uma saída diferente:
| Chave | Gera |
|---|---|
color.palette | Uma custom property e três classes (cor de texto, de fundo e de borda) |
typography.fontSizes | Uma custom property e uma classe |
typography.fontFamilies | Uma custom property e uma classe |
spacing.spacingSizes | Apenas uma custom property |
custom | Propriedades --wp--custom--* |
color.custom, customFontSize | Apenas interface do editor, sem CSS |
O theme.json tem duas chaves custom sem relação entre si. settings.color.custom: false oculta o seletor de cores. Já settings.custom é um objeto livre cujos valores viram variáveis CSS.
Como funcionam layout.contentSize e wideSize?
layout.contentSize define a largura padrão do conteúdo dentro de layouts restritos (constrained). layout.wideSize define a largura dos blocos com alinhamento “largo” (wide). O core expõe os dois valores como --wp--style--global--content-size e --wp--style--global--wide-size em :root, depois que o PR #42084 do Gutenberg moveu as custom properties globais de body para lá. Com isso, componentes personalizados podem se alinhar ao grid de blocos:
.site-banner {
max-width: var(--wp--style--global--wide-size);
margin-inline: auto;
}
O que vai em styles?
styles aplica valores padrão em três níveis:
- As propriedades de nível superior se aplicam ao
body. elementsse aplica a elementos HTML comolink(mapeado paraa) e deh1ah6.blocksse aplica a blocos individuais pelo nome.
A seção de estilos do Handbook documenta cada nível.
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"color": { "text": "var(--wp--preset--color--ink)" },
"spacing": { "blockGap": "1.5rem" },
"blocks": {
"core/group": {
"color": { "text": "var(--wp--preset--color--accent)" },
"elements": {
"h2": { "typography": { "fontSize": "var(--wp--preset--font-size--large)" } }
}
}
}
}
}
Saída:
body {
color: var(--wp--preset--color--ink);
}
:root :where(.wp-block-group) {
color: var(--wp--preset--color--accent);
}
:root :where(.wp-block-group h2) {
font-size: var(--wp--preset--font-size--large);
}
Desde o WordPress 6.6, o wrapper :root :where() mantém essas regras com especificidade 0-1-0, a mesma de uma única classe. Qualquer regra do tema com especificidade igual ou maior que seja carregada depois prevalece. Os elementos link e button também aceitam chaves de pseudoestado, como ":hover" e ":focus".
Que CSS o WordPress gera a partir do theme.json?
Todo preset, exceto os filtros de duotone, vira uma CSS custom property chamada --wp--preset--{category}--{slug}. Os presets que geram classes seguem o padrão .has-{slug}-{category}.
Os valores em settings.custom viram propriedades --wp--custom--. O WordPress converte chaves em camelCase para kebab-case e coloca -- entre cada nível de aninhamento. Assim, custom.lineHeight.body vira --wp--custom--line-height--body. O FAQ de nomenclatura do Handbook detalha o nome segmento por segmento.
Com as configurações e os estilos acima, a folha de estilos global contém uma saída como esta. Os exemplos do Handbook mostram body, mas o core atual declara essas propriedades em :root, mudança feita no PR #42084 do Gutenberg:
:root {
--wp--preset--color--ink: #1b1f24;
--wp--preset--color--accent: #3b5bdb;
--wp--preset--font-size--large: 1.5rem;
--wp--custom--radius--card: 12px;
--wp--style--block-gap: 1.5rem;
}
.has-accent-color { color: var(--wp--preset--color--accent) !important; }
O valor raiz de styles.spacing.blockGap é exposto como --wp--style--block-gap. Se os editores podem alterá-lo depende de settings.spacing.blockGap:
| Valor | Controle de espaçamento entre blocos | Saída dos estilos de gap |
|---|---|---|
true | Exibido | Sim |
false | Oculto | Sim, os valores definidos no theme.json continuam sendo aplicados |
null (padrão) | Oculto | Não |
Como são custom properties comuns, qualquer folha de estilos pode usá-las:
.pricing-card {
background: var(--wp--preset--color--ink);
color: #fff;
border-radius: var(--wp--custom--radius--card);
padding: var(--wp--style--block-gap);
font-size: var(--wp--preset--font-size--large);
}
Se você alterar um token no theme.json, esse componente é atualizado junto. A saída do theme.json fica em cache, então defina WP_DEVELOPMENT_MODE como 'theme' no wp-config.php durante o desenvolvimento.
O que o theme.json não faz e como os temas filhos se combinam?
O theme.json cobre apenas as propriedades presentes no seu schema de estilos. Todo o resto vai para o CSS:
- Layout de marcação que não é um bloco, como a saída de plugins ou de terceiros
- Animações, transições e keyframes
- Seletores arbitrários que não estão vinculados a um bloco ou elemento
- Estilização de componentes que vai além das propriedades de estilo disponíveis (o guia tema WordPress responsivo com Bootstrap mostra a abordagem que parte do CSS)
O style.css continua sendo obrigatório, porque contém o cabeçalho do tema. Em um tema filho, o campo Template indica o tema pai pelo nome da pasta dele dentro de wp-content/themes, escrito exatamente igual. A página sobre a folha de estilos principal no Theme Handbook explica esse requisito:
/*
Theme Name: Studio Child
Template: studio
*/
O theme.json de um tema filho é mesclado sobre o do tema pai, mas qualquer lista de presets declarada nele substitui por completo a lista do tema pai. Este arquivo do tema filho deixa apenas uma cor na paleta:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "accent", "color": "#c2255c", "name": "Accent" }
]
}
}
}
Para alterar apenas accent, copie a paleta inteira e edite somente essa entrada:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "ink", "color": "#1b1f24", "name": "Ink" },
{ "slug": "accent", "color": "#c2255c", "name": "Accent" }
]
}
}
}
No theme.json de um tema filho, as chaves de objeto que você não declara continuam sendo herdadas do tema pai. Se o tema filho define apenas styles.spacing.padding.top e bottom, o padding esquerdo e direito do tema pai permanece.
Às vezes um slug removido faz o conteúdo cair em uma cor diferente no site em produção, mas não na pré-visualização do editor. Nesses casos, um session replay (reprodução de sessão) do front-end mostra qual elemento e qual template perderam o preset.
Conclusão
O theme.json é um arquivo de tokens que o WordPress compila em custom properties, classes utilitárias e regras padrão de baixa especificidade. Mantenha os presets em settings, os padrões em styles e todo o resto em CSS que leia as variáveis --wp-- geradas.
Como próximo passo, abra uma página que usa o seu tema, localize global-styles-inline-css nas devtools do navegador e compare as propriedades declaradas com o seu arquivo. Qualquer token ausente indica um erro de slug ou de schema que você pode corrigir antes que chegue aos usuários.
Perguntas frequentes
Por que um valor que alterei no theme.json não aparece no meu site?
Uma personalização salva no Editor do site está sobrescrevendo esse valor. Quando um usuário altera estilos em Aparência > Editor, o WordPress salva esse JSON no banco de dados do site. O Theme Handbook coloca essa configuração do usuário acima dos padrões do core, do theme.json do tema pai e do theme.json do tema filho. Verifique se o token foi personalizado no painel Estilos, redefina-o ali e recarregue o front-end.
Posso escrever CSS puro dentro do theme.json?
Sim. Desde o WordPress 6.2, o theme.json aceita strings de CSS em styles.css para regras globais e na propriedade css de um bloco, dentro de styles.blocks, para regras por bloco. O CSS por bloco aparece para aquele bloco no painel Estilos, onde os usuários podem editá-lo. O CSS personalizado do usuário pode sobrescrever ou remover o CSS do tema adicionado dessa forma, então coloque as regras das quais o design depende em uma folha de estilos enfileirada (enqueued).
Um tema clássico em PHP pode usar o theme.json?
Sim. Um tema clássico pode incluir um theme.json para configurar as opções e os presets do editor de blocos sem chamadas a add_theme_support. A comunidade chama essa configuração de tema híbrido. Adicionar o arquivo não transforma o tema em um tema de blocos, porque o WordPress só trata um tema como tema de blocos quando ele contém templates/index.html. Se o tema mantiver algumas chamadas a add_theme_support, qualquer configuração correspondente no theme.json tem precedência sobre elas.
Como leio os valores do theme.json em PHP?
Chame wp_get_global_settings() para as configurações e wp_get_global_styles() para os estilos. As duas funções recebem um array de caminho, então wp_get_global_settings( array( 'color', 'palette', 'theme' ) ) retorna apenas as entradas da paleta do tema. Um array de contexto com a chave block_name restringe a consulta a um único bloco. Por padrão, o resultado inclui as personalizações do usuário. Defina origin como 'base' no array de contexto para obter apenas os valores do core e do tema.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k