Make WordPress Core

Opened 7 weeks ago

Closed 4 weeks ago

Last modified 8 days ago

#65992 closed defect (bug) (fixed)

Responsive @tablet / @mobile styles are ignored in standalone block style variation JSON partials

Reported by: imflexwala Owned by: ramonopoly
Priority: normal Milestone: 7.2
Component: Editor Version: 7.1
Severity: normal Keywords: needs-testing has-screenshots has-patch has-unit-tests gutenberg-merge
Cc: Focuses: css

Description

WordPress 7.1 introduced responsive style states using the @tablet and @mobile keys. The dev note (Responsive block styles and configurable viewports in WordPress 7.1) states that these apply to all block types and their block style variations that use core block supports such as typography, color, background, border, dimensions, spacing and layout.

That holds when the variation is declared inside theme.json under styles.blocks.<block>.variations.<slug>. It does not hold when the same variation is declared in a standalone JSON partial in the theme's styles/ directory.

In the partial case, the base styles from the variation are generated correctly, but no media-query CSS is generated for the @tablet or @mobile blocks. Those keys appear to be dropped during processing rather than producing an error, so there is no indication in the editor or on the front end that anything was ignored.

Steps to reproduce

  1. On a block theme running WordPress 7.1, create styles/article-heading-xl.json:
{
  "$schema": "https://schemas.wp.org/wp/7.1/theme.json",
  "version": 3,
  "title": "Heading XL",
  "slug": "article-heading-xl",
  "blockTypes": ["core/heading", "core/post-title"],
  "styles": {
    "typography": {
      "fontSize": "40px",
      "fontWeight": "700",
      "lineHeight": "1.3"
    },
    "@tablet": {
      "typography": { "fontSize": "28px" }
    },
    "@mobile": {
      "typography": { "fontSize": "16px", "lineHeight": "1.35" }
    }
  }
}
  1. Add a Heading block to a page and apply the "Heading XL" style variation.
  2. View the page on the front end and inspect the heading in DevTools.
  3. Resize the viewport below the tablet breakpoint, then below the mobile breakpoint.

Expected result

Three rules are generated for the variation selector: the base rule, plus rules wrapped in the tablet and mobile media queries. The heading font size steps down at each breakpoint.

Actual result

Only the base rule is generated:

:root :where(.wp-block-heading.is-style-article-heading-xl--15) {
  font-size: clamp(24.034px, 1.502rem + ((1vw - 3.2px) * 1.782), 40px);
  font-weight: 700;
  line-height: 1.3;
}

No media-query rules are output for the variation. The heading keeps the desktop font size at every viewport width. Screenshots attached show the same element at 1440px and at 440px, with an identical computed font size and no additional rules in the Styles panel.

Working comparison

Moving the identical @tablet and @mobile blocks into theme.json under styles.blocks.core/heading.variations.article-heading-xl generates the expected media-query CSS. Only the standalone partial path is affected.

Attachments

Screenshot 2026-08-28 at 4.47.37 PM.jpg - front end at 1440px, base rule generated, no responsive rules present
Screenshot 2026-08-28 at 4.49.23 PM.jpg - same page at 440px, still resolving to the desktop font size

Attachments (3)

Screenshot 2026-08-28 at 4.49.23 PM.jpg​ (567.7 KB ) - added by imflexwala 7 weeks ago.
Screenshot 2026-08-28 at 4.47.37 PM.jpg​ (543.5 KB ) - added by imflexwala 7 weeks ago.
ticket-65992-after.png​ (176.9 KB ) - added by arkaprabhachowdhury 6 weeks ago.
PR #13325 WordPress Playground regression evidence

Download all attachments as: .zip

Change History (22)

#1 @wildworks
7 weeks ago

  • Milestone Awaiting Review → 7.1.1

Thanks for the report. This issue might need to be fixed in a minor release. cc @isabel_brison @ramonopoly

#2 @imflexwala
7 weeks ago

Thank you!

This ticket was mentioned in ​PR #13325 on ​WordPress/wordpress-develop by ​@mitgiselle.


6 weeks ago
#3

  • Keywords has-patch has-unit-tests added

## Problem

Responsive @tablet and @mobile styles are silently dropped from block style
variations declared in a standalone JSON partial in a theme's styles/
directory. The base rule is generated, but no media query CSS is emitted, and
nothing surfaces an error in the editor or on the front end.

The same variation declared inline in theme.json under
styles.blocks.<block>.variations.<slug> works correctly. Only the standalone
partial path is affected.

## Cause

Partials declare their styles at the root of the styles object:

{
  "slug": "article-heading-xl",
  "blockTypes": [ "core/heading" ],
  "styles": {
    "typography": { "fontSize": "40px" },
    "@tablet": { "typography": { "fontSize": "28px" } }
  }
}

WP_Theme_JSON_Resolver::get_style_variations() sanitizes each partial by
running it through WP_Theme_JSON, so the partial is validated against the
top-level styles schema in WP_Theme_JSON::sanitize().

That schema was deliberately built to mirror the block style variation schema —
both are VALID_STYLES plus blocks and elements — which is what makes
partials sanitize correctly in the first place. The responsive breakpoint states
added in 7.1 were only added to the block, element, and variation branches, so
@tablet and @mobile at the top level are removed by
remove_keys_not_in_schema() as unknown keys.

The variation branch cannot cover this case: it validates
styles.blocks.<block>.variations.<slug>, a different location in the tree, and
its guard also requires the variation to already be present in
$valid_variations, which is derived from the block styles registry. Partials
are not registered until wp_register_block_style_variations_from_theme_json_partials()
runs, which happens *after* get_style_variations() returns.

The later, fully-correct sanitize pass in get_theme_data() cannot recover the
data either, because inject_variations_from_block_style_variation_files()
copies the already-stripped styles.

## Fix

Add the responsive breakpoint states to the top-level styles schema, mirroring
what the block style variation branch already does. This restores the parity the
two schemas were written to have.

## Testing instructions

  1. On a block theme, create styles/article-heading-xl.json:
{
	"version": 3,
	"title": "Heading XL",
	"slug": "article-heading-xl",
	"blockTypes": [ "core/heading" ],
	"styles": {
		"typography": { "fontSize": "40px", "fontWeight": "700", "lineHeight": "1.3" },
		"@tablet": { "typography": { "fontSize": "28px" } },
		"@mobile": { "typography": { "fontSize": "16px", "lineHeight": "1.35" } }
	}
}
  1. Add a Heading block to a page and apply the "Heading XL" style variation.
  2. View the page on the front end and inspect the heading.

Before: only the base rule is generated; the heading keeps its desktop font
size at every viewport width.

After: the base rule plus tablet and mobile media query rules are generated,
and the font size steps down at each breakpoint.

## Automated tests

  • test_block_style_variation_partial_retains_responsive_styles — asserts the breakpoint keys survive WP_Theme_JSON_Resolver::get_style_variations().
  • test_block_style_variation_partial_responsive_styles_generate_css — asserts the expected media queries appear in the generated CSS.

Both fail before the change and pass after. An existing expectation in
test_get_style_variations is updated to account for the new test fixture.

## AI assistance

  • AI assistance: Yes
  • Tool(s): Claude Code (Claude Opus 5)
  • Used for: Root cause analysis, drafting the fix, and the two regression tests.

The tests were written first and confirmed failing against unpatched trunk, then
confirmed passing after the change. The full PHPUnit suite was run locally
(31,037 tests, no regressions). All output was reviewed by me before submission.

#4 @mitgiselle
6 weeks ago

The Gutenberg plugin has the identical gap. Since WP_Theme_JSON_Gutenberg overrides core's class when the plugin is active, a core-only fix leaves Gutenberg users affected.

Happy to open a companion PR in Gutenberg — let me know if you'd like that now so the two can be reviewed together, or once the approach here is agreed.

This is my first core contribution, so please point out anything that doesn't match conventions.

@arkaprabhachowdhury
6 weeks ago

PR #13325 WordPress Playground regression evidence

#5 @arkaprabhachowdhury
6 weeks ago

Test Report

Description

This report validates that PR #13325 addresses Trac #65992.

Patch tested: ​PR #13325 at cf098c6be1bfb5eebec3657959ddbc28bcfeb9e

Environment

  • WordPress: 7.2-alpha-20260831.00481
  • PHP: 7.4 (Playground blueprint)
  • Server: PHP.wasm
  • Browser: Relay Browser
  • OS: Windows
  • Theme: Responsive Test (temporary block theme)
  • MU Plugins: None activated
  • Plugins: None activated

Steps to Test

  1. Opened the PR-specific Playground: ​https://playground.wordpress.net/wordpress.html?pr=13325
  2. Created and activated a temporary block theme with styles/responsive-variation.json, containing base, @tablet, and @mobile typography settings.
  3. Cleared the theme JSON resolver cache and called WP_Theme_JSON_Resolver::get_style_variations( 'block' ).
  4. Rendered the matching block style variation and inspected the generated CSS.

Expected Results

  • The standalone variation remains available to the resolver.
  • The @tablet and @mobile typography values survive sanitization.
  • Generated CSS contains both responsive media-query rules.

Actual Results

  • variation-found: yes
  • tablet-value: 28px
  • mobile-value: 16px
  • tablet-media: present
  • mobile-media: present
  • Generated CSS included @media (width <= 480px) with font-size: 16px and @media (480px < width <= 782px) with font-size: 28px.

The patch passes this test.

Supplemental Artifacts

  • After patch: attached ticket-65992-after.png

This ticket was mentioned in ​Slack in #core by adrianduffell. ​View the logs.


6 weeks ago

#7 @adrianduffell
5 weeks ago

  • Keywords close added

This will be included in 7.1.1, but suggesting to close as it will be handled on the Gutenberg-side:

Issue: ​https://github.com/WordPress/gutenberg/issues/82392
PR: ​https://github.com/WordPress/gutenberg/pull/82403

#8 @wildworks
5 weeks ago

  • Keywords gutenberg-merge added; close removed

The Gutenberg PR alone is not enough. The PHP changes need to be backported from Gutenberg to Core. Once ​https://github.com/WordPress/wordpress-develop/pull/13325 is committed and backported to the 7.1 branch, we can finally close this ticket.

This ticket was mentioned in ​Slack in #core by adamsilverstein. ​View the logs.


5 weeks ago

​@adamsilverstein commented on ​PR #13325:


5 weeks ago
#10

Hello @guzel is this PR ready for review? I see the upstream PR has not been merged.

Please note the RC for 7.1.1 is September 10th if we want it included in that version.

​@mitgiselle commented on ​PR #13325:


5 weeks ago
#11

Thanks @adamsilverstein, yes, it's ready for review.
I've just pushed an update so this matches the current state of
​WordPress/gutenberg#82403

That includes the review feedback from @talldan there: the states are now gated on the blockTypes property, so only block style variation partials are affected and regular theme.json files are unchanged. Pseudo-selectors in partials are supported alongside the responsive states, since they were dropped by the same root cause.

The Gutenberg PR is green and waiting on final sign-off. If anything changes there I'll mirror it here.

​@adamsilverstein commented on ​PR #13325:


5 weeks ago
#12

Thanks @guzel! I have requested some reviewers in GitHub.

This ticket was mentioned in ​Slack in #core by adrianduffell. ​View the logs.


5 weeks ago

#14 @adamsilverstein
5 weeks ago

  • Milestone 7.1.1 → 7.1.2

7.1.1 RC is in a couple of hours - punting this to 7.1.2 for continued work.

​@ramonopoly commented on ​PR #13325:


5 weeks ago
#15

@adamsilverstein PR approved if there's still time for 7.1.1 RC 1

#16 @ramonopoly
4 weeks ago

  • Owner set to ramonopoly
  • Resolution → fixed
  • Status new → closed

In 63610:

Editor: Retain responsive styles in block style variation partials

Responsive @tablet and @mobile styles were silently dropped from block style variations declared in a standalone JSON partial in a theme's styles/ directory.

This commit adds the responsive breakpoint states to the top-level styles schema, mirroring what the block style variation branch already does. This restores the parity to the two schemas.

Developed in: ​https://github.com/WordPress/wordpress-develop/pull/13325

Props adamsilverstein, andraganescu, andrewserong, firdaus666, mitgiselle, pbiron, ramonopoly, talldanwp.

Fixes #65992.

#17 @johnbillion
3 weeks ago

  • Milestone 7.1.2 → 7.1.3

#18 @jorbin
8 days ago

  • Milestone 7.1.3 → 7.2

@ramonopoly Did you intend to reopen this for backport? If so, please do so and put it in the minor release. I've moved it to the next major since it wasn't reopened two weeks after commit.

#19 @ramonopoly
8 days ago

Did you intend to reopen this for backport? If so, please do so and put it in the minor release. I've moved it to the next major since it wasn't reopened two weeks after commit.

Thanks for the ping @jorbin

Looks like it was suggested above to backport, but 7.2 is fine I think since it's been idle.

Cheers!

Note: See TracTickets for help on using tickets.