Setting the file. One moment.
Subchapter 21.5
references/full-screen-motion.mdMarkdown3 KBView on GitHub
For full-frame motion (continuous backgrounds, color washes, full-bleed visual states that span multiple clips), prefer a shared background layer + transparent timed content layers over stacked opaque scene backgrounds.
<style>
/* The runtime auto-positions root children that carry data-start. The shared
background deliberately has none, so it gets NO automatic layout and must
size itself, or #bg is 0px tall and the tween paints nothing. */
#bg.full-bleed {
position: absolute;
inset: 0;
}
.clip.transparent {
background: transparent;
}
</style>
<div id="root" data-composition-id="main" data-width="1920" data-height="1080" data-duration="20">
<!-- Shared background — NOT a clip. Always visible. Driven by the timeline. -->
<div id="bg" class="full-bleed"></div>
<!-- Timed content layers — transparent backgrounds. -->
<section
id="scene1"
class="clip transparent"
data-start="0"
data-duration="6"
data-track-index="1"
>
<!-- content -->
</section>
<section
id="scene2"
class="clip transparent"
data-start="6"
data-duration="14"
data-track-index="1"
>
<!-- content -->
</section>
</div>
<script>
const tl = gsap.timeline({ paused: true });
// Drive the shared background from the seekable timeline.
tl.to("#bg", { backgroundColor: "#0a1530", duration: 6, ease: "sine.inOut" }, 0);
tl.to("#bg", { backgroundColor: "#1a0a30", duration: 14, ease: "sine.inOut" }, 6);
// Scene-local animations stay transparent on top.
tl.from("#scene1 h1", { y: 48, opacity: 0, duration: 0.6 }, 0.2);
window.__timelines["main"] = tl;
</script>data-start / data-duration. It exists for the whole composition.data-start. An untimed background must set its own position: absolute; inset: 0, or it collapses to zero height and nothing you animate on it is visible. This is the most common way this pattern is copied wrong.#bg shows through..clip elements. HyperFrames already shows/hides clips based on data-start and data-duration. Animating display / visibility on the clip itself races with the framework’s own show/hide. Animate a child wrapper inside the clip instead.data-layout-allow-overflow to silence an inspect warning, run npx hyperframes snapshot and confirm the overflow is what you want.