模糊入场文字

标题逐字从模糊变得清晰,每个字落定时微微上升。

  • CSS
  • 文字
  • 进场
  • 收录于

AI 提示词

用 React 制作一个逐字从模糊变清晰的标题入场效果。用 Array.from 把“逐渐清晰”拆成 inline-block 的 span,并把 --i 设为每个字的序号。每个 span 从 opacity 0、filter blur(12px)、translateY(0.25em) 动画到 opacity 1、blur(0)、translateY(0),时长 700ms,缓动为 cubic-bezier(0.16, 1, 0.3, 1),fill-mode 为 both,延迟为 calc(var(--i) * 45ms)。添加一个“重播”按钮,通过改变外层元素的 key 重新播放动画。可读文字放在 aria-label 中。在 prefers-reduced-motion 下改为整句 150ms 的透明度淡入。

源代码

Demo.tsx
'use client'

import { useState } from 'react'
import s from './demo.module.css'

export default function BlurInLetters({ labels }: { labels: Record<string, string> }) {
  const [run, setRun] = useState(0)

  return (
    <div className={s.wrap}>
      <p key={run} className={s.text} aria-label={labels.text}>
        {Array.from(labels.text).map((ch, i) => (
          <span key={i} className={s.ch} style={{ '--i': i } as React.CSSProperties} aria-hidden="true">
            {ch === ' ' ? ' ' : ch}
          </span>
        ))}
      </p>
      <button type="button" className={s.button} onClick={() => setRun(run + 1)}>
        {labels.replay}
      </button>
    </div>
  )
}
demo.module.css
.wrap { display: grid; justify-items: center; gap: 16px; }

.text {
  display: flex;
  margin: 0;
  font: 700 2.6rem / 1.1 var(--font-display);
  letter-spacing: -0.03em;
  color: var(--stage-ink);
  white-space: nowrap;
}

.ch {
  display: inline-block;
  animation: focus-in 700ms var(--ease-out) both;
  animation-delay: calc(var(--i) * 45ms);
}

@keyframes focus-in {
  from { opacity: 0; filter: blur(12px); transform: translateY(0.25em); }
}

.button {
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--stage-rule);
  border-radius: 8px;
  background: var(--stage-surface);
  color: var(--stage-ink);
  font: 500 var(--text-sm) / 1 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
}

.button:hover { border-color: var(--stage-accent); }
.button:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .ch { animation: none; }
  .text { animation: fade 150ms linear both; }
}

@keyframes fade { from { opacity: 0; } }

投稿创意

看到想收录的动效或主题?简单描述一下,会打开一个预先填好的 GitHub Issue,确认后即可提交。

你想投稿的是?

需要 GitHub 账号,投稿内容会公开。