WordPress / WordPress/gutenberg

Template style variations

Open
#75,331 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

[Type] Enhancement
Dominant language
JavaScript
Stars
11.8k
Forks
4.9k
PR merge metrics
PR metrics pending

Description

What problem does this address?

The global styles system (wp_global_styles posts and theme.json) operates site-wide — all templates inherit the same theme styles and user customizations. This makes several real-world scenarios unnecessarily difficult:

Seasonal or campaign pages: A site wants holiday-specific templates (Christmas, Halloween, etc.) with unique color schemes and typography without affecting the main site theme.

Multi-brand sites: An organization managing multiple brands from one WordPress installation needs templates for each brand with distinct styling.

Plugin-specific templates: Plugins providing specialized functionality (forums, e-commerce, membership areas) want templates with tailored design systems that complement but don't override the site theme.

Email editor integration: One of the goals of this proposal is to enable better integration of email editors with the site editor. For example, the WooCommerce email editor registers email templates and uses a custom theme.json with email-safe fonts and spacing. It syncs only a subset of the site theme's styles and manually merges them via a custom Theme_Controller. This proposal would let email editors use style variations with an email-optimized base theme instead, removing the need for custom merge logic.

What is your proposed solution?

A standardized way for templates to be associated with specific style variations, enabling scoped style customizations per template.

Core Concepts
  1. Template-Style Association: Templates can reference a specific style variation by its ID.
  2. Scoped Customizations: Style variations are user customizations scoped to specific templates rather than applied globally. Users can edit a variation's styles in the existing Styles UI — edits are saved to a dedicated wp_global_styles post for that variation.
  3. Base Theme Support: Style variations can optionally specify a "base theme" — an alternative theme.json that replaces the active theme's base layer. This lets plugins define a completely different design foundation (e.g., email-safe typography) while still participating in the standard style cascade.
  4. Registration API: Plugins and themes register style variations and base themes via PHP functions, making the system extensible by third parties.
  5. Automatic Editor Integration: The block editor automatically loads template-specific styles when editing a template that has an associated variation.
  6. Editing style variation: User can edit style variations in Styles editing UI.
Style Variations
  • Style variations can be registered by the active theme (via styles/ directory JSON files) or by plugins (via PHP API).
  • All registered variations appear in the template style variation picker.
  • Once a variation is associated with a template and edited by the user, edits are saved to a wp_global_styles post linked to the original registered variation. Multiple templates sharing the same variation share this post.
Base Themes

A base theme allows replacing the active theme's theme.json entirely for templates using a given variation:

  • Plugins or themes can register additional theme.json configurations as base themes, each with a unique ID.
  • A style variation can reference a base theme. When it does, that base theme is used instead of the active theme in the style cascade. When no base theme is specified, the active theme is used as normal.
Data Model

Three entities and their relationships:

wp_template post                  Style Variation (registered)         wp_global_styles post
┌─────────────────────┐          ┌──────────────────────────┐         ┌──────────────────────┐
│ post_type:           │          │ ID: "plugin//dark-mode"  │         │ post_type:            │
│   wp_template        │────────▶│ title, data (styles/     │◀────────│   wp_global_styles    │
│                      │         │   settings), base_theme  │         │ (user edits for this  │
│ variation ID         │         └──────────────────────────┘         │  variation)           │
│   = "plugin//dark-   │                    │                         │ source variation ID    │
│     mode"            │                    ▼ (optional)              │   = "plugin//dark-    │
└─────────────────────┘           Base Theme (registered)             │     mode"             │
                                  ┌──────────────────────────┐        └──────────────────────┘
                                  │ ID: "plugin//email-base" │
                                  │ Full theme.json data     │
                                  └──────────────────────────┘
  • A template references a variation by its registered ID.
  • A variation's user edits are stored in a wp_global_styles post linked back to the variation by its registered ID. This is a one-to-one relationship: one post per variation, shared by all templates using it.
  • A base theme is referenced by the variation's registration data (not stored on the template).
Style Cascade

When rendering a template (in the editor or on the frontend), the merge order follows the existing global styles cascade:

Core defaults → Block styles → Theme (or Base Theme if specified) → Variation user customizations

If the template has no associated variation, the standard global styles apply unchanged.

Proof of Concept

An exploratory implementation is available at https://github.com/WordPress/gutenberg/pull/75330 demonstrating the full flow: PHP registries, REST API, editor integration, frontend rendering, and a demo with sample variations.

https://github.com/user-attachments/assets/06a4c744-ac0b-4d3b-a61b-90a72405ee12

Backward Compatibility

This feature is purely additive — when no style variation is assigned to a template, the existing global styles cascade applies unchanged. Templates without a _wp_style_variation_id meta value behave exactly as they do today: they inherit site-wide styles from the default wp_global_styles post and the active theme's theme.json. No existing APIs, hooks, or data structures are modified; the new registries, meta fields, and REST endpoints only activate when the feature is explicitly used.

Related Issues

This proposal builds on and extends several existing discussions:

Open Questions

  1. Full snapshot vs. diff storage: When saving variation edits, should we store the complete variation state or only the changed values (diff from the registered defaults)?
  2. Are base themes necessary? Style variations can carry both settings and styles. The combination of a variation's registered data plus user edits may be sufficient for most use cases. Base themes add power (a clean alternative theme.json foundation) but also complexity.
  3. Variation sharing model: The current model has one wp_global_styles post per variation shared across all templates using it. Should there be a per-template override option, or is shared state the right default?
  4. Template style variation UI: Where shall the UI for assigning a style variation to a template live? Perhaps we could add it to the existing style browser in the Styles panel, where a user could choose whether to apply a style variation site-wide or scope it to the current template.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing exploratory PR #75330 and the related issues listed in the proposal. Trace how the wp_template and wp_global_styles data, theme.json, REST API, editor integration, and frontend rendering are handled there. The open questions about storage, sharing, base themes, and UI mean the scope and definition of done still need agreement.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, php
Domain
backend-api-design, frontend, full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.