Transition
A div wrapper that drives CSS @keyframes animations via data-transition and data-mounted attributes. The initial state renders correctly in SSR — no JavaScript required for the entry animation. Toggle mounted from client-side state to play the exit animation.
Available transitions
All of these boxes are mounted (mounted=true), so the entry animation has already completed. In practice you toggle mounted to animate in/out.
fade
slide-up
slide-down
slide-left
slide-right
scale
scale-y
pop
skew-up
skew-down
rotate-left
rotate-right
<Transition transition="fade" mounted>
<div>fade</div>
</Transition>
<Transition transition="slide-up" mounted>
<div>slide-up</div>
</Transition>
<Transition transition="scale" mounted>
<div>scale</div>
</Transition>
<Transition transition="pop" mounted>
<div>pop</div>
</Transition>Duration
duration=100ms
duration=400ms
duration=1000ms
<Transition transition="fade" mounted duration={100}><div>Fast</div></Transition>
<Transition transition="fade" mounted duration={400}><div>Normal</div></Transition>
<Transition transition="fade" mounted duration={1000}><div>Slow</div></Transition>Unmounted state
When mounted=false, the element is hidden (exit animation plays). Toggle it from a signal or state to animate in/out.
This content is hidden (mounted=false)
Nothing visible here — mounted=false
const [show, setShow] = createSignal(false)
<button onClick={() => setShow(!show())}>Toggle</button>
<Transition transition="scale" mounted={show()}>
<div>Animated content</div>
</Transition>Props
| Prop | Type | Default | Description |
|---|---|---|---|
transition | 'fade'|'slide-up'|'slide-down'|'slide-left'|'slide-right'|'scale'|'scale-y'|'pop'|'skew-up'|'skew-down'|'rotate-left'|'rotate-right' | 'fade' | Named CSS animation preset |
mounted | boolean | true | When true the enter animation plays; when false the exit animation plays |
duration | number | 150 | Animation duration in milliseconds |
timingFunction | string | — | CSS easing function (e.g. 'ease-in-out') |