Skip to main content
Version: Next

AnimatedText

ui-animated-text is the framework-agnostic animated text primitive from @editora/ui-core. It is built for text-only motion: hero headlines, onboarding copy, status callouts, release announcements, and narrative dashboard moments where motion should stay readable and accessible.

Best For

  • Hero headlines and campaign messaging
  • Guided onboarding copy and step transitions
  • Status callouts and operational summaries
  • Narrative product surfaces that need motion without sacrificing legibility

Import

import '@editora/ui-core';

Basic Usage

<ui-animated-text effect="fade-up" split="words" variant="gradient" size="lg">
Editorial automation that feels alive
</ui-animated-text>

Choosing an Effect

  • Use fade-up, fade-down, slide-left, and slide-right for calmer interface motion.
  • Use blur, blur-up, zoom-in, and rotate-in for premium hero or announcement surfaces.
  • Use pop, wave, flip-up, skew-in, and glow for more expressive or branded motion systems.
  • Use typewriter when you want a deliberate authored reveal.

Attribute-Based Text Source

Use the text attribute when you want a declarative text source without slotted content.

<ui-animated-text
text="Bring motion to system headlines without sacrificing readability."
effect="blur"
split="words"
variant="soft"
tone="info"
size="md"
padding="10 14"
></ui-animated-text>

Trigger Modes

<ui-animated-text
effect="wave"
split="words"
trigger="visible"
variant="minimal"
tone="success"
>
This text animates when it enters the viewport.
</ui-animated-text>

Manual Playback

<ui-animated-text
id="headline"
trigger="manual"
effect="typewriter"
variant="contrast"
tone="info"
size="xl"
padding="14 18"
>
Command the rollout, then let the copy animate on cue.
</ui-animated-text>

<script type="module">
const headline = document.getElementById('headline');
headline?.play();
// headline?.pause();
// headline?.replay();
// headline?.refresh();
</script>

Built-in Effects

ui-animated-text currently ships with 14 built-in effects:

fade-up, fade-down, slide-left, slide-right, blur, blur-up, pop, wave, zoom-in, rotate-in, flip-up, skew-in, glow, typewriter

Custom Effects

Define a global keyframe and pass its name through effect, or use custom-effect explicitly.

Use direct effect="your-keyframe-name" when you want the shortest markup. Use effect="custom" with custom-effect when you want an explicit contract in shared examples or design-system code.

<style>
@keyframes brand-ribbon {
from {
opacity: 0;
transform: translateY(0.4em) rotate(-8deg) scale(0.92);
filter: blur(8px);
}
to {
opacity: 1;
transform: translateY(0) rotate(0deg) scale(1);
filter: blur(0);
}
}
</style>

<ui-animated-text
effect="brand-ribbon"
effect-timing="cubic-bezier(0.16, 1, 0.3, 1)"
>
Custom keyframes with built-in text segmentation.
</ui-animated-text>

Or:

<ui-animated-text
effect="custom"
custom-effect="brand-ribbon"
effect-direction="alternate"
effect-iteration-count="infinite"
effect-fill-mode="both"
>
Explicit custom motion recipe
</ui-animated-text>

Custom Effect Guidelines

  • Define custom keyframes in global or page-level CSS so the animation name exists before the element renders.
  • Prefer animating transform, opacity, filter, or letter-spacing instead of layout-changing properties.
  • Remember that the animated unit is each generated segment. Word splitting animates words, character splitting animates characters.
  • Use effect-timing, effect-direction, effect-iteration-count, and effect-fill-mode to tune playback without cloning keyframes unnecessarily.
  • Always test with reduced motion enabled so the static fallback remains readable and useful.

Attributes

AttributeTypeDefaultDescription
textstringExplicit text source. If omitted, the component uses slotted text content
effectbuilt-in effect name or custom keyframe namefade-upReveal animation style
splitchars | words | lineswordsSegmentation strategy. typewriter forces chars
triggerload | visible | manualloadWhen playback begins
durationCSS time or number720msSegment animation duration
staggerCSS time or number55msDelay between segments
delayCSS time or number0msInitial sequence delay
loopbooleanfalseReplays the animation continuously
loop-delayCSS time or number1400msDelay between loops
pausedbooleanfalsePauses playback
custom-effectstringExplicit keyframe name used when effect="custom"
effect-timingstringOverrides animation timing function
effect-directionnormal | reverse | alternate | alternate-reverseOverrides animation direction
effect-iteration-countnumber, string, or infiniteOverrides iteration count
effect-fill-modenone | forwards | backwards | bothOverrides fill mode
variantdefault | soft | solid | contrast | gradient | minimaldefaultVisual treatment
tonebrand | neutral | info | success | warning | dangerbrandAccent tone
sizesm | md | lg | xl | 1 | 2 | 3 | 4mdTypography scale
radiusCSS length or semantic tokenSurface radius override
elevationnone | low | highlowSurface shadow depth
paddingCSS lengthSurface padding override
alignstart | center | end | left | rightstartText alignment

Methods

const animatedText = document.querySelector('ui-animated-text');
animatedText?.play();
animatedText?.pause();
animatedText?.replay();
animatedText?.refresh();

Notes

  • ui-animated-text is intentionally text-first. It does not preserve nested HTML structure in the animated output.
  • The host keeps semantic text available via role="text" and aria-label.
  • Reduced-motion environments automatically disable motion while preserving readable static text.
  • trigger="manual" preserves layout while hiding the text until playback starts.
  • Custom effects still benefit from built-in text splitting, staggering, playback controls, and reduced-motion handling.
  • The component includes internal safe-area handling for tighter containers so descenders and right-edge glyphs remain visible during animation.