remocn logoremocn

Text Fade Replace

Cross-fade between two strings on the same line without layout shift.

A typography primitive that swaps one string for another in place. Both spans are absolutely positioned in a relative container so they never push each other in the DOM during the fade.

Installation

$ pnpm dlx shadcn@latest add @remocn/text-fade-replace

Usage

// src/Root.tsx
import { Composition } from "remotion";
import { TextFadeReplace } from "@/components/remocn/text-fade-replace";

const TextFadeReplaceScene = () => (
  <TextFadeReplace from="Before" to="After" fontSize={72} />
);

export const RemotionRoot = () => (
  <Composition
    id="TextFadeReplace"
    component={TextFadeReplaceScene}
    durationInFrames={90}
    fps={30}
    width={1280}
    height={720}
  />
);

Props

PropTypeDefaultDescription
fromrequired
stringInitial text shown at the start of the composition.
torequired
stringReplacement text shown at the end of the composition.
fontSize
number48Font size in pixels.
fontWeight
number600CSS font-weight.
color
string"#171717"Text color for both strings.
className
stringOptional className passed to both spans.

Notes

Absolute positioning

Both texts are position: absolute inside a zero-size relative anchor. This guarantees there is no layout reflow during the cross-fade, even when from and to have different widths.

Long strings

If your strings are very long, make sure your composition is wide enough — neither span will wrap because they use whiteSpace: nowrap.

Variant: Strikethrough Replace

A companion primitive that animates a strikethrough line growing left-to-right across the from text, then cross-fades to the to text. Useful for "old way / new way" comparisons.

Installation

$ pnpm dlx shadcn@latest add @remocn/strikethrough-replace

Usage

import { StrikethroughReplace } from "@/components/remocn/strikethrough-replace";

<StrikethroughReplace
  from="Slow setup"
  to="Instant setup"
  lineColor="#ff5e3a"
  fontSize={72}
/>

Props

PropTypeDefaultDescription
fromrequired
stringOriginal text that gets struck through.
torequired
stringReplacement text that fades in.
lineColor
string"#ff5e3a"Color of the strikethrough bar.
fontSize
number48Font size in pixels.
fontWeight
number600CSS font-weight.
color
string"#171717"Text color for both strings.
className
stringOptional className passed to the underlying spans.
Three phases

The animation runs in three phases tied to durationInFrames: draw the strike line (0–40%), cross-fade to the new text (40–60%), then hold (60–100%).