How to add a slide down animation for the appearance of an element in a multi-page app?

1 day ago 1
ARTICLE AD BOX

The issue is that ::view-transition-new renders into a fixed-size container that's pre-allocated before the animation runs, so the full block size is reserved from frame one, even though your keyframe starts at block-size: 0.

The fix is to animate transform: translateY combined with clip-path (or overflow: clip on the pair) instead of animating block-size. This way the element occupies no visible space at the start without the browser needing to reserve room for it.

Here's the corrected approach:

css

::view-transition-image-pair(--incoming) { overflow-y: clip; } ::view-transition-new(--incoming) { animation-duration: 3s; animation-fill-mode: both; transform-origin: top center; @media (prefers-reduced-motion: no-preference) { animation-name: --slide-down-in; } } @keyframes --slide-down-in { from { transform: translateY(-100%); clip-path: inset(100% 0 0 0); } to { transform: translateY(0%); clip-path: inset(0% 0 0 0); } }

The two properties work together here:

translateY(-100%)

slides the element up so it starts above its natural position, and

clip-path: inset(100% 0 0 0)

clips it so nothing bleeds into the space above. As both animate to their

to

values simultaneously, the element appears to grow downward from zero height, which is the Svelte slide effect you're after.

The key insight is that you're not actually changing the element's size (which is what caused the pre-allocation problem), you're just revealing it progressively from top to bottom while sliding it into place.

One caveat:

animation-fill-mode: both

is important here so the from state is applied immediately at frame zero, before the transition paint starts.

Read Entire Article