Docs
Letter Swap Hover

Letter Swap Hover

A text component that swaps the letters vertically on hover.

Hover me chief!Hover me chief!{awesome}{awesome}Good day!Good day!More text?More text?oh, seriously?!oh, seriously?!

There are two types of animations available for this component:

  1. Forward animation — plays the animation timeline once forward, when you hover over the text.
  2. Ping Pong animation — plays the animation timeline in a ping pong fashion. It plays once forward when you hover over the text, and once in the opposite direction when you hover away from the text.

Source code


Only forward animation

Ping Pong animation

Install the following dependencies:

lodash is used for debouncing here — so the animation doesn't break on rapid hover changes.

npm install lodash

lodash is used for debouncing here — so the animation doesn't break on rapid hover changes.

Copy and paste the following code into your project:

Understanding the component


  1. First, we duplicate the text we want to animate. We'll have two identical copies of the text.

  2. We create a container <span> element with these key properties:

    • position: relative - This establishes a positioning context
    • overflow: hidden - This ensures text outside the container boundaries is hidden
  3. For each copy of the text:

    • We split it into individual letters
    • Each letter is wrapped in its own <span> element, with absolute positioning
    • The letters from both copies are stacked vertically on top of each other (top: 0, and top: 100%)
  4. When hovering:

    • The original letters slide upward out of view (hidden by overflow), by setting top: 100%
    • The duplicate letters slide up into the original position, by setting top: 0
    • This creates a smooth swapping effect

If reverse is enabled, the animation direction is flipped.

Examples


Stagger

With the staggerFrom prop, you can control the index of the letter where the stagger animation starts.

FirstFirstCenterCenterLastLast

Line swap

By setting the staggerDelay prop to zero, you can create a line swap effect.

oh, wow!oh, wow!nice!nice!

Props


PropTypeDefaultDescription
label*string-The text to be displayed and animated
reversebooleantrueDirection of the animation (true: bottom to top, false: top to bottom)
transitionDynamicAnimationOptions{ type: "spring", duration: 0.7 }Animation configuration for each letter. Refer to framer-motion docs for more details
staggerDurationnumber0.03Delay between each letter's animation start
staggerFrom"first" | "last" | "center" | number"first"Starting point of the stagger effect
classNamestring-Additional CSS classes for styling
onClick() => void-Callback function for click events