Skip to content

fix(dom): stop pseudoClassEnabledElements from freezing layout + settle transitions (PER-9836)#2331

Open
Sriram567 wants to merge 1 commit into
masterfrom
fix/per-9836-pseudoclass-layout-baking
Open

fix(dom): stop pseudoClassEnabledElements from freezing layout + settle transitions (PER-9836)#2331
Sriram567 wants to merge 1 commit into
masterfrom
fix/per-9836-pseudoclass-layout-baking

Conversation

@Sriram567

Copy link
Copy Markdown
Contributor

What & why (PER-9836)

pseudoClassEnabledElements bakes an opted-in element's computed style as an inline !important block so a forced :hover/:active appearance survives serialization. Baking the full computed style — captured once at the SDK viewport, at serialize time — caused two customer-reported regressions:

  1. Layout frozen across widths. Sizing/box-model props (width, height, padding, margin, inset, flex, grid, display, …) were baked !important, freezing the SDK-viewport geometry and overriding the page's responsive rules at every other Percy render width. A CTA anchor baked width: 134px !important (its 1280 content-width) rendered content-width at Percy's 375px width instead of the site's mobile full-width.
  2. Mid-transition colour. The SDK forces :hover then serializes immediately, so getComputedStyle read a half-faded colour (the rest→hover transition frame) and baked it — the button showed a wrong hover colour.

Fix

  • NON_BAKED_STYLE_PROPS — exclude layout/box-model/positioning/flex/grid + transition* props from the baked block. Only the paint delta of the forced state is baked; layout stays governed by the page's own (separately serialized) stylesheets, which re-evaluate media queries per render width.
  • computedStyleTextSettled — disable the element's transition before reading getComputedStyle and restore it in a finally, so the baked value is the settled forced-state colour, not a mid-transition frame. The live page (SDK mode) is left untouched.

Scope is limited to the pseudoClassEnabledElements bake path — no other behavior changes.

Verification

  • @percy/dom suite green (added 2 regression tests: excluded-property set; transition disable-during-read/restore-after).
  • Real-browser capture check on a page mirroring the reported mechanism: baked block no longer contains width/height/padding/display; background-color is now the settled hover colour.
  • Capture→render (375) before/after: button 98px → 343px (partial → full-width).

Fixes PER-9836.

🤖 Generated with Claude Code

…le transitions (PER-9836)

serializePseudoClasses bakes an opted-in element's computed style as an
inline `!important` block so the forced :hover/:active appearance survives
serialization. Two problems fell out of baking the FULL computed style,
captured once at the SDK viewport at serialize time:

1. Layout/box-model props (width/height/padding/margin/inset/flex/grid/
   display/…) were baked `!important`, freezing the SDK-viewport geometry
   and overriding the page's responsive rules at every OTHER Percy render
   width. PER-9836: a CTA anchor baked `width: 134px !important` rendered
   content-width at Percy's 375px width instead of the site's mobile
   full-width. Fix: NON_BAKED_STYLE_PROPS excludes sizing/spacing/
   positioning/flex/grid/transition props from the bake; layout stays
   governed by the page's own (separately serialized) stylesheets.

2. The bake read getComputedStyle mid CSS-transition (the SDK forces
   :hover then serializes immediately), so a half-faded colour was frozen
   instead of the settled hover colour. Fix: computedStyleTextSettled
   disables the element's `transition` before reading computed style and
   restores it in a `finally`, so the baked value is the settled state.

Only paint/state props are baked now; responsive layout and the final
forced-state colours both render correctly. Adds regression tests for the
excluded-property set and the transition-settle/restore behaviour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Sriram567 Sriram567 requested a review from a team as a code owner July 5, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant