Text Reveal <mv-text-reveal>

按字母、单词或行拆分的文字显现效果,有 6 种交错预设(淡入、模糊、滑入、3D 旋转、缩放、遮罩),进入视口时触发;保留内联标记。

分类动画文字
类型Web Component(<mv-text-reveal>)
状态稳定版
Keywordssplit-text, blur-fade, stagger, reveal, headline, hero, text-animate, mask

When to use

  • A hero headline should animate in by letters, words or lines when it enters the viewport
  • An entrance preset (fade, blur, slide, 3D rotate, zoom, mask) must keep inline markup like em or strong
  • A heading should replay its reveal on hover or from script

Avoid when

  • The reveal should be driven by scroll progress rather than a one-shot entrance → use Scroll Text instead
  • Whole cards or sections should fade in, not split text → use Scroll Reveal instead
  • Long body copy; splitting paragraphs into staggered pieces delays reading

安装

node scripts/add.mjs text-reveal --out ./src/marvelous

使用 Marvelous UI MCP 服务器的 AI 智能体:install_components({ slugs: ["text-reveal"], target_dir: "<absolute path>/src/marvelous", framework: "react" })。

复制的文件(含依赖):tokens/tokens.css、core/base.css、core/dom.js、core/element.js、core/motion.js、core/observe.js、components/text-reveal/text-reveal.js、components/text-reveal/text-reveal.css。

用法

标准标记,可在此基础上通过属性、data-* 和 CSS 变量进行定制:

<div id="tr-demo" style="display:grid;gap:2rem;width:min(100%,46rem);margin-inline:auto">
  <div style="text-align:center">
    <p style="margin:0 0 .5rem;font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;color:var(--mv-fg-muted)">
      <mv-text-reveal effect="blur" by="chars" delay="100">Launch · Spring 2026</mv-text-reveal>
    </p>
    <h2 style="margin:0;font:700 clamp(2rem,5vw,3.4rem)/1.05 var(--mv-font-display);letter-spacing:-.035em">
      <mv-text-reveal effect="mask" by="words">Interfaces that make people <em style="font-style:normal;color:var(--mv-accent)">want</em> to click.</mv-text-reveal>
    </h2>
    <p style="margin:.9rem auto 0;max-width:32rem;color:var(--mv-fg-muted);line-height:1.55">
      <mv-text-reveal effect="fade-up" by="lines" delay="450">Native components, polished animations, accessible by default. Copy, paste, ship. In any framework.</mv-text-reveal>
    </p>
  </div>

  <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(13rem,100%),1fr));gap:.75rem">
    <div style="padding:1rem 1.1rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-surface)">
      <small style="color:var(--mv-fg-subtle);font-family:var(--mv-font-mono)">effect="blur"</small>
      <p style="margin:.35rem 0 0;font-size:1.3rem;font-weight:600;letter-spacing:-.02em"><mv-text-reveal effect="blur">Sharp from the very first second.</mv-text-reveal></p>
    </div>
    <div style="padding:1rem 1.1rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-surface)">
      <small style="color:var(--mv-fg-subtle);font-family:var(--mv-font-mono)">effect="rotate" by="chars"</small>
      <p style="margin:.35rem 0 0;font-size:1.3rem;font-weight:600;letter-spacing:-.02em"><mv-text-reveal effect="rotate" by="chars">Every letter counts.</mv-text-reveal></p>
    </div>
    <div style="padding:1rem 1.1rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-surface)">
      <small style="color:var(--mv-fg-subtle);font-family:var(--mv-font-mono)">effect="scale"</small>
      <p style="margin:.35rem 0 0;font-size:1.3rem;font-weight:600;letter-spacing:-.02em"><mv-text-reveal effect="scale" easing="var(--mv-ease-spring)" duration="900">Small detail, big impact.</mv-text-reveal></p>
    </div>
    <div style="padding:1rem 1.1rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-surface)">
      <small style="color:var(--mv-fg-subtle);font-family:var(--mv-font-mono)">effect="slide" by="chars"</small>
      <p style="margin:.35rem 0 0;font-size:1.3rem;font-weight:600;letter-spacing:-.02em"><mv-text-reveal effect="slide" by="chars">Always one step ahead.</mv-text-reveal></p>
    </div>
  </div>

  <div style="display:flex;justify-content:center">
    <button class="mv-button" data-variant="outline" data-size="sm" id="tr-demo-replay">Replay</button>
  </div>
</div>
<script type="module">
  const root = document.getElementById("tr-demo");
  root.querySelector("#tr-demo-replay").addEventListener("click", () => {
    root.querySelectorAll("mv-text-reveal").forEach((el) => el.replay());
  });
</script>

API

Attributes

Name类型DefaultDescription
effectfade-up | blur | slide | rotate | scale | maskfade-upEntrance preset. mask = pieces rise from behind a clipping line.
bychars | words | lineswordsSplit granularity. lines groups words by visual line (measured at start).
triggerview | load | hover | manualviewTrigger (combinable: "view hover"). manual shows the text and waits for replay().
durationnumber (ms)700 (900 for mask)Duration per piece.
delaynumber (ms)0Delay before the first piece.
staggernumber (ms)28 / 70 / 160Delay between pieces (letters / words / lines).
easingCSS easingvar(--mv-ease-out)Animation easing (tokens accepted, e.g. var(--mv-ease-spring)).
repeatbooleanReplays every time it enters the viewport (otherwise once).
textstringText to display (otherwise the child content). Changing it replays the animation.

Methods

NameDescription
replay()Restarts the reveal from the hidden state.

Events

NameDescription
mv-endWhen the last piece has finished entering.

Content structure

NameDescription
(content)Text with optional inline markup (<em>, <strong>, <span>…), preserved after splitting.

CSS variables

NameDescription
--mv-text-reveal-durationDefault duration per piece.
--mv-text-reveal-staggerDefault stagger.
--mv-text-reveal-easingDefault easing.
--mv-text-reveal-delayDefault initial delay.

Accessibility

The real text lives in a visually hidden copy read by screen readers; the split version is aria-hidden. Put the element inside an <h1>/<p> to keep the semantics. Under reduced motion, the text is shown immediately in its final state.

本页面由 AI 翻译。报告翻译问题