03Xoay vào khung hình
Mỗi chữ chuyển rotate và opacity cùng lúc từ -25 độ về 0 độ, trông như bay vào lúc còn nghiêng rồi tự đứng thẳng lại. Vì mỗi chữ tự có delay riêng qua --i, cụm chữ ngắn kiểu badge hay tag xoay vào theo đúng thứ tự đọc.
Dùng choTiêu đề card xuất hiện, nhấn mạnh nhãn badge và tag
transform: rotateopacity-25deg→0

<main class="stage">
<h1 class="rot" data-split>Hàng mới</h1>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop; // 글자들이 한 바퀴 도는 시간 (시차는 $stagger)
$easing: $ease-out; // 시작 빠르고 끝은 부드럽게
$stagger: 90ms; // --i 1당 시차
@include stage($stage-orange);
.rot {
margin: 0;
display: flex;
gap: clamp(4px, 1.4vw, 10px);
font-weight: 800; font-size: clamp(30px, 11vw, 48px); line-height: 1; font-family: inherit;
color: $subject-cream;
span {
display: inline-block;
animation: rotate-in $duration $easing infinite, letter-blur-in $duration $easing infinite;
animation-delay: calc(var(--i) * #{$stagger} + var(--n) * 60ms);
}
}
@keyframes rotate-in {
0%, 4% { opacity: 0; transform: rotate(-25deg); }
26%, 72% { opacity: 1; transform: rotate(0deg); }
90%, 100% { opacity: 0; transform: rotate(18deg); }
}
@keyframes letter-blur-in {
0%, 4% { filter: blur(9px); }
26%, 72% { filter: blur(0); }
90%, 100% { filter: blur(9px); }
}
@media (prefers-reduced-motion: reduce) {
.rot 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: #ff4d1f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.rot {
margin: 0;
display: flex;
gap: clamp(4px, 1.4vw, 10px);
font-weight: 800;
font-size: clamp(30px, 11vw, 48px);
line-height: 1;
font-family: inherit;
color: #fff7e6;
}
.rot span {
display: inline-block;
animation: rotate-in 2s ease-out infinite, letter-blur-in 2s ease-out infinite;
animation-delay: calc(var(--i) * 90ms + var(--n) * 60ms);
}
@keyframes rotate-in {
0%, 4% {
opacity: 0;
transform: rotate(-25deg);
}
26%, 72% {
opacity: 1;
transform: rotate(0deg);
}
90%, 100% {
opacity: 0;
transform: rotate(18deg);
}
}
@keyframes letter-blur-in {
0%, 4% {
filter: blur(9px);
}
26%, 72% {
filter: blur(0);
}
90%, 100% {
filter: blur(9px);
}
}
@media (prefers-reduced-motion: reduce) {
.rot 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 "./RotateIn.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 RotateInProps = {
letters: string[];
/** 글자들이 한 바퀴 도는 시간 ms (기본 2000) */
duration?: number;
/** --i 1당 시차 ms (기본 90ms) */
stagger?: number;
color?: string;
};
export default function RotateIn({ letters, duration = 2000, color = "#fff7e6" }: RotateInProps) {
return (
<h1 className={styles.rot} 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>
);
}03 Xoay vào khung hình — Diện tích đo được 4.82% · khung hình chuyển động 15/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


