fix(core): scope sub-composition html/body styles to the composition box (#2089)

Sub-composition <head> styles targeting html/body/:root (width/height/
overflow/background) were injected into the parent document unscoped by both
the Studio runtime mount (compositionLoader) and the render-time inliner
(inlineSubCompositions/htmlBundler). scopeCssToComposition deliberately passed
html/body/:root through unchanged, so a sub-composition smaller than the root
clobbered the host <body> dimensions and its overflow:hidden clipped the
composite to the last sub-comp's size. Only the top-left element painted;
everything else (and framework-owned video positioned outside that box) was
clipped away.

Add a scopeRootSelectors option to scopeCssToComposition that remaps
html/body/:root to the composition's own box, and enable it everywhere
sub-composition styles are scoped. The universal selector stays untouched.
Top-level composition scoping is unchanged (it legitimately owns the document).

Covered by new compositionScoping tests.
This commit is contained in:
Miguel Ángel
2026-07-08 22:21:47 -04:00
committed by GitHub
parent 57b3c78987
commit 6f0b57d608
6 changed files with 136 additions and 21 deletions
@@ -406,6 +406,11 @@ async function mountCompositionContent(params: {
authoredScopeCompositionId,
runtimeScopeSelector,
authoredRootId,
// Sub-comp styles are injected into the PARENT preview document, so
// remap html/body/:root to the composition box — otherwise a sub-comp
// `body { width/height/overflow }` clobbers the host body and clips
// the preview to the last-mounted sub-comp's size.
{ scopeRootSelectors: true },
);
}
document.head.appendChild(clonedStyle);