Skip to content

Nested compositions: sibling instances share CSS scope under attribute selectors #556

@sidorovanthon

Description

@sidorovanthon

Summary

When a sub-composition is embedded twice via data-composition-src in the same parent, CSS rules using [data-composition-id="<own-id>"] from one instance match the DOM of the other instance. There is no per-instance CSS isolation.

Possibly already addressed in 0.4.34

Between 0.4.31 (where I hit this) and 0.4.34 the following commits look directly relevant:

  • c58b995 refactor: use postcss for composition CSS scoping
  • c32db3e fix: isolate studio sub-composition previews
  • fix: flatten inlined composition roots
  • fix: preserve inferred composition ids when inlining

Empirical signals from a synthetic compare:

  • compositions/flowchart.html after hyperframes add is byte-identical between 0.4.31 and 0.4.34 — so any scoping must run later than add time.
  • hyperframe.runtime.iife.js grew from ~96 KB / 17 minified lines to ~157 KB / 182 lines, with scope/postcss references jumping 2 → 10. Substantial work concentrated in the area in question.
  • A two-instance flowchart repro renders cleanly visually under 0.4.34, but my test fixture was missing window.__timelines registration so I couldn't conclusively confirm fix-or-no-fix.

If a maintainer can confirm whether c58b995 is intended to address per-instance CSS scoping for nested compositions (i.e., this issue), the issue can be closed. Happy to file a tighter repro fixture if useful.

Repro (on 0.4.31)

Parent composition embeds the same block twice:

<div data-composition-src="./flowchart.html" data-composition-id="flowchart" ...></div>
<div data-composition-src="./flowchart.html" data-composition-id="flowchart" ...></div>

Inside flowchart.html, a CSS rule [data-composition-id="flowchart"] .node { ... } matches BOTH instances during render, causing visual collisions and unexpected animation re-targeting.

Why this matters

docs/skills/hyperframes/SKILL.md (lines ~148–158) prescribes [data-composition-id="my-comp"] { ... } as the canonical scoping pattern for sub-compositions. Block authors who follow that guidance still hit cross-instance leakage.

Real-world incident: see https://github.com/sidorovanthon/anticodeguy-video-editing-studio (file docs/operations/planner-pipeline-fixes/findings.md, items D15/D21) where 22 selectors in a single catalog block had to be rewritten by hand for a single episode.

Suggested fix

Per-instance CSS scoping during nested-composition resolution: each embedded instance's data-composition-id="X" could become a unique runtime suffix (e.g., data-composition-id="X-instance-3"), with the block's own selectors rewritten to match. Authors keep writing [data-composition-id="my-comp"]; HF guarantees isolation.

Workaround

Block authors can use #<id> selectors instead of attribute selectors. This is narrower than the documented pattern but does isolate to a single instance because id is unique per DOM (HF presumably places only one element with the specified id per instance).

Affected catalog blocks (in our usage)

  • flowchart (1920x1080) — confirmed leakage in production
  • yt-lower-third — not yet confirmed, candidate for the same audit

Related


Generated by Claude Code (Opus 4.7).

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