02Nảy từng chữ
Mỗi chữ trong tiêu đề nằm trong một thẻ span riêng, được gắn animation-delay lệch nhau 40ms qua biến --i, nên chữ nảy lên từ dưới và rơi đúng vị trí lần lượt chứ không cùng lúc. Vì công thức trễ chỉ dựa vào --i, thêm bớt chữ chỉ cần đánh lại số thứ tự.
Dùng choIntro logo, tiêu đề hero trang landing
--i 변수40ms 간격translateY 바운스

<main class="stage">
<h1 class="letters" data-split>GODRICH</h1>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop; // 글자들이 한 바퀴 도는 시간 (시차는 $stagger)
$easing: $ease-pop; // 아래에서 튀어오르는 느낌
$stagger: 40ms; // --i 1당 시차
@include stage($stage-yellow);
.letters {
margin: 0;
display: flex;
gap: clamp(2px, 1vw, 6px);
font-weight: 800; font-size: clamp(28px, 10vw, 46px); line-height: 1; font-family: inherit;
color: $subject-ink;
span {
display: inline-block;
animation: letter-bounce $duration $easing infinite, letter-blur-in $duration $easing infinite;
animation-delay: calc(var(--i) * #{$stagger} + var(--n) * 60ms);
}
}
@keyframes letter-bounce {
0%, 4% { opacity: 0; transform: translateY(22px); }
22%, 70% { opacity: 1; transform: translateY(0); }
88%, 100% { opacity: 0; transform: translateY(-14px); }
}
@keyframes letter-blur-in {
0%, 4% { filter: blur(10px); }
22%, 70% { filter: blur(0); }
88%, 100% { filter: blur(10px); }
}
@media (prefers-reduced-motion: reduce) {
.letters span { animation: none; opacity: 1; transform: none; filter: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffd23f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.letters {
margin: 0;
display: flex;
gap: clamp(2px, 1vw, 6px);
font-weight: 800;
font-size: clamp(28px, 10vw, 46px);
line-height: 1;
font-family: inherit;
color: #17141a;
}
.letters span {
display: inline-block;
animation: letter-bounce 2s cubic-bezier(0.2, 1.4, 0.4, 1) infinite, letter-blur-in 2s cubic-bezier(0.2, 1.4, 0.4, 1) infinite;
animation-delay: calc(var(--i) * 40ms + var(--n) * 60ms);
}
@keyframes letter-bounce {
0%, 4% {
opacity: 0;
transform: translateY(22px);
}
22%, 70% {
opacity: 1;
transform: translateY(0);
}
88%, 100% {
opacity: 0;
transform: translateY(-14px);
}
}
@keyframes letter-blur-in {
0%, 4% {
filter: blur(10px);
}
22%, 70% {
filter: blur(0);
}
88%, 100% {
filter: blur(10px);
}
}
@media (prefers-reduced-motion: reduce) {
.letters span {
animation: none;
opacity: 1;
transform: none;
filter: none;
}
}(function(){
function splitLetters(el){
var text = el.textContent;
el.textContent = "";
Array.from(text).forEach(function(ch, i){
var span = document.createElement("span");
span.className = "letter";
var seed = Math.sin((i + 1) * 12.9898) * 43758.5453;
var noise = seed - Math.floor(seed);
span.style.setProperty("--i", i);
span.style.setProperty("--n", noise.toFixed(3));
span.textContent = ch === " " ? " " : ch;
el.appendChild(span);
});
}
document.querySelectorAll("[data-split]").forEach(splitLetters);
})();import type { CSSProperties } from "react";
import styles from "./LetterBounce.module.scss";
type Vars = CSSProperties & { "--i"?: number; "--n"?: number };
function noise(i: number): number {
const s = Math.sin((i + 1) * 12.9898) * 43758.5453;
return Number((s - Math.floor(s)).toFixed(3));
}
export type LetterBounceProps = {
letters: string[];
/** 글자들이 한 바퀴 도는 시간 ms (기본 2000) */
duration?: number;
/** --i 1당 시차 ms (기본 40ms) */
stagger?: number;
color?: string;
};
export default function LetterBounce({ letters, duration = 2000, color = "#17141a" }: LetterBounceProps) {
return (
<h1 className={styles.letters} style={{ "--color": color, "--duration": `${duration}ms` } as CSSProperties}>
{letters.map((ch, i) => (
<span key={i} style={{ "--i": i, "--n": noise(i) } as Vars}>{ch}</span>
))}
</h1>
);
}02 Nảy từng chữ — Diện tích đo được 8.615% · khung hình chuyển động 12/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 CSS Text Animation Effects — dán 1 dòng là chạy
Bài viết chứa demo này
9 CSS Text Animation Effects — dán 1 dòng là chạyCSS text animation effects là các chuyển động chữ dựng thuần bằng CSS, không cần JavaScript, giúp tiêu đề hay câu chữ xu Xem tất cả demo trong bài này

