در حال بارگذاری...

انیمیشن در CSS

ترنزیشن گفت از A به B چقدر طول بکشد. Transform گفت پیکسل‌ها کجا بروند. انیمیشن یک خط زمانی می‌نویسد: نقطهٔ وضعیت آرام بزند، لودر بی‌وقفه بچرخد، کارت‌ها یکی‌یکی وارد شوند — با @keyframes برای گام‌ها و animation برای اجرا.

انیمیشن یعنی چه؟

دو تکه دارد: یک مجموعهٔ نام‌دار از @keyframes که استایل را در درصدها (یا from / to) می‌چیند، و قانونی که همان نام را با مدت، تأخیر اختیاری، تعداد تکرار، جهت، تابع زمان‌بندی و fill-mode پخش می‌کند. مرورگر بین ایستگاه‌های کلیدی میان‌یابی می‌کند.

نام باید یکی باشد: animation-name: pulse فقط وقتی کار می‌کند که @keyframes pulse وجود داشته باشد. یکی را عوض کنید و دیگری را نه — هیچ حرکتی نمی‌بینید.

کنترل‌های انیمیشن در یک نگاه

📊 اجزای اصلی انیمیشن

قطعه نقش
@keyframes name { … } خط زمانی مقادیر در % / from / to
animation-name کدام مجموعهٔ keyframe پخش شود
animation-duration طول یک دور (s یا ms)
animation-timing-function نرمی داخل دور (ease، linear، …)
animation-delay صبر قبل از دور اول
animation-iteration-count چند بار تکرار (عدد یا infinite)
animation-direction normal، reverse، alternate، alternate-reverse
animation-fill-mode استایل قبل/بعد (none، forwards، backwards، both)
animation shorthand name → duration → timing → delay → iteration → direction → fill-mode (ترتیب رایج)

همهٔ longhand را با هم لازم ندارید. از name + duration شروع کنید؛ برای لودر infinite بگذارید، برای برگشت نرم alternate، و وقتی فریم آخر باید بماند forwards.

اولین خط زمانی — پالس آرام

Opacity و transform برای حرکت سبک مناسب‌اند. یک پالس نرم تمرین خوبی برای اولین @keyframes است.

پالس ملایم وضعیت با @keyframes

css
@keyframes pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.55;
transform: scale(0.92);
}
}

.status-dot {
display: inline-block;
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background: #16a34a;
animation: pulse 1.4s ease-in-out infinite;
}

0% و 100% یکی‌اند تا حلقه تمیز بسته شود. infinite دور را ادامه می‌دهد — برای نقطهٔ کوچک وضعیت خوب است؛ اگر کل هیرو صفحه را انیمیت کنید، شلوغ می‌شود.

چرخش بی‌وقفه — اسپینر با linear

چرخش با linear و infinite مثل اسپینر پیوسته دیده می‌شود. حتماً مسیر prefers-reduced-motion بگذارید که بچرخد یا بایستد.

حلقهٔ لودر با rotate بی‌وقفه

css
@keyframes spin {
to {
transform: rotate(360deg);
}
}

.loader {
width: 2rem;
height: 2rem;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
.loader {
animation: none;
border-top-color: #e5e7eb;
}
}

to همان 100% است. اگر فقط به پایان دور اهمیت می‌دهید، شروع پیش‌فرض 0% (بدون transform) کافی است.

تأخیر و stagger — یک keyframe، شروع‌های مختلف

یک مجموعهٔ keyframe می‌تواند چند عنصر را جلو ببرد. با animation-delay فاصله بیندازید تا فهرست پشت‌سرهم حس شود — بدون سه انیمیشن جدا.

محو شدن و بالا آمدن پشت‌سرهم آیتم‌ها

css
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(0.75rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.reveal-list li {
opacity: 0;
animation: fade-up 0.45s ease forwards;
}

.reveal-list li:nth-child(1) { animation-delay: 0s; }
.reveal-list li:nth-child(2) { animation-delay: 0.08s; }
.reveal-list li:nth-child(3) { animation-delay: 0.16s; }

forwards استایل فریم آخر را بعد از تمام شدن نگه می‌دارد — وگرنه آیتم‌ها ممکن است به opacity: 0 قانون پایه برگردند. اینجا animation-fill-mode واقعاً کار می‌کند.

fill-mode برای ورود یک‌باره

ورود معمولاً یک‌بار اجرا می‌شود. fill-mode مشخص می‌کند استایل قبل از تأخیر و بعد از فریم آخر چطور بماند.

ورود کارت با fill-mode both

css
@keyframes card-in {
from {
opacity: 0;
transform: translateY(1rem) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}

.card-enter {
animation: card-in 0.5s ease 0.1s both;
}

در این shorthand: نام card-in، مدت 0.5s، easing ease، تأخیر 0.1s، fill-mode both. both در زمان تأخیر فریم اول را می‌گذارد و بعد از پایان، فریم آخر را نگه می‌دارد.

جهت، توقف پخش، و کی انیمیت نکنیم

animation-direction: alternate دورهای فرد را جلو و زوج را برعکس می‌برد — برای بالا و پایین نرم بدون دوباره‌نویسی keyframe. animation-play-state: paused انیمیشن در حال اجرا را متوقف می‌کند (مثلاً مکث تزئینی روی هاور).

برای عوض شدن سادهٔ رنگ روی هاور همان transition کافی است. وقتی حلقه، داستان چندگامه، یا حرکتی می‌خواهید که به یک سوییچ حالت گره نخورده، سراغ انیمیشن بروید. داخل keyframe ترجیح با transform و opacity است؛ انیمیت کردن width، height یا top سنگین‌تر است و اغلب چیدمان را می‌لرزاند.

خودتان تمرین کنید

  1. پالسی با سه ایستگاه (0% / 50% / 100%) فقط روی opacity بسازید؛ بعد یک scale خیلی کوچک اضافه کنید.
  2. اسپینر با spin + linear + infinite؛ بعد ease بگذارید و حس ناهماهنگ را ببینید.
  3. سه نشان را با همان fade-up و تأخیرهای 0s، 0.1s، 0.2s stagger کنید — با و بدون forwards مقایسه کنید.
  4. روی یک پنل shorthand بنویسید: animation: card-in 0.5s ease 0.15s both؛ both را بردارید و برگشت ناگهانی را ببینید.
  5. زیر prefers-reduced-motion: reduce برای حلقه‌های تزئینی animation: none (یا یک محو کوتاه) بگذارید.

اشتباه‌های رایج

  • انتظار دارید محو هاور «تا ابد» تکرار شود — آن کار انیمیشن است، نه یک transition تنها
  • نام animation-name با @keyframes یکی نیست — بی‌صدا هیچ اتفاقی نمی‌افتد
  • infinite روی ناحیهٔ بزرگ و پرهیاهو بدون مکث یا مسیر reduced-motion
  • انیمیت ویژگی‌های چیدمان (width، margin، top) وقتی transform/opacity کافی است
  • فراموش کردن forwards / both در reveal یک‌باره که پایهٔ قانون opacity: 0 دارد

جمع‌بندی

  • @keyframes خط زمانی را می‌سازد؛ animation (یا longhandها) آن را پخش می‌کند
  • با iteration، direction، delay و fill-mode حلقه، برگشت، stagger و ماندن انتها را کنترل کنید
  • transform و opacity را ترجیح دهید؛ حرکت تزئینی را با prefers-reduced-motion محترم بشمارید
  • برای تغییر سادهٔ حالت transition؛ برای چندگام و تکرار انیمیشن
  • بعدی در Effects & Motion: فیلترهای CSS

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
7
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود