motion-swap

Splits text into individual characters and swaps them vertically on hover or scroll reveal. Each character has an original and duplicate that trade places with a spring animation.

Preview

Hover me

Import

import 'motion-components/motion-swap'   // just this one
import 'motion-components'               // or the whole library

Usage

<motion-swap>Hover me</motion-swap>

Loop

Add loop to swap the word in, hold, swap it back out and swap in again. hold sets how long the swapped word stays, gap how long it stays swapped back.

swap me

<motion-swap trigger="view" loop hold="1.4" gap="0.5">swap me</motion-swap>

The cycle runs only while the text is on screen, and once is ignored. Add pause-on-hover to freeze it while the pointer is over the text.

Properties

Attribute Property Type Default Description
trigger trigger string 'hover' Animation trigger: 'hover' swaps in and out on mouseenter and mouseleave. 'view' plays on viewport entry
reverse reverse boolean true Letters swap bottom-to-top. Set reverse="false" to swap top-to-bottom.
interval interval number 0.03 Delay in seconds between each character's animation start
duration duration number 0.7 Spring duration of each character swap, in seconds
bounce bounce number 0.3 Spring bounciness: 0 settles without overshoot, higher is more elastic
once once boolean true Animate only on first intersection (trigger="view"). Set once="false" to animate on every entry. Ignored with loop
delay delay number 0 Delay in seconds before animation starts
loop loop boolean false Swap in, hold, swap out and swap in again on repeat. With trigger="view" the cycle runs while the text is on screen
hold hold number 1.6 With loop, seconds the swapped word stays before it swaps back
gap gap number 0.5 With loop, seconds the word stays swapped back before it swaps in again
pause-on-hover pauseOnHover boolean false Pause the loop while the pointer is over the text, resuming on leave

JavaScript API

Control the swap view mode programmatically with play() and cancel().

JavaScript API
–

Accessibility

Respects prefers-reduced-motion: when enabled, the swap effect is skipped, the text appears at its default state and loop never starts.