12k
All articles

Qué incluye un archivo theme.json de WordPress

Conoce qué incluye un archivo WordPress theme.json, cómo settings y styles generan variables CSS y cómo funcionan los presets, el CSS personalizado y los temas hijo.

OpenReplay Team
OpenReplay Team
Qué incluye un archivo theme.json de WordPress

Un archivo theme.json de WordPress es un archivo JSON ubicado en la raíz de un tema de bloques que declara los tokens de diseño del tema (colores, tamaños de fuente, familias tipográficas, espaciado y anchos de diseño) una sola vez, de modo que tanto el editor de bloques como el frontend lean los mismos valores.

Si vienes de flujos de trabajo con tokens de diseño, el archivo te resultará familiar hasta que intentes encontrar el CSS que genera o averiguar por qué un tema hijo eliminó la mitad de la paleta. Este artículo recorre cada parte del archivo, muestra el CSS que WordPress genera a partir de él, explica cómo usar esas variables en tu propia hoja de estilos y aborda los casos en los que sigue siendo necesario escribir CSS a mano. Todos los ejemplos usan la versión 3 del esquema, introducida en WordPress 6.6.

Puntos clave

  • theme.json tiene dos claves principales de nivel superior: settings determina qué controles y presets ofrece el editor, y styles aplica valores predeterminados a la página, a los elementos HTML y a bloques individuales.
  • Todos los presets, excepto los filtros duotono, se convierten en una propiedad personalizada de CSS con el nombre --wp--preset--{category}--{slug}, de modo que un color de la paleta con el slug ink está disponible como var(--wp--preset--color--ink) en cualquier hoja de estilos.
  • Los valores dentro de settings.custom se convierten en propiedades --wp--custom--*: el camelCase se transforma en kebab-case y cada nivel de anidamiento se separa con un doble guion.
  • El theme.json de un tema hijo se fusiona sobre el del tema padre, pero cualquier lista de presets que declare reemplaza por completo la lista del padre.

¿Qué es theme.json?

theme.json es el archivo de tokens de diseño de un tema de bloques. En él declaras una sola vez los colores, la tipografía, el espaciado y los anchos de diseño. Después, WordPress usa esos valores para construir los controles del editor y generar la hoja de estilos del frontend. El nivel superior es reducido: $schema, version, settings y styles, además de customTemplates, templateParts y patterns para registrar plantillas, partes de plantilla y patrones del Directorio de Patrones.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {},
  "styles": {}
}

Si apuntas $schema al esquema de theme.json de trunk, obtendrás autocompletado y validación en VS Code.

¿Por qué existe theme.json?

theme.json sustituye tres elementos que solían desincronizarse entre sí: los flags de add_theme_support() en PHP, la configuración del editor y el CSS del frontend. La guía de configuración global del Block Editor Handbook relaciona cada flag antiguo de add_theme_support con una clave de theme.json, y si un tema define lo mismo en ambos lugares, prevalece el valor de theme.json.

add_theme_supportEquivalente en theme.json
editor-color-palettesettings.color.palette
editor-font-sizessettings.typography.fontSizes
disable-custom-colorssettings.color.custom: false
custom-unitssettings.spacing.units
appearance-toolssettings.appearanceTools: true

¿Qué incluye settings?

settings controla lo que ofrece el editor: qué presets aparecen en los selectores y qué controles de formato libre están permitidos. Los presets son arrays de objetos, cada uno con un slug, un valor y un name visible.

{
  "$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" } }
  }
}

Establecer color.custom, customGradient y customFontSize en false elimina los selectores libres, de modo que los editores solo pueden elegir entre tus presets. defaultFontSizes: false es importante en la versión 3. La nota para desarrolladores sobre la versión 3 de theme.json explica que un tema v3 solo puede reutilizar los slugs predeterminados de tamaño de fuente y de tamaño de espaciado del core cuando defaultFontSizes o defaultSpacingSizes está establecido en false, y tanto small como large son slugs del core. appearanceTools: true activa un conjunto de herramientas de diseño que se enumeran en la referencia viva de theme.json. Si cargas fuentes web para fontFamilies, consulta cómo alojar Google Fonts en tu propio servidor en WordPress.

Cada tipo de preset produce una salida distinta:

ClaveGenera
color.paletteUna propiedad personalizada más tres clases (color de texto, de fondo y de borde)
typography.fontSizesUna propiedad personalizada más una clase
typography.fontFamiliesUna propiedad personalizada más una clase
spacing.spacingSizesSolo una propiedad personalizada
customPropiedades --wp--custom--*
color.custom, customFontSizeSolo interfaz del editor, sin CSS

theme.json tiene dos claves custom que no guardan relación entre sí. settings.color.custom: false oculta el selector de color. settings.custom es un objeto de formato libre cuyos valores se convierten en variables CSS.

¿Cómo funcionan layout.contentSize y wideSize?

layout.contentSize define el ancho predeterminado del contenido dentro de los diseños restringidos (constrained layouts). layout.wideSize define el ancho de los bloques con alineación “ancha”. El core expone ambos valores como --wp--style--global--content-size y --wp--style--global--wide-size en :root, desde que el PR #42084 de Gutenberg trasladó allí las propiedades personalizadas globales desde body. Esto permite que los componentes personalizados se alineen con la retícula de bloques:

.site-banner {
  max-width: var(--wp--style--global--wide-size);
  margin-inline: auto;
}

¿Qué incluye styles?

styles aplica valores predeterminados en tres niveles. Las propiedades de nivel superior se aplican a body; elements se aplica a elementos HTML como link (que corresponde a a) y de h1 a h6; y blocks se aplica a bloques individuales por su nombre. La sección de estilos del Handbook documenta cada nivel.

{
  "$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)" } }
        }
      }
    }
  }
}

Salida:

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 WordPress 6.6, el envoltorio :root :where() mantiene estas reglas con una especificidad de 0-1-0, la misma que una sola clase. Cualquier regla del tema con especificidad igual o superior que se cargue después prevalece. Los elementos link y button también aceptan claves de pseudoestado como ":hover" y ":focus".

¿Qué CSS genera WordPress a partir de theme.json?

Todos los presets, excepto los filtros duotono, se convierten en una propiedad personalizada de CSS con el nombre --wp--preset--{category}--{slug}, y los presets que generan clases siguen el patrón .has-{slug}-{category}. Los valores dentro de settings.custom se convierten en propiedades --wp--custom--. WordPress transforma las claves en camelCase a kebab-case e inserta -- entre cada nivel de anidamiento, de modo que custom.lineHeight.body se convierte en --wp--custom--line-height--body. Las preguntas frecuentes sobre nomenclatura del Handbook desglosan el nombre segmento a segmento.

Con los ajustes y estilos anteriores, la hoja de estilos global contiene una salida como esta. Los ejemplos del Handbook muestran body, pero el core actual declara estas propiedades en :root, un cambio introducido en el PR #42084 de 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; }

El valor raíz de styles.spacing.blockGap se expone como --wp--style--block-gap. Que los editores puedan modificarlo depende de settings.spacing.blockGap:

ValorControl de espaciado de bloquesSalida de estilos de separación (gap)
trueVisibleSí
falseOcultoSí, los valores definidos en theme.json se siguen aplicando
null (predeterminado)OcultoNo

Son propiedades personalizadas normales, por lo que cualquier hoja de estilos puede utilizarlas:

.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);
}

Si cambias un token en theme.json, este componente se actualiza en consecuencia. La salida de theme.json se almacena en caché, así que establece WP_DEVELOPMENT_MODE en 'theme' dentro de wp-config.php durante el desarrollo.

¿Qué no puede hacer theme.json y cómo se combinan los temas hijo?

theme.json solo abarca las propiedades incluidas en su esquema de estilos. Todo lo demás va en CSS:

  • El diseño del marcado que no es un bloque, como la salida de plugins o de terceros
  • Animaciones, transiciones y keyframes
  • Selectores arbitrarios que no están vinculados a un bloque o elemento
  • El estilo de componentes que va más allá de las propiedades de estilo disponibles (la guía sobre cómo crear un tema de WordPress responsive con Bootstrap muestra el enfoque basado en CSS)

style.css sigue siendo obligatorio, ya que contiene la cabecera del tema. En un tema hijo, el campo Template indica el tema padre mediante el nombre de su carpeta dentro de wp-content/themes, escrito exactamente igual, tal como explica la página sobre la hoja de estilos principal del Theme Handbook:

/*
Theme Name: Studio Child
Template: studio
*/

El theme.json de un tema hijo se fusiona sobre el del tema padre, pero cualquier lista de presets que declare reemplaza por completo la lista del padre. Este archivo hijo deja un solo color en la paleta:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {
    "color": {
      "palette": [
        { "slug": "accent", "color": "#c2255c", "name": "Accent" }
      ]
    }
  }
}

Para cambiar solo accent, copia la paleta completa y modifica únicamente esa 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" }
      ]
    }
  }
}

En el theme.json de un tema hijo, las claves de objeto que no declares se siguen heredando del padre. Si el hijo define solo styles.spacing.padding.top y bottom, el relleno izquierdo y derecho del padre se mantiene. Cuando la eliminación de un slug hace que el contenido recurra a un color diferente en el sitio en producción pero no en la vista previa del editor, una reproducción de sesión (session replay) del frontend muestra qué elemento y qué plantilla perdieron el preset.

Conclusión

theme.json es un archivo de tokens que WordPress compila en propiedades personalizadas, clases utilitarias y reglas predeterminadas de baja especificidad. Mantén los presets en settings, los valores predeterminados en styles y todo lo demás en CSS que lea las variables --wp-- generadas. Como siguiente paso, abre global-styles-inline-css en las herramientas de desarrollo de tu navegador en una página que use tu tema y compara las propiedades declaradas con tu archivo. Cualquier token que falte apunta a un error de slug o de esquema que puedes corregir antes de que llegue a los usuarios.

Preguntas frecuentes

¿Por qué un valor que cambié en theme.json no aparece en mi sitio?

Una personalización guardada en el Editor del sitio lo está sobrescribiendo. Cuando un usuario cambia los estilos en Apariencia > Editor, WordPress guarda ese JSON en la base de datos del sitio, y el Theme Handbook sitúa esta configuración de usuario por encima de los valores predeterminados del core, del theme.json del tema padre y del theme.json del tema hijo. Comprueba si el token se personalizó en el panel Estilos y restablécelo allí; después, recarga el frontend.

¿Puedo escribir CSS directamente dentro de theme.json?

Sí. Desde WordPress 6.2, theme.json acepta cadenas de CSS en styles.css para reglas globales y en la propiedad css de un bloque dentro de styles.blocks para reglas por bloque. El CSS por bloque aparece para ese bloque en el panel Estilos, donde los usuarios pueden editarlo. El CSS personalizado del usuario puede sobrescribir o eliminar el CSS del tema añadido de esta forma, así que coloca las reglas de las que depende el diseño en una hoja de estilos encolada.

¿Puede un tema clásico en PHP usar theme.json?

Sí. Un tema clásico puede incluir theme.json para configurar los ajustes y presets del editor de bloques sin llamadas a add_theme_support, una configuración que la comunidad denomina tema híbrido. Añadir el archivo no lo convierte en un tema de bloques, porque WordPress solo considera un tema como tema de bloques cuando contiene templates/index.html. Si el tema conserva algunas llamadas a add_theme_support, cualquier ajuste equivalente en theme.json tiene prioridad sobre ellas.

¿Cómo leo los valores de theme.json en PHP?

Llama a wp_get_global_settings() para los ajustes y a wp_get_global_styles() para los estilos. Ambas funciones aceptan un array de ruta, por lo que wp_get_global_settings( array( 'color', 'palette', 'theme' ) ) devuelve solo las entradas de la paleta del tema. Un array de contexto con la clave block_name limita la consulta a un único bloque. De forma predeterminada, el resultado incluye las personalizaciones del usuario. Establece origin en 'base' en el array de contexto para obtener únicamente los valores del core y del tema.

DevTools for the frontend

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

We use cookies to improve your experience. By using our site, you accept cookies.