Animation و Keyframes در CSS
بهنام نوبخت · ۱۴۰۵/۶/۲۸
در مقاله قبل با Transition آشنا شدیم و یاد گرفتیم چگونه تغییرات بین دو وضعیت، مانند حالت عادی و hover، را نرم و تدریجی کنیم.
اما Transition برای همه نیازهای ما کافی نیست.
فرض کنید بخواهیم یک دکمه:
بهصورت خودکار حرکت کند،
چند مرحله مختلف داشته باشد،
چند بار تکرار شود،
بهصورت بینهایت اجرا شود،
در هر بار اجرا جهت خود را تغییر دهد،
یا بدون هیچ تعامل کاربر از ابتدا اجرا شود.
در چنین شرایطی CSS Animation ابزار مناسبتری است.
Animation به کمک keyframes اجازه میدهد مراحل مختلف یک حرکت را تعریف کنیم و سپس مشخص کنیم این Animation چه مدت اجرا شود، چند بار تکرار شود، با چه سرعتی حرکت کند و در پایان چه وضعیتی داشته باشد.
Animation در CSS چیست؟
Animation در CSS روشی برای تغییر تدریجی مقادیر CSS در طول زمان است.
تفاوت مهم آن با Transition این است که Animation میتواند یک توالی کامل از مراحل داشته باشد.
مثلاً:
شروع
↓
حرکت به راست
↓
بزرگ شدن
↓
چرخش
↓
کوچک شدن
↓
پایانبرای تعریف چنین مراحلی از keyframes استفاده میکنیم.
keyframes چیست؟
keyframes محل تعریف مراحل مختلف یک Animation است.
مثلاً:
@keyframes move-box {
from {
transform: translateX(0);
}
to {
transform: translateX(300px);
}
}در این مثال Animation دو مرحله دارد:
from → شروع
to → پایانfrom معادل 0% و to معادل 100% است. همچنین میتوان بهجای دو مرحله، درصدهای مختلفی مانند 25%، 50% و 75% تعریف کرد.
اجرای اولین Animation
فقط تعریف keyframes کافی نیست.
باید Animation را به یک عنصر متصل کنیم.
مثلاً:
.box {
width: 100px;
height: 100px;
background-color: #f97316;
animation-name: move-box;
animation-duration: 2s;
}
@keyframes move-box {
from {
transform: translateX(0);
}
to {
transform: translateX(300px);
}
}در اینجا:
animation-name: move-box;نام Animation را مشخص میکند.
و:
animation-duration: 2s;مشخص میکند یک چرخه Animation دو ثانیه طول بکشد.
animation-name
ویژگی animation-name مشخص میکند کدام keyframes باید روی عنصر اجرا شود.
مثلاً:
.box {
animation-name: move-box;
}و:
@keyframes move-box {
from {
transform: translateX(0);
}
to {
transform: translateX(300px);
}
}نام باید با نام keyframes مطابقت داشته باشد.
مثلاً اگر بنویسیم:
animation-name: slide;باید Animation زیر وجود داشته باشد:
@keyframes slide {
...
}animation-duration
ویژگی animation-duration مدت زمان یک چرخه Animation را مشخص میکند.
مثلاً:
.box {
animation-duration: 3s;
}یعنی یک چرخه Animation سه ثانیه طول میکشد.
مثال:
.box {
animation-name: move-box;
animation-duration: 1s;
}یا:
.box {
animation-name: move-box;
animation-duration: 500ms;
}Animation چندمرحلهای
قدرت اصلی keyframes زمانی مشخص میشود که بیش از دو مرحله داشته باشیم.
مثلاً:
@keyframes move-box {
0% {
transform: translateX(0);
}
50% {
transform: translateX(200px);
}
100% {
transform: translateX(400px);
}
}در اینجا Animation سه مرحله دارد:
0% → شروع
50% → وسط
100% → پایان
این یعنی میتوانیم رفتار عنصر را در نقاط مختلف Animation کنترل کنیم.
استفاده از درصدها
میتوانیم مراحل بیشتری تعریف کنیم:
@keyframes example {
0% {
transform: translateX(0);
}
25% {
transform: translateX(100px);
}
50% {
transform: translateX(200px);
}
75% {
transform: translateX(100px);
}
100% {
transform: translateX(0);
}
}حالا عنصر:
0%
↓
25%
↓
50%
↓
75%
↓
100%حرکت میکند.
این یکی از مهمترین تفاوتهای Animation و Transition است.
ساخت Animation با from و to
برای Animationهای ساده میتوان از:
from
toاستفاده کرد.
مثلاً:
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}و:
.box {
animation: fade-in 1s ease;
}این روش برای Animationهای ساده و دو مرحلهای بسیار خوانا است.
Animation برای ظاهر شدن عنصر
یکی از کاربردهای بسیار رایج:
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}سپس:
.hero-content {
animation: fade-up 0.8s ease-out;
}نتیجه:
عنصر ابتدا:
شفاف + کمی پایینتر
↓
عنصر در پایان:
نمایان + در جای اصلیاین نوع Animation در Landing Pageها بسیار رایج است.
animation-timing-function
این ویژگی تعیین میکند Animation در طول زمان با چه منحنی سرعتی پیش برود.
مقادیر رایج:
linear
ease
ease-in
ease-out
ease-in-outمثلاً:
.box {
animation:
move-box 2s ease-in-out;
}linear
animation-timing-function: linear;سرعت تقریباً ثابت است.
ease
animation-timing-function: ease;حرکت در ابتدا و انتها نرمتر است.
ease-in
animation-timing-function: ease-in;Animation آرامتر شروع میشود.
ease-out
animation-timing-function: ease-out;Animation در پایان آرامتر میشود.
ease-in-out
animation-timing-function: ease-in-out;شروع و پایان نرمتر هستند.
animation-delay
گاهی نمیخواهیم Animation بلافاصله شروع شود.
برای این کار از animation-delay استفاده میکنیم.
.box {
animation-name: fade-in;
animation-duration: 1s;
animation-delay: 0.5s;
}یعنی Animation پس از 0.5 ثانیه شروع میشود.
animation-iteration-count
این ویژگی مشخص میکند Animation چند بار اجرا شود. مقدار پیشفرض 1 است. همچنین میتوان از infinite برای اجرای بینهایت استفاده کرد.
مثلاً:
.box {
animation-iteration-count: 3;
}Animation سه بار اجرا میشود.
یا:
.box {
animation-iteration-count: infinite;
}Animation تا زمانی که عنصر در صفحه وجود داشته باشد، تکرار میشود.
Animation بینهایت
مثلاً یک نقطه چشمکزن:
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.dot {
animation: blink 1s ease-in-out infinite;
}این Animation دائماً تکرار میشود.
برای مواردی مانند:
Loading
وضعیت آنلاین
اعلانها
عناصر تزئینی
میتواند کاربرد داشته باشد.
animation-direction
ویژگی animation-direction مشخص میکند Animation در چه جهتی اجرا شود. حالتهای اصلی آن عبارتاند از:
normal
reverse
alternate
alternate-reversenormal
حالت پیشفرض:
animation-direction: normal;Animation از ابتدا به انتها اجرا میشود.
0% → 100%reverse
در این حالت Animation در جهت معکوس اجرا میشود:
animation-direction: reverse;100% → 0%alternate
یکی از کاربردیترین حالتها:
animation-direction: alternate;اگر Animation چند بار تکرار شود:
→
←
→
←مثلاً:
.box {
animation:
move-box 1s ease-in-out infinite alternate;
}این روش برای حرکت رفت و برگشتی بسیار کاربردی است.
alternate-reverse
در این حالت اولین چرخه از جهت معکوس شروع میشود:
animation-direction: alternate-reverse;ساخت Animation رفت و برگشتی
مثلاً یک توپ:
@keyframes bounce {
from {
transform: translateY(0);
}
to {
transform: translateY(-80px);
}
}
.ball {
animation:
bounce 0.7s ease-in-out infinite alternate;
}نتیجه:
بالا
↓
پایین
↓
بالا
↓
پایینبدون نیاز به تعریف چند Animation جداگانه.
animation-fill-mode
یکی از ویژگیهای مهم Animation، animation-fill-mode است.
این ویژگی مشخص میکند استایلهای Animation قبل از شروع و بعد از پایان چگونه روی عنصر اعمال شوند.
مقادیر مهم:
none
forwards
backwards
bothnone
حالت پیشفرض است:
animation-fill-mode: none;Animation قبل و بعد از اجرای خودش استایلهای keyframe را حفظ نمیکند.
forwards
با:
animation-fill-mode: forwards;عنصر پس از پایان Animation در وضعیت آخر Animation باقی میماند.
مثلاً:
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.box {
animation:
fade-out 1s ease forwards;
}پس از پایان Animation، عنصر در وضعیت opacity: 0 باقی میماند.
backwards
با backwards، در زمان delay نیز استایل اولین Keyframe اعمال میشود.
.box {
animation:
fade-in 1s ease 1s backwards;
}both
ترکیبی از forwards و backwards است:
animation-fill-mode: both;یعنی رفتار هر دو حالت را در زمان مناسب اعمال میکند.
animation-play-state
این ویژگی برای کنترل وضعیت اجرای Animation استفاده میشود.
دو مقدار اصلی:
running
pausedمثلاً:
.box {
animation: move-box 2s linear infinite;
}
.box:hover {
animation-play-state: paused;
}حالا Animation هنگام Hover متوقف میشود.
ساخت Loader با Animation
یکی از پروژههای کلاسیک CSS:
<div class="loader"></div>CSS:
.loader {
width: 50px;
height: 50px;
border: 5px solid #e5e7eb;
border-top-color: #f97316;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}در اینجا:
animation: spin 0.8s linear infinite;یعنی:
Animation:
spinمدت:
0.8sسرعت:
linearتکرار: بینهایت
ساخت Pulse Effect
میتوانیم یک عنصر را بهصورت ضربانی نمایش دهیم.
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.08);
opacity: 0.7;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.pulse {
animation: pulse 1.5s ease-in-out infinite;
}این افکت برای:
دکمههای مهم
اعلانها
وضعیت آنلاین
عناصر تبلیغاتی
قابل استفاده است.
البته نباید از چنین افکتهایی بیش از حد استفاده کرد.
ساخت Floating Animation
برای ایجاد حرکت آرام بالا و پایین:
@keyframes floating {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-12px);
}
100% {
transform: translateY(0);
}
}
.floating {
animation: floating 3s ease-in-out infinite;
}این افکت برای عناصر تزئینی Hero Section بسیار مناسب است.
ساخت انیمیشن چندمرحلهای
حالا یک Animation حرفهایتر بسازیم.
@keyframes hero-card {
0% {
opacity: 0;
transform: translateY(40px) scale(0.95);
}
50% {
opacity: 0.7;
transform: translateY(-10px) scale(1.02);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}و:
.hero-card {
animation: hero-card 1s ease-out;
}در این Animation چند ویژگی همزمان تغییر میکنند:
opacity
transform
translateY
scaleاین همان جایی است که قدرت واقعی keyframes مشخص میشود.
Animation Shorthand
مانند بسیاری از ویژگیهای CSS، Animation نیز یک Shorthand دارد.
مثلاً:
animation-name: fade-up;
animation-duration: 0.8s;
animation-timing-function: ease-out;
animation-delay: 0.2s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: forwards;میتواند به شکل کوتاهتر نوشته شود:
animation:
fade-up
0.8s
ease-out
0.2s
1
normal
forwards;یا در یک خط:
animation: fade-up 0.8s ease-out 0.2s 1 normal forwards;ویژگی animation یک Shorthand برای مجموعهای از ویژگیهای Animation است.
در پروژههای واقعی معمولاً شکل کوتاهشده بسیار کاربردیتر است.
یک الگوی بسیار مهم برای پروژهها
مثلاً:
.card {
animation:
fade-up 0.7s ease-out 0.2s both;
}این خط را میتوان به شکل زیر تحلیل کرد:
fade-up
↓
نام Animation
0.7s
↓
مدت Animation
ease-out
↓
نحوه سرعت
0.2s
↓
تأخیر
both
↓
Fill Modeچند Animation روی یک عنصر
میتوان چند Animation را روی یک عنصر اجرا کرد.
مثلاً:
.box {
animation:
move 2s ease-in-out infinite alternate,
rotate 4s linear infinite;
}هر Animation با کاما از Animation بعدی جدا میشود. CSS از چند Animation در یک declaration پشتیبانی میکند.
این قابلیت بسیار قدرتمند است، اما باید با دقت استفاده شود تا حرکتهای مختلف با یکدیگر تداخل ایجاد نکنند.
Animation و Transform
یکی از بهترین ویژگیهایی که میتوان همراه Animation استفاده کرد:
transformمثلاً:
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}و:
.icon {
animation: rotate 2s linear infinite;
}یا:
@keyframes float {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-15px);
}
100% {
transform: translateY(0);
}
}این ترکیب برای UI مدرن بسیار پرکاربرد است.
ساخت Hero Section با Animation
فرض کنید یک Hero Section داریم:
<section class="hero">
<div class="hero-content">
<span class="hero-badge">
راهکارهای دیجیتال
</span>
<h1>
زیرساخت دیجیتال
کسبوکار شما
</h1>
<p>
مجموعهای از محصولات و خدمات مدرن
برای رشد کسبوکار شما.
</p>
<a href="#" class="hero-button">
مشاهده خدمات
</a>
</div>
</section>حالا Animation:
@keyframes hero-content {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hero-content {
animation:
hero-content 0.8s ease-out both;
}حالا میتوانیم عناصر را با تأخیرهای مختلف وارد کنیم.
.hero-badge {
animation:
hero-content 0.6s ease-out 0.1s both;
}
.hero h1 {
animation:
hero-content 0.7s ease-out 0.2s both;
}
.hero p {
animation:
hero-content 0.7s ease-out 0.35s both;
}
.hero-button {
animation:
hero-content 0.7s ease-out 0.5s both;
}در نتیجه عناصر بهصورت مرحلهای ظاهر میشوند:
Badge
↓
Title
↓
Description
↓
Buttonاین تکنیک را میتوان برای ایجاد ورود تدریجی محتوا استفاده کرد.
Animation و Hover
Animation را میتوان هنگام hover نیز فعال کرد.
مثلاً:
@keyframes shake {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-5px);
}
100% {
transform: translateX(0);
}
}
.button:hover {
animation: shake 0.4s ease;
}با این حال، برای تغییرات ساده hover معمولاً Transition انتخاب سادهتری است.
Animation زمانی ارزش بیشتری پیدا میکند که به چند مرحله مختلف نیاز داشته باشیم.
تفاوت Transition و Animation
حالا تفاوت این دو را دقیقتر ببینیم.
ویژگی | Transition | Animation |
|---|---|---|
نیاز به تغییر State | معمولاً بله | خیر |
| ندارد | دارد |
چند مرحله | محدود به ابتدا و انتها | بسیار مناسب |
اجرای خودکار | معمولاً خیر | بله |
تکرار بینهایت | مناسب نیست | بله |
کنترل جهت | محدود | کاملتر |
Delay | دارد | دارد |
Loop | ندارد | دارد |
مناسب Hover | بسیار مناسب | مناسب برای موارد خاص |
یک قانون ساده:
اگر تغییر بین دو وضعیت دارید، ابتدا به Transition فکر کنید.
اگر یک توالی چندمرحلهای یا Animation مستقل دارید، از Animation و
@keyframesاستفاده کنید.
Animation و Accessibility
Animation جذاب است، اما نباید فراموش کنیم که همه کاربران تجربه یکسانی از حرکت ندارند.
برای کاربرانی که سیستم خود را روی کاهش حرکت تنظیم کردهاند، میتوان Animation را کاهش داد یا حذف کرد.
مثلاً:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}هدف این است که Motion غیرضروری کاهش پیدا کند.
در طراحی حرفهای، Animation باید در خدمت تجربه کاربری باشد، نه اینکه تجربه کاربر را مختل کند.
اشتباهات رایج در Animation
۱. Animation بیش از حد
اگر تمام عناصر صفحه دائماً حرکت کنند:
عنوان
دکمه
کارت
تصویر
منو
آیکون
پسزمینهصفحه میتواند بسیار شلوغ و آزاردهنده شود.
Animation باید هدف مشخصی داشته باشد.
۲. استفاده از Animation بسیار طولانی
مثلاً:
animation: fade-in 10s ease;برای یک ورود ساده معمولاً بیش از حد طولانی است.
۳. استفاده بیدلیل از infinite
این کد:
animation: pulse 1s infinite;تا زمانی که عنصر وجود دارد اجرا میشود.
اگر تعداد زیادی عنصر چنین Animationای داشته باشند، صفحه دائماً در حال حرکت خواهد بود.
پس infinite را فقط زمانی استفاده کنید که تکرار مداوم واقعاً بخشی از طراحی باشد.
۴. فراموش کردن animation-name
اگر فقط بنویسیم:
.box {
animation-duration: 2s;
}Animationی اجرا نمیشود، چون مشخص نکردهایم کدام @keyframes باید استفاده شود.
باید مثلاً داشته باشیم:
animation-name: fade-in;یا:
animation: fade-in 2s ease;۵. اشتباه گرفتن Duration و Delay
این دو متفاوت هستند:
animation-duration: 2s;یعنی:
Animation چقدر طول بکشد؟
اما:
animation-delay: 2s;یعنی:
Animation چه زمانی بعد شروع شود؟
۶. استفاده نامناسب از transform
اگر چند Animation همزمان بخواهند transform را کنترل کنند، ممکن است نتیجه مورد انتظار ایجاد نشود.
مثلاً یک Animation:
transform: translateX(...);و Animation دیگر:
transform: rotate(...);میتوانند با یکدیگر تداخل ایجاد کنند.
در چنین شرایطی باید ساختار Animationها را با دقت طراحی کنید.
پروژه عملی: Animated Service Card
حالا یک کارت خدمات واقعی طراحی کنیم.
HTML
<article class="service-card">
<div class="service-icon">
🚀
</div>
<h3>
طراحی سایت
</h3>
<p>
طراحی سایت مدرن، سریع و Responsive
برای کسبوکارهای امروزی.
</p>
<a href="#">
مشاهده خدمات ←
</a>
</article>CSS
.service-card {
padding: 30px;
background-color: #ffffff;
border-radius: 20px;
border: 1px solid #e5e7eb;
box-shadow:
0 10px 30px rgba(0, 0, 0, 0.06);
animation:
card-enter 0.8s ease-out both;
}
@keyframes card-enter {
from {
opacity: 0;
transform:
translateY(30px)
scale(0.96);
}
to {
opacity: 1;
transform:
translateY(0)
scale(1);
}
}حالا آیکون را نیز متحرک کنیم:
.service-icon {
display: inline-block;
animation:
icon-floating 2s ease-in-out infinite alternate;
}
@keyframes icon-floating {
from {
transform: translateY(0);
}
to {
transform: translateY(-8px);
}
}در این مثال:
خود کارت هنگام ورود ظاهر میشود.
آیکون بهصورت مداوم حرکت بسیار آرام دارد.
این نمونهای از ترکیب چند نوع Animation در یک رابط کاربری است.
تمرینهای مقاله
تمرین ۱ — Fade In
یک عنصر ایجاد کنید که از:
opacity: 0;شروع شود و به:
opacity: 1;برسد.
Animation باید یک ثانیه طول بکشد.
تمرین ۲ — حرکت از پایین
یک Animation بسازید که عنصر از:
transform: translateY(50px);
opacity: 0;به:
transform: translateY(0);
opacity: 1;برسد.
تمرین ۳ — چرخش
یک Loader بسازید که دائماً بچرخد.
از:
animation-iteration-count: infinite;استفاده کنید.
تمرین ۴ — رفت و برگشت
یک عنصر بسازید که به سمت راست حرکت کند و دوباره به سمت چپ برگردد.
از این ترکیب کمک بگیرید:
animation-direction: alternate;
animation-iteration-count: infinite;تمرین ۵ — Animation چندمرحلهای
یک Animation پنج مرحلهای بسازید:
0%
25%
50%
75%
100%در هر مرحله مقدار transform را تغییر دهید.
جمعبندی
در این مقاله با سیستم Animation در CSS آشنا شدیم.
مهمترین بخش Animation، @keyframes است. با استفاده از آن میتوانیم مراحل مختلف یک حرکت را تعریف کنیم. from و to برای Animationهای ساده مناسب هستند و درصدهایی مانند 0%، 50% و 100% امکان ساخت Animationهای چندمرحلهای را فراهم میکنند.
سپس یاد گرفتیم Animation را با ویژگیهایی مانند:
animation-name
animation-duration
animation-timing-function
animation-delay
animation-iteration-count
animation-direction
animation-fill-mode
animation-play-stateکنترل کنیم. این ویژگیها در قالب Shorthand animation نیز قابل ترکیب هستند.
همچنین دیدیم که Animation میتواند برای ساخت:
Fade In
Slide In
Loader
Spinner
Pulse
Floating Effect
Hero Animation
کارتهای متحرک
استفاده شود.
اما یک نکته مهم را همیشه به خاطر داشته باشید:
Animation خوب، انیمیشنی نیست که بیشترین حرکت را داشته باشد؛ انیمیشنی است که به درک بهتر رابط کاربری و تجربه بهتر کاربر کمک کند.
در مقاله بعدی وارد یکی دیگر از قابلیتهای مهم CSS3 میشویم و با Filterها در CSS آشنا خواهیم شد؛ ویژگیهایی که به کمک آنها میتوان روی تصاویر و عناصر مختلف افکتهایی مانند Blur، Brightness، Contrast، Grayscale و دیگر جلوههای بصری ایجاد کرد.
نظرات
هنوز نظری ثبت نشده است.