Skip to content

Closed accordion panels keep their layout box: cloned page renders ~69% taller than source #65

Description

@aeonbilal

Summary

A cloned page renders ~69% taller than its source because closed accordion panels keep their layout box. The interaction pass classifies only 1 accordion pattern for 12 panels, so the other 11 fall through to the motion runtime's visibility: hidden path — which hides the pixels but preserves the box.

The capture already contains the correct collapsed geometry. It just never gets applied.

Repro

git clone https://github.com/ion-design/ditto.site.git && cd ditto.site
npm ci && npx playwright install chromium
npm run clone -- https://www.wix.com/symphony --out=./output --styling=tailwind --framework=next
cd output/wix/app && npm install && npm run dev
  • ditto.site 3860a1a (2026-07-30)
  • node v22.22.3, playwright 1.56.1, macOS 24.6.0

Expected vs actual

Full-page height, same Chromium, same viewport, fonts settled, animations frozen:

viewport source generated delta
1280 13,927px 23,497px +68.7%
1440 14,810px 25,309px +70.9%

Measured at 1280, the inflation is one section, not spread across the page:

idx source generated delta
0 720 720 0
1 805 800 −5
2 645 683 +38
3 765 744 −21
4 983 982 −1
5 767 862 +95
6 5400 4800 −600
7 713 713 0
8 692 692 0
9 1,446 11,205 +9,759
10 521 825 +304

Section 9 is the FAQ: 12 rows, one open on the source. In the generated app all 12 render at their full open height (~900px each).

Root cause

Capture log from the run:

{"event":"interactions_patterns","tabs":0,"accordions":1,"carousels":0,"disclosures":0}

One accordion pattern is detected for twelve panels. The one that is detected gets a correct spec — page.tsx contains its regionHidden:

{"height":"0px","maxHeight":"0px","overflow":"hidden","opacity":"0", ...}

The other eleven arrive as reveals carrying visibility: "hidden", and src/app/ditto/DittoMotion.tsx applies exactly that:

if (rv.visibility === "hidden") {
  el.style.visibility = "hidden";
  el.style.animationName = "none";
}

visibility: hidden removes the paint but keeps the layout box, so each closed panel still occupies its full open height. The geometry needed to fix it (height/maxHeight/overflow) is already in the capture — it's only ever attached to the single detected accordion.

Suggested direction

Either would address it:

  1. Detection — make the interaction pass generalize a matched accordion across sibling rows sharing the same structure, so all N panels get a regionHidden spec rather than the first.
  2. Runtime — when a reveal spec carries visibility: "hidden" on an element that is a disclosure region, apply the captured collapsed geometry alongside visibility.

Note on patching downstream

I tried three local workarounds and all three failed, which is why I'm reporting it rather than sending a patch:

  • Collapsing by reveal-spec signature in DittoMotion — the 12 visibility:hidden anchors turn out to be the rows, not the answer panels, so this hides the question text.
  • A max-height clamp on the row ids — measures within 2.4% of source but renders broken (question text gone).
  • A targeted pass collapsing only tall children per row — same, rows collapse to nothing.

Worth flagging for anyone else measuring: page height is not a proxy for correctness here. All three attempts landed within a few percent of the source height while rendering incorrectly, because collapsing content reduces height whether or not the result is right. Screenshot diffing catches it; height diffing does not.

Two smaller things from the same run

  • 3 visual assets skipped, 2 of them videos over the size cap (contentLength 24,762,262 and 11,786,350). No <video> element or reference is emitted for them, so the section renders without its media and there's nothing downstream to re-point at a local file.
  • {"event":"screenshot_cdp_fallback","viewport":1920,"error":"Error: cdp: content 1920x18700 exceeds max shot dimension"} — the 1920 capture screenshot fails on tall pages. Possibly related, since the inflated height is what pushes it over the limit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions