Un sistema de diseño en WordPress es el conjunto de tokens, controles permitidos en el editor y layouts insertables que Gutenberg va a aplicar de verdad. Un archivo de Figma no obliga a nada en el sitio publicado. En 2026 ese contrato son theme.json versión 3, la carpeta /patterns y unos pocos bloques propios. Todo lo demás es un prototipo o un objeto en la base de datos, y conviene tratarlo como tal.
El fallo se repite en los sitios editoriales grandes: el manual de marca vive en Figma, el CSS vive en cinco hojas de estilo y el editor sigue ofreciendo un selector de color libre. Marketing publica entonces un hexadecimal de campaña que existe en una sola landing. La campaña siguiente lo copia. Seis meses después nadie sabe cuál es el verde de la marca. Gutenberg puede impedirlo, pero solo si apaga esos controles y pone la paleta en theme.json.
Esto no va de migrar desde un maquetador. Va de la capa posterior a esa decisión: cómo se mantiene coherente el sistema cuando los editores entran al insertador todos los días.
Conozca más sobre el desarrollo WordPress profesional en WPPoland.
1. La fuente única de verdad: theme.json versión 3
La especificación viva es theme.json versión 3, introducida en WordPress 6.6. Los archivos con version: 2 siguen cargando, pero los ajustes nuevos aterrizan en la versión 3. No existe una versión 4, por mucho que lo repitieran los resúmenes de 2025.
El archivo gobierna dos cosas distintas: settings es lo que el editor tiene permitido hacer, y styles es el aspecto por defecto cuando nadie sobrescribe un bloque. Mezclarlas es como se acaba publicando un valor por defecto bonito que el editor puede romper con un clic.
Gobernanza global
En lugar de repartir hexadecimales por cinco hojas de estilo, define la paleta una vez. Gutenberg emite las variables CSS y los controles del editor a partir de ella. Lo que el archivo no puede hacer por sí solo es cerrar el selector de color: eso exige apagar los flags de la sección siguiente.
Apunte $schema a la versión mínima de WordPress que soporta, no a trunk, salvo que el sitio corra siempre el plugin Gutenberg.
Estructura de theme.json versión 3:
{
"$schema": "https://schemas.wp.org/wp/6.6/theme.json",
"version": 3,
"settings": {
"color": {
"custom": false,
"customDuotone": false,
"customGradient": false,
"defaultPalette": false,
"defaultGradients": false,
"palette": [
{ "slug": "primary", "color": "#1a1a2e", "name": "Primario" },
{ "slug": "secondary", "color": "#16213e", "name": "Secundario" },
{ "slug": "accent", "color": "#0f3460", "name": "Acento" },
{ "slug": "highlight", "color": "#e94560", "name": "Destacado" }
]
},
"typography": {
"customFontSize": false,
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Pequeño" },
{ "slug": "medium", "size": "1rem", "name": "Medio" },
{ "slug": "large", "size": "1.5rem", "name": "Grande" },
{ "slug": "x-large", "size": "2.25rem", "name": "Extra Grande" }
]
},
"spacing": {
"customSpacingSize": false,
"spacingSizes": [
{ "slug": "10", "size": "0.5rem", "name": "XS" },
{ "slug": "20", "size": "1rem", "name": "S" },
{ "slug": "30", "size": "1.5rem", "name": "M" },
{ "slug": "40", "size": "2.5rem", "name": "L" },
{ "slug": "50", "size": "4rem", "name": "XL" }
]
}
}
}Controles estrictos
color.custom: false es el equivalente moderno de add_theme_support( 'disable-custom-colors' ). defaultPalette: false esconde las muestras grises y azules del núcleo, de modo que el selector enseñe solo sus slugs. La correspondencia está en el manual de Global Settings and Styles. Si esos dos flags se quedan en su valor por defecto (true), no tiene un sistema de diseño: tiene una sugerencia.
appearanceTools: true no es un interruptor de bloqueo. Enciende los controles de borde, margen, padding, sticky, altura mínima e interlineado. Actívelo cuando el trabajo de layout deba hacerse en el editor; déjelo apagado, o fije las claves una a una, cuando quiera que el espaciado salga solo de los presets.
Restricciones habituales:
- Deshabilitar el selector de color personalizado
- Limitar fuentes a la familia tipográfica corporativa
- Restringir el espaciado a los valores de
spacingSizes - Fijar
templateLocken las plantillas que no deben reordenarse - Ofrecer patrones aprobados como contenido inicial en lugar de un lienzo vacío
Organización modular de theme.json
WordPress ya reparte el archivo por tres vías propias: el tema hijo fusiona su theme.json sobre el del padre, las variaciones de estilo viven como archivos JSON sueltos en /styles, y PHP puede retocar el árbol con el filtro wp_theme_json_data_theme cuando un sitio de la red necesita otro primario sin bifurcar el tema.
Compilar parciales con un script propio es legítimo si su equipo ya mantiene ese build, pero no es una funcionalidad de WordPress ni está documentada como tal:
theme/
├── theme.json (compilado)
├── config/
│ ├── colors.json
│ ├── typography.json
│ ├── spacing.json
│ ├── layout.json
│ └── custom.json
└── build-theme-json.js (script de compilacion)Esta estructura permite que diseño, desarrollo y marketing gestionen sus áreas sin pisarse, y el script de compilación fusiona todo en el theme.json final. El coste es que ese script pasa a ser código que alguien tiene que mantener.
2. Block Patterns: El fin de las páginas vacías
Dar a un editor una página en blanco es una invitación al desastre. La alternativa es una biblioteca de patrones que arranque el contenido dentro de los parámetros de marca. Antes de listarla conviene fijar la distinción que más proyectos quema: un patrón del tema no es un patrón sincronizado.
El manual de temas lo dice sin rodeos: los patrones que coloca en /patterns no están sincronizados. Son plantillas para la siguiente inserción. WordPress copia el marcado dentro de la entrada. Si edita el archivo PHP más tarde, las páginas ya publicadas no cambian.
| Tipo | Vive en | Actualiza páginas existentes | Viaja entre entornos |
|---|---|---|---|
Patrón del tema (/patterns) | el tema, en Git | no | sí, con el despliegue |
| Patrón sincronizado | la base de datos | sí | solo si copia las entradas wp_block |
| Parte de plantilla (cabecera, pie) | archivo del tema hasta que se edita, luego BD | sí, como parte | archivo hasta que alguien la personaliza |
Registre los patrones del tema dejando un archivo PHP con su cabecera en /patterns, que es la ruta que recomienda el capítulo de registro de patrones, o llamando a register_block_pattern() en init. Un patrón, un método. No registre el mismo slug dos veces.
Patrones atómicos
Componentes pequeños y reutilizables como un “Header Hero” o una “Tarjeta de Funcionalidad”. Estos son los bloques de construcción básicos del sistema de diseño.
Ejemplos de patrones atómicos:
- Hero Header: Título, subtitulo, CTA y imagen de fondo
- Tarjeta de servicio: Icono, título, descripción y enlace
- Testimonio: Foto, cita, nombre y cargo
- Estadística: Número grande, etiqueta y contexto
- CTA Banner: Título, descripción y botón de acción
Patrones de página completa
Layouts completos para landing pages, casos de estudio o whitepapers que pueden insertarse con un solo clic. Los editores seleccionan un patrón y simplemente reemplazan el contenido de ejemplo con su contenido real.
Biblioteca de patrones de página típica:
- Landing page de servicio
- Caso de estudio con métricas
- Página de producto con especificaciones
- Página de equipo con biografías
- Página de FAQ con schema automático
- Página de contacto con formulario y mapa
Patrones sincronizados (Synced Patterns)
Los patrones sincronizados (los antiguos bloques reutilizables, hasta WordPress 6.3) son entradas wp_block en la base de datos y se crean desde el editor. Si el equipo legal cambia el patrón de “Disclaimer”, todas sus instancias cambian con él. WordPress 6.6 añadió sobrescrituras en patrones sincronizados, de modo que una tarjeta puede conservar el diseño compartido y variar el encabezado y la imagen por instancia.
El precio es que esos objetos no están en Git. Staging y producción necesitan cada uno la misma fila wp_block, o los recrea a mano.
Casos de uso para patrones sincronizados:
- Avisos legales y disclaimers
- Barras de cookies y consentimiento
- Banners de promoción temporales
- Bloques de información corporativa (dirección, teléfono)
- CTAs globales con el mensaje de campaña vigente
Versionado de patrones
WordPress no versiona patrones: no hay estados, ni aprobaciones, ni migración automática de instancias. Lo que sí existe es Git sobre la carpeta /patterns, y ahí el ciclo lo impone el equipo:
- Borrador: el patrón nuevo vive en una rama.
- Revisión: marca o legal lo aprueban en la pull request.
- Publicado: se despliega y aparece en el insertador.
- Retirado: se quita del insertador con
register_block_patternfuera o borrando el archivo. Las páginas que ya lo insertaron conservan su marcado y hay que tocarlas una a una.
3. Design Tokens: Conectando código y creatividad
Los design tokens representan las piezas más pequeñas de su marca (colores, unidades de espaciado, profundidades de sombra). Son el lenguaje compartido entre diseñadores y desarrolladores.
Implementación nativa
Cada slug de la paleta se convierte en una propiedad personalizada --wp--preset--color--{slug} y en clases de utilidad como .has-{slug}-color y .has-{slug}-background-color. Los tamaños de fuente y el espaciado siguen el mismo patrón con --wp--preset--font-size--{slug} y --wp--preset--spacing--{slug}. Esa nomenclatura está en el mismo manual. El CSS propio del tema debería consumir esas variables y no un segundo juego de tokens --brand-primary que acabará divergiendo.
Ahí termina la historia de los design tokens en Gutenberg. WordPress no importa Tokens Studio: emite presets a partir de theme.json. Si el equipo de diseño ya tiene sus tokens en JSON, el pipeline honesto es un paso de build que escriba settings.color.palette y las escalas de tipografía y espaciado dentro de theme.json.
Tokens típicos de un sistema de diseño empresarial:
/* Colores de marca */
--wp--preset--color--primary: #1a1a2e;
--wp--preset--color--secondary: #16213e;
--wp--preset--color--accent: #0f3460;
/* Tipografia */
--wp--preset--font-family--heading: 'Inter', sans-serif;
--wp--preset--font-family--body: 'Source Sans Pro', sans-serif;
/* Espaciado */
--wp--preset--spacing--10: 0.5rem;
--wp--preset--spacing--20: 1rem;
--wp--preset--spacing--30: 1.5rem;
/* Sombras */
--wp--custom--shadow--sm: 0 1px 2px rgba(0,0,0,0.1);
--wp--custom--shadow--md: 0 4px 6px rgba(0,0,0,0.1);
--wp--custom--shadow--lg: 0 10px 15px rgba(0,0,0,0.1);
/* Bordes */
--wp--custom--border-radius--sm: 4px;
--wp--custom--border-radius--md: 8px;
--wp--custom--border-radius--lg: 16px;Cambio de tema
¿Quiere una paleta alternativa? La vía del núcleo es una variación de estilos: un archivo JSON en /styles que redefine los mismos slugs y que el usuario elige en el editor del sitio. No hace falta tocar el CSS del tema, porque los bloques ya consumen las variables de preset.
Variación de estilos en /styles/oscuro.json:
{
"$schema": "https://schemas.wp.org/wp/6.6/theme.json",
"version": 3,
"title": "Oscuro",
"settings": {
"color": {
"palette": [
{ "slug": "base", "color": "#111111", "name": "Base" },
{ "slug": "contrast", "color": "#f5f5f5", "name": "Contraste" }
]
}
},
"styles": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
}
}
}Un conmutador claro/oscuro automático por prefers-color-scheme no viene de serie: eso sigue siendo CSS que usted escribe.
Tokens multi-marca
Para organizaciones con múltiples marcas bajo un mismo paraguas corporativo:
- Tokens base compartidos (espaciado, grid, sombras)
- Tokens de marca específicos (colores, tipografía, iconografía)
- Tokens de contexto (variaciones por página o sección)
- Tokens de estado (hover, activo, deshabilitado)
4. Gobernanza de bloques personalizados con React
Encabezado, párrafo e imagen del núcleo cubren la mayoría de los módulos de marketing. Un bloque propio se gana su sitio cuando el layout necesita atributos que se puedan validar: una tabla comparativa que debe llevar un SKU, una moneda y una fecha de verificación. Si el bloque es solo una piel alrededor de bloques internos, prefiera un patrón.
Componentes React avanzados
Construimos los bloques con @wordpress/scripts, mantenemos el marcado de save aburrido y evitamos recrear un maquetador dentro del inspector.
Estructura de un bloque personalizado empresarial:
blocks/
├── product-comparison/
│ ├── block.json
│ ├── edit.js (interfaz del editor)
│ ├── save.js (salida del frontend)
│ ├── style.scss (estilos del frontend)
│ ├── editor.scss (estilos del editor)
│ └── transforms.js (conversiones entre bloques)Validación de atributos
Conviene saber hasta dónde llega block.json. Los atributos declaran type, enum, default y de dónde se extrae el valor. enum sí restringe el valor guardado; en cambio no hay maxLength, minimum ni maximum que Gutenberg haga cumplir por usted. Los límites de rango y longitud se aplican en el componente de edición o en el guardado por REST.
Atributos en block.json:
{
"attributes": {
"heading": { "type": "string", "default": "" },
"price": { "type": "number", "default": 0 },
"variant": {
"type": "string",
"enum": ["primary", "secondary", "accent"],
"default": "primary"
}
}
}El límite real se impone en edit.js:
<RichText
tagName="h3"
value={attributes.heading}
onChange={(heading) => setAttributes({ heading: heading.slice(0, 120) })}
/>Bloques compuestos con bloqueo
Para layouts complejos que deben mantener su estructura:
// Bloquear la estructura interna del bloque
<InnerBlocks
template={TEMPLATE}
templateLock="all"
allowedBlocks={['core/heading', 'core/paragraph', 'core/button']}
/>templateLock="all" impide reordenar, añadir y eliminar. templateLock="insert" deja reordenar pero no insertar nada nuevo. El mismo bloqueo se aplica a las plantillas de página desde theme.json y desde el editor del sitio, y ahí es donde se sostienen los tipos de página que deben permanecer en molde.
Los editores pueden cambiar el texto y las imágenes, pero no pueden reorganizar, eliminar o agregar bloques fuera de la estructura definida. Esta restricción es esencial para mantener la integridad visual de la marca.
Sistema de iconografía
Un sistema de diseño completo incluye una biblioteca de iconos consistente:
- Iconos SVG integrados como bloques personalizados
- Tamaños y colores tomados de las variables de preset, nunca hexadecimales sueltos
- Búsqueda y filtrado en el editor
- Un único origen del SVG en el repositorio, exportado a mano desde el archivo de diseño
5. Cerrando la brecha: de Figma a theme.json
No existe sincronización oficial entre Figma y WordPress. El núcleo no lee archivos de Figma y ningún plugin de Figma escribe en producción por sí mismo. Lo que sí se puede construir es un paso de build: los tokens salen de la herramienta de diseño como JSON y un script los escribe dentro de theme.json, que es lo que el despliegue envía.
Exportación JSON
Los diseñadores exportan sus estilos como un objeto JSON, y un script propio lo transforma a la forma que espera theme.json. Los nombres casi nunca coinciden de entrada, así que ese mapeo es código que alguien mantiene. El proceso puede ser manual (una exportación periódica) o dispararse desde CI.
Flujo de trabajo de sincronización:
- El diseñador actualiza un color en Figma
- Un plugin de Figma exporta los tokens actualizados como JSON
- Un webhook dispara el pipeline CI/CD
- El script de compilación actualiza
theme.json - Las pruebas visuales comparan capturas antes y después
- Una persona revisa el diff de
theme.jsony aprueba la pull request
Despliegues automatizados
El pipeline puede llegar hasta abrir la pull request con el theme.json regenerado. Recomendamos parar ahí: un webhook que despliega producción sin que nadie lea el diff no es un sistema, es un demo. El color de marca es justo el tipo de cambio que merece una revisión humana.
Herramientas de sincronización 2026
| Herramienta | Función | Qué hay que escribir igualmente |
|---|---|---|
| Tokens Studio for Figma | Exporta tokens a JSON | El mapeo de ese JSON a settings de theme.json |
| Style Dictionary | Transforma tokens entre plataformas | Un formato de salida propio para theme.json |
| GitHub Actions | Ejecuta el build y abre la PR | El paso de revisión antes del merge |
| Chromatic o Playwright | Comparación visual | Las rutas y estados que se capturan |
Documentación viva
La documentación no se genera sola, pero puede salir casi gratis de material que ya existe:
- Una página del propio sitio que inserte cada patrón de la biblioteca, editable por el equipo
- El historial de Git de
/patternsytheme.jsoncomo changelog visual - Las capturas de la comparación visual como registro de antes y después
6. Accesibilidad como pilar del sistema de diseño
Un sistema de diseño no está completo sin accesibilidad desde la base. Nada de esto lo hace WordPress por usted: son comprobaciones que se montan alrededor del tema.
Contraste de color automático
La paleta es una lista corta de hexadecimales en un archivo JSON, así que el contraste se puede comprobar en el build:
- Un test que recorra los pares de texto y fondo permitidos y calcule la ratio WCAG
- Fallo de la build cuando un par baja de 4.5:1 en texto normal
- La combinación problemática señalada por slug, no por hexadecimal
- El editor de bloques ya avisa en el inspector cuando el contraste elegido es insuficiente, pero ese aviso no bloquea la publicación
Componentes accesibles por defecto
Cada bloque propio que escribimos incluye:
- Roles ARIA apropiados
- Navegación por teclado completa
- Textos alternativos obligatorios para imágenes
- Etiquetas descriptivas para elementos interactivos
- Skip links integrados en la navegación
Pruebas de accesibilidad automatizadas
Integradas en el pipeline de CI/CD:
- Auditoría de accesibilidad de Lighthouse en cada despliegue
- axe-core para detectar problemas de ARIA y de roles
- Pruebas de navegación por teclado sobre las plantillas principales
- Verificación de contraste en cada variación de estilos publicada
Conviene recordar el límite: las herramientas automáticas detectan una parte de los criterios WCAG. El resto sigue siendo revisión manual con teclado y lector de pantalla.
7. Rendimiento del sistema de diseño
Un sistema de diseño mal montado puede ser más lento que el desarrollo a medida, porque cada patrón arrastra su CSS. El rendimiento es parte del contrato.
Estilos de bloque por bloque
Lo que sí hace el núcleo es cargar los estilos de los bloques del núcleo por separado, en lugar de una hoja única. Los temas de bloques lo tienen activado; un tema clásico lo pide así:
add_filter( 'should_load_separate_core_block_assets', '__return_true' );Con eso, una página que no usa la galería no carga el CSS de la galería. Lo que no hace WordPress es generar CSS crítico ni eliminar reglas sin usar: eso sigue siendo trabajo de su build o de una capa de caché.
Carga de bloques bajo demanda
Los bloques personalizados se cargan solo cuando son necesarios:
// Solo cargar el JS del bloque si está presente en la página
function conditionally_load_block_assets() {
if (has_block('wppoland/product-comparison')) {
wp_enqueue_script('product-comparison-block');
}
}
add_action('enqueue_block_assets', 'conditionally_load_block_assets');Presupuesto de rendimiento por componente
Los presupuestos por componente son una decisión de equipo, no una medida del núcleo. Sirven cuando alguien los revisa en cada pull request:
| Componente | CSS objetivo | JS objetivo | Imágenes |
|---|---|---|---|
| Hero | 2 KB | 0 KB | 1 imagen optimizada |
| Tarjeta de servicio | 1 KB | 0 KB | 1 icono SVG |
| Carrusel | 1,5 KB | 3 KB diferido | N imágenes con carga diferida |
| Tabla comparativa | 2 KB | 1 KB | 0 |
| Acordeón de FAQ | 1 KB | 0 KB con <details> | 0 |
La última fila es el ejemplo del criterio: un acordeón hecho con <details> y <summary> no necesita JavaScript y ya es accesible por teclado.
8. Por qué WPPoland es su socio de sistemas de diseño
No diseñamos temas sueltos, montamos el contrato que el equipo del cliente va a mantener después. En desarrollo WordPress la secuencia es siempre la misma:
- Tokens en
theme.jsonversión 3, con el selector bloqueado y la paleta del núcleo oculta. - Un juego corto de patrones en
/patternspara los layouts que marketing repite de verdad, versionados en Git con el resto del tema. - Uno o dos patrones sincronizados para el texto que gobierna legal, exportados junto con el contenido y nunca dejados en “ya lo recreamos en producción”.
- Bloques propios solo después de que un patrón sobre bloques del núcleo haya fallado por una restricción real de atributos.
- Una revisión en el editor del sitio con una cuenta de editor, no de administrador, porque el administrador sigue viendo herramientas que usted creía haber escondido.
Ese último punto es el que más veces cambia el resultado de una auditoría.
9. Conclusión: escalar sin comprometer
Si el front ya usa CSS de utilidades, mantenga theme.json como origen de los tokens y mapee los slugs hacia esas clases. A Gutenberg le da igual qué framework consuma --wp--preset--color--primary; lo que le importa es que el editor y el front nombren el mismo slug.
El sistema funciona cuando una landing nueva es una inserción de patrón, el selector de color tiene ocho muestras, y la petición de “solo este naranja” llega como una pull request a theme.json y no como un hexadecimal dentro de un bloque Grupo.
¿Listo para montar su sistema de diseño en WordPress? Escríbanos desde contacto.
Recursos relacionados
- Desarrollo WordPress profesional - Arquitectura empresarial de temas
- Rediseño WordPress - Modernización de sistemas visuales
- Optimización de velocidad WordPress - Rendimiento de sistemas de diseño
- Mantenimiento WordPress - Mantenimiento continuo de componentes
- Migración a Astro y Next.js - Sistemas de diseño en arquitecturas headless






