انیمیشن‌ها؛ وقتی transition دیگه کافی نیست

تا اینجا با transition کار کردیم و دیدیم چطور می‌شه یه تغییر رو نرم کرد. اما transition یه محدودیت اساسی داره: فقط بین دو حالت (شروع و پایان) حرکت می‌کنه و فقط وقتی یه چیزی عوض بشه (مثل هاور یا کلاس جدید) فعال می‌شه. اگه بخواید یه حرکت پیچیده‌تر بسازید، مثلاً چیزی که چند مرحله داره، یا چیزی که بدون هیچ محرکی خودش شروع بشه و تکرار بشه، باید سراغ @keyframes برید. این شروع یه فصل کاملاً جدیده.

@keyframes چیه؟

@keyframes یه قانون CSS هست که بهتون اجازه می‌ده مراحل مختلف یه انیمیشن رو تعریف کنید؛ یعنی بگید المنت در چه درصدهایی از زمان انیمیشن، چه شکلی باید باشه. بعد این تعریف رو با یه اسم دلخواه ذخیره می‌کنید تا بعداً به هر المنتی که خواستید وصلش کنید:

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

اینجا fade-in اسمیه که خودمون انتخاب کردیم؛ می‌تونست هر اسم دیگه‌ای باشه. from و to هم معادل 0% و 100% هستن؛ یعنی حالت شروع و پایان انیمیشن.

چطور این انیمیشن رو اجرا کنیم؟

خود @keyframes به‌تنهایی هیچ کاری انجام نمی‌ده؛ فقط یه تعریفه. برای اجرا کردنش، باید حداقل دو ویژگی روی المنت موردنظر ست کنید: animation-name و animation-duration:

.box {
  animation-name: fade-in;
  animation-duration: 1s;
}

به محض این‌که این کد لود بشه، المنت .box بدون نیاز به هیچ هاور یا کلیکی، خودش انیمیشن رو اجرا می‌کنه. این دقیقاً همون فرقی هست که با transition داره؛ transition منتظر یه تغییر می‌مونه، ولی animation خودش شروع‌کننده‌ست.

تعریف مراحل بیشتر با درصد

محدود به دو نقطه‌ی from و to نیستید. می‌تونید هر تعداد نقطه‌ی میانی که بخواید با درصد مشخص کنید:

@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-30px);
  }
  100% {
    transform: translateY(0);
  }
}

مرورگر بین هر دو نقطه‌ی مشخص‌شده، مقادیر رو به‌صورت خودکار و نرم تولید می‌کنه (interpolation)؛ شما فقط نقاط کلیدی (همون keyframe ها) رو تعیین می‌کنید.

می‌شه چند ویژگی رو هم‌زمان تو یه keyframe انیمیت کرد

هیچ محدودیتی نیست که هر درصد فقط یه ویژگی داشته باشه؛ می‌تونید هر تعداد ویژگی که بخواید رو با هم تغییر بدید:

@keyframes pop-in {
  0% {
    opacity: 0;
    transform: scale(0.5);
  }
  70% {
    opacity: 1;
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

نکته‌ی جالب اینجا اینه که opacity تو مرحله‌ی ۱۰۰٪ نوشته نشده. تو این حالت‌ها، مرورگر آخرین مقدار مشخص‌شده رو نگه می‌داره؛ یعنی opacity همون ۱ که تو ۷۰٪ گذاشتیم می‌مونه.

اسم‌گذاری keyframes: چند نکته

اسم انیمیشن (مثل fade-in یا bounce) کاملاً دلخواهه، فقط باید از حروف، عدد، خط تیره و آندرلاین استفاده کنید و با عدد شروع نشه. یه نکته‌ی مهم: اسم‌های none، inherit، initial و unset رو نمی‌تونید به‌عنوان اسم انیمیشن استفاده کنید، چون این‌ها مقادیر رزرو‌شده‌ی CSS هستن.

نکته مهم: اگه یه ویژگی رو در یکی از مراحل درصدی ننویسید، مرورگر ازش رد نمی‌شه و خالی نمی‌مونه؛ بلکه آخرین مقدار تعریف‌شده‌ی قبلی همون ویژگی رو نگه می‌داره تا مرحله‌ی بعدی که دوباره تعریف بشه.

کدوم ویژگی‌ها رو می‌شه انیمیت کرد؟

مثل transition، فقط ویژگی‌هایی قابل انیمیت هستن که مقداری عددی یا قابل محاسبه دارن؛ مثل opacity، transform، رنگ‌ها، عرض و ارتفاع، فاصله‌ها و غیره. ویژگی‌هایی مثل display قابل انیمیت نیستن (یا حالت جامپ می‌کنن، نه نرم).

اشتباه رایج: فراموش کردن animation-duration

اگه فقط animation-name رو تنظیم کنید و animation-duration رو ننویسید، مقدار پیش‌فرض 0s هست؛ یعنی انیمیشن تعریف می‌شه ولی هیچ‌وقت دیده نمی‌شه چون تو صفر ثانیه تمام می‌شه. این یکی از رایج‌ترین دلایلیه که تازه‌کارها فکر می‌کنن انیمیشن‌شون کار نمی‌کنه.

جمع‌بندی

@keyframes بهتون اجازه می‌ده مراحل مختلف یه انیمیشن رو با درصد یا با from/to تعریف کنید، و بعد با animation-name و animation-duration این تعریف رو به یک المنت وصل کنید. برخلاف transition، این انیمیشن نیازی به محرک خارجی نداره و خودش اجرا می‌شه. تو درس‌های بعدی می‌ریم سراغ ویژگی‌های دیگه‌ی animation مثل تکرار، جهت حرکت و توقف در حالت پایانی.