Split Text

Motion

Staggered Tailwind split text and Tailwind CSS text reveal components spanning letter-by-letter entrance animations.

Orchestrate the perfect typographic entrance with Tailwind split text animations. By breaking sentences down into individual characters, this Tailwind CSS text reveal component creates sophisticated, staggered entrances (like fade up or scale) that make your copywriting feel incredibly premium.

Split text pairs beautifully with Fade In wrappers, allowing you to sequence the entrance of a Hero headline just before the surrounding content.

Implementation

"use client";

import React, { useRef } from "react";
import { motion, useInView, Variants } from "framer-motion";

const presets = {
  fadeUp: { hidden: { opacity: 0, y: 12, filter: "blur(4px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)" } },
  fadeIn: { hidden: { opacity: 0 }, visible: { opacity: 1 } },
  scale: { hidden: { opacity: 0, scale: 0.5 }, visible: { opacity: 1, scale: 1 } },
  slideDown: { hidden: { opacity: 0, y: -20 }, visible: { opacity: 1, y: 0 } },
};

export const SplitText = ({ text, animation = "fadeUp", delay = 0, staggerDelay = 0.03 }) => {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-60px" });

  return (
    <motion.span ref={ref}
      variants={{ hidden: {}, visible: { transition: { staggerChildren: staggerDelay, delayChildren: delay } } }}
      initial="hidden" animate={isInView ? "visible" : "hidden"}>
      {text.split("").map((char, i) => (
        <motion.span key={`${char}-${i}`}
          variants={{ hidden: presets[animation].hidden, visible: { ...presets[animation].visible, transition: { duration: 0.35 } } }}
          className="inline-block" style={{ whiteSpace: char === " " ? "pre" : "normal" }}>
          {char}
        </motion.span>
      ))}
    </motion.span>
  );
};

Usage

Default (Fade Up)

Letter by letter.
<SplitText text="Letter by letter." />

Animation Variants

Fade Up

Every detail matters

Scale

Subtle and refined

Slide Down

Crafted with care
<SplitText text="Every detail matters" animation="fadeUp" />
<SplitText text="Subtle and refined" animation="scale" delay={0.4} />
<SplitText text="Crafted with care" animation="slideDown" delay={0.8} />

Props

PropTypeDefaultDescription
textstringText to split and animate
animation"fadeUp" | "fadeIn" | "scale" | "slideDown""fadeUp"Animation preset
delaynumber0Initial delay (seconds)
staggerDelaynumber0.03Delay between each letter
classNamestring""Additional CSS classes