Karaoke Text
Lyric lines colored character by character along a timeline, with the current line scaled up in focus.
Multiple lyric lines play along a timeline: the current line scales up in focus, a gradient sweeps its characters from left to right, sung lines fade out and drift up, and the whole sheet scrolls automatically to keep the current line centered. Play, pause, and restart controls are built in, and playing can also be fully controlled — well suited to music product pages, lyric showcases, and rhythmic taglines.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add karaoke-text.enPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<KaraokeText/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
Installation
npx webberui@latest add https://webberui.com/r/karaoke-text.en.jsonOr, once registries are configured in components.json, install it as @webberui/karaoke-text.
Usage
import { KaraokeText } from "@/components/ui/karaoke-text";
<KaraokeText
lines={[
{ text: "The first line of the lyrics", duration: 2400 },
{ text: "The second line of the lyrics", duration: 2600 },
{ text: "The third line of the lyrics" },
]}
height={220}
className="text-xl font-semibold"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
lines | KaraokeLine[] | — | Array of lyric lines, where KaraokeLine is { text: string; duration?: number } (milliseconds) |
playing | boolean | — | Controlled playback state; when omitted, the component manages it internally |
onPlayingChange | (playing: boolean) => void | — | callback for playback state changes (fired on control clicks and when playback ends) |
autoPlay | boolean | true | Whether playback starts automatically in uncontrolled mode |
loop | boolean | true | Whether to loop back to the start after the last line |
showControls | boolean | true | Whether to show the built-in play / pause / restart control bar |
height | number | 240 | Height of the lyric viewport (px); the current line auto-scrolls to the center |
defaultDuration | number | 2400 | Default duration for lines with no duration (milliseconds) |
activeScale | number | 1.12 | Scale factor of the current line |
baseClassName | string | greyscale text color | Class for the color of text not yet sung |
fillClassName | string | amber → rose → fuchsia gradient | Class for the gradient fill of sung text (colored via bg-clip-text) |
onLineChange | (index: number) => void | — | callback fired when the current line index changes |
className | string | — | forwarded to the outermost container; font size and weight are inherited by the lyric lines |
Accessibility
- When the user has "reduce motion" enabled at the system level, there is no per-character sweep, scaling, or blur — the current line is simply highlighted with the full fill, and lines still advance along the timeline
- The underlying lyrics are real text that the screen reader can announce; the gradient fill layer is a decorative copy marked
aria-hidden - The play, pause, and restart buttons all carry an
aria-label, and the current line number is shown (for example03 / 06) as a visual confirmation - rAF pauses automatically when the tab goes to the background, and resumes with a clamped time delta on return, so it never jumps lines
Blur Reveal Text
A whole passage comes into focus line by line from a heavy blur on entering the viewport — made for narrative paragraphs.
Logo Reveal Set
Five common logo entrances (bloom, stroke-then-fill, shine sweep, lockup slide-out and wordmark morph) triggered on mount, on entering the viewport or manually.