Text & Numbers
Fade Through
Phrase cycling where the old line leaves before the new one arrives.
A crossfade and a fade-through look similar in a still, and very different in motion. In a crossfade both strings are on screen at once for a few hundred milliseconds, which at headline size looks like two lines fighting for the same space. A fade-through closes that gap: the outgoing phrase finishes leaving, then the incoming one starts.
The cost is time. One swap takes roughly 0.68s end to end, so the interval has
to be long enough to leave the phrase readable in between.
Usage
One line at a time.
<template>
<div class="flex w-full items-center justify-center py-12">
<MFadeThrough
class="text-center text-3xl font-semibold text-highlighted"
:phrases="phrases"
/>
</div>
</template>
<script setup lang="ts">
/**
* A fade-through is deliberately quieter than a slide: the old copy leaves
* before the new one arrives, so the line never looks like two strings at once.
*/
const phrases = [
'One line at a time.',
'No overlap, no jitter.',
'Quiet by default.',
]
</script>
Customize
One line at a time.
Customize
Interval (ms)2500
Phrases3
Props
| Prop | Type | Default | Description |
|---|---|---|---|
phrasesrequired | string[] | - | The phrases to cycle through. One phrase disables the timer. |
interval | number | 2500 | Milliseconds each phrase stays fully visible. Clamped to a 300ms minimum so
the exit can finish before the next swap is queued. |
class | string | - | Extra classes for the root element, which is the aria-live region. |
Accessibility
- The root is
aria-live="polite"witharia-atomic="true"; the new phrase is announced once, in full. - Reduced motion stops the rotation entirely rather than making it instant. An instant swap would still re-announce the line on a timer with no visual cue that anything changed.
- Use it on decorative or marketing copy. A phrase the reader must act on should not change under them.
Performance
AnimatePresence mode="wait"keeps one phrase in the tree at a time.- The enter animates
opacity,transformand a smallfilter; the exit uses opacity and a few pixels of travel only, so leaving is cheaper than arriving. - A single interval, cleared on unmount and restarted when the phrase count or interval changes. No scroll listeners.