توسعه فرانت‌اند

CSS Animations و Transitions: راهنمای عملی

تفاوت گذار و Keyframes با فایل کامل HTML/CSS/JS، وضعیت واقعی پنل، Focus و Reduced Motion؛ بدون حرکت خروج یا قابلیت ادعایی ناموجود.

1404/11/12 2 دقیقه مطالعه 1,447 بازدید

حرکت در رابط وقتی مفید است که تغییر را روشن کند: دکمه بازخورد بدهد، پنل ورودش را نشان دهد یا رابطه دو وضعیت قابل فهم شود. حرکت دائمی و بی‌هدف می‌تواند توجه را از کار اصلی بگیرد. در CSS، Transition برای گذار میان مقدارهای یک ویژگی و Animation برای توالی تعریف‌شده با Keyframes به کار می‌رود. انتخاب میان آن‌ها به نوع تغییر بستگی دارد، نه اینکه کدام پیشرفته‌تر به نظر می‌رسد.

پیش از نوشتن کد بپرسید چه چیزی تغییر می‌کند و کاربر باید چه برداشتی داشته باشد. اگر بازشدن یک پنل نتیجه کلیک است، حرکت باید همان وضعیت را همراهی کند. اگر پردازشی طول می‌کشد، شکل متحرک به تنهایی وضعیت واقعی را گزارش نمی‌کند. پیام، وضعیت و امکان ادامه باید روشن باشند. یک حرکت زیبا نمی‌تواند پاسخ نامعلوم یا فرایند خراب را قابل اعتماد کند.

Transition به تغییر مقدار نیاز دارد

Transition وقتی دیده می‌شود که مقدار یک ویژگی قابل گذار تغییر کند؛ مثلاً transform از جای معمول به کمی بالاتر برود. تعریف transition بدون تغییر وضعیت، حرکت تولید نمی‌کند. Duration مدت گذار و Timing Function الگوی پیشرفت آن را مشخص می‌کنند. Delay شروع را عقب می‌اندازد. راهنمای Transition در MDN مرجع رفتار ویژگی‌هاست. همه ویژگی‌ها به یک شکل میان مقدارها تغییر نمی‌کنند.

بهتر است ویژگی‌های مورد نظر را مشخص کنید، نه اینکه همه چیز را با all وارد گذار کنید. تغییر بعدی یک ویژگی نامرتبط می‌تواند حرکت ناخواسته ایجاد کند. برای حالت hover، حالت focus-visible را نیز در نظر بگیرید تا بازخورد فقط به ماوس محدود نشود. حرکت نباید اطلاعاتی را که فقط با Hover دیده می‌شوند، تنها راه دسترسی به کار اصلی کند. لمس و کیبورد رفتار یکسانی با اشاره‌گر ندارند.

Animation برای توالی مستقل‌تر

Keyframes وضعیت‌های مسیر را تعریف می‌کند و Animation مدت، تکرار، جهت و نحوه نگهداری وضعیت را مشخص می‌سازد. می‌توانید یک ورود کوتاه بسازید یا یک توالی چندمرحله‌ای داشته باشید. وجود Keyframes به تنهایی کافی نیست؛ باید animation-name یا قرارداد shorthand به عنصر مربوط وصل شود. راهنمای Animation در MDN این رابطه را توضیح می‌دهد. نام کلاس و نام Keyframes دو نقش متفاوت دارند.

تکرار بی‌نهایت را فقط با نیاز روشن انتخاب کنید. نشانگر دائمی می‌تواند مزاحم شود و برای بعضی کاربران ناخوشایند باشد. اگر حرکت اطلاعات مهمی دارد، متن یا وضعیت ثابت نیز باید آن را منتقل کند. Animation نباید فرم را بدون درخواست جابه‌جا کند یا کنترل را از محل مورد انتظار دور ببرد. حرکت ورود کوتاه معمولاً مسئله متفاوتی از پس‌زمینه متحرک دائمی دارد.

نمونه کامل یک فایل

کد زیر را در index.html ذخیره و در مرورگر باز کنید. به ابزار Build، کتابخانه، تصویر یا شبکه نیاز ندارد. دکمه «نمایش توضیح» وضعیت یک پنل را عوض می‌کند. خود دکمه Transition دارد و پنل هنگام ظاهرشدن Animation کوتاه می‌گیرد. HTML، CSS و JavaScript همگی در همان فایل هستند. شناسه panel و toggle در متن نمونه تعریف شده‌اند و کلاس action روی همان دکمه قرار دارد.

<!doctype html>
<html lang="fa" dir="rtl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>گذار و حرکت CSS</title>
<style>
body { font-family: sans-serif; margin: 2rem; }
.action { padding: .75rem 1rem; font: inherit; transition: transform 160ms ease; }
.action:hover, .action:focus-visible { transform: translateY(-2px); }
.action:focus-visible { outline: 3px solid #1757b8; outline-offset: 3px; }
.panel { margin-top: 1rem; padding: 1rem; background: #e8f1ff; animation: enter 180ms ease-out; }
.panel[hidden] { display: none; }
@keyframes enter { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .action { transition: none; } .panel { animation: none; } }
</style>
</head>
<body>
<main>
<h1>نمایش توضیح</h1>
<button class="action" id="toggle" type="button" aria-expanded="false" aria-controls="panel">نمایش توضیح</button>
<section class="panel" id="panel" hidden><h2>توضیح کوتاه</h2><p>حرکت باید به فهم تغییر کمک کند.</p></section>
</main>
<script>
const toggle = document.getElementById('toggle');
const panel = document.getElementById('panel');
toggle.addEventListener('click', () => {
  panel.hidden = !panel.hidden;
  toggle.setAttribute('aria-expanded', String(!panel.hidden));
  toggle.textContent = panel.hidden ? 'نمایش توضیح' : 'بستن توضیح';
});
</script>
</body>
</html>

در این نمونه، hidden وضعیت نمایش را تعیین می‌کند و aria-expanded روی دکمه با آن هماهنگ می‌شود. وقتی پنل پنهان است، فقط شفاف نشده؛ از نمایش خارج است. این نمونه عمداً انیمیشن خروج ندارد تا مدیریت زمان پایان و نگهداری عنصر در نمایش لازم نباشد. ورود با Keyframes انجام می‌شود. ادعای «باز و بسته‌شدن نرم در هر دو جهت» برای این کد درست نیست؛ متن باید همین مرز را حفظ کند.

مدت و الگوی حرکت

Duration را با فاصله و اهمیت تغییر هماهنگ کنید. عدد کوتاه برای یک دکمه با حرکت طولانی یک صفحه یکسان نیست. Timing Function می‌تواند شروع و پایان را نرم کند، اما مقدار مناسب به تجربه مورد نظر وابسته است. یک عدد ثابت برای همه رابط‌ها نسخه مناسبی نیست. در نمونه، زمان‌ها کوتاه‌اند تا بازخورد اصلی عقب نیفتد. کاربر نباید برای انجام قدم بعد منتظر نمایشی غیرضروری بماند.

اگر چند عنصر حرکت دارند، ترتیب باید رابطه منطقی را نشان دهد. تأخیر طولانی روی تک‌تک کارت‌ها ممکن است اطلاعات را دیر در دسترس قرار دهد. تغییر صفحه و بازخورد کنترل باید با جریان واقعی هماهنگ باشند. از داده عملکرد بدون اندازه‌گیری صحبت نکنید؛ یک حرکت کوتاه هم می‌تواند روی دستگاهی خاص سنگین باشد. کیفیت حرکت هم به حس رابط و هم به هزینه اجرای آن وابسته است.

Transform و Opacity، با مرز روشن

برای بسیاری از حرکت‌های ساده، transform و opacity انتخاب‌های رایج‌اند و معمولاً از تغییر مکرر ابعاد و موقعیت Layout مناسب‌ترند. اما این جمله تضمین اجرای بی‌هزینه روی هر عنصر نیست. اندازه سطح، فیلترها، لایه‌ها و دستگاه اثر دارند. will-change را روی همه عناصر فعال نکنید؛ ساخت لایه‌های بی‌نیاز می‌تواند هزینه داشته باشد. بهینه‌سازی باید به مسئله مشاهده‌شده وصل شود، نه فهرست اصطلاح‌ها.

تغییر opacity به صفر، عنصر را لزوماً از مسیر کیبورد و فناوری کمکی خارج نمی‌کند. برای پنل پنهان باید وضعیت تعاملی نیز درست باشد. نمونه از hidden استفاده می‌کند و به همین دلیل خروج را بی‌حرکت انجام می‌دهد. اگر خروج متحرک می‌خواهید، نیاز به قرارداد نمایش و پایان حرکت دارید. اضافه‌کردن فقط opacity بدون رسیدگی به Focus می‌تواند کنترل نامرئی قابل انتخاب بسازد.

Reduced Motion بخشی از نمونه است

برخی کاربران حرکت کمتر را در تنظیمات سیستم ترجیح می‌دهند. Media Query با prefers-reduced-motion امکان واکنش به این ترجیح را می‌دهد. در نمونه، Animation و Transition در حالت reduce حذف می‌شوند، اما کارکرد دکمه و پنل باقی می‌ماند. مستندات MDN درباره Reduced Motion مرجع این قابلیت است. حذف حرکت نباید اطلاعات یا امکان انجام کار را حذف کند.

حرکت شدید، بزرگ‌نمایی و جابه‌جایی وسیع را با دقت بیشتری بررسی کنید. ترجیح سیستم تنها ورودی ممکن برای طراحی نیست؛ برای تجربه‌های دارای حرکت قابل توجه، کنترل مناسب محصول هم ممکن است لازم باشد. یک Query به تنهایی گواهی دسترس‌پذیری کامل نیست. راهنمای دسترس‌پذیری رابط موضوع Focus، نام کنترل و وضعیت را جدا دنبال می‌کند. در CSS خالص هم همین اصول کاربرمحور اهمیت دارند.

Hover، Focus و صفحه لمسی

در نمونه، دکمه هنگام Hover یا Focus-visible کمی جابه‌جا می‌شود و Outline واضح دارد. این حرکت اطلاعات ضروری نیست و حذف آن عملکرد را تغییر نمی‌دهد. روی صفحه لمسی نباید فرض کنید Hover مثل دسکتاپ رخ می‌دهد. کنترل اصلی با کلیک یا فعال‌سازی کیبورد کار می‌کند و وضعیت بازبودن در ویژگی دکمه منعکس است. طراحی باید بدون وابستگی به یک شیوه ورودی قابل استفاده بماند.

حرکت را بهانه حذف نشانگر Focus نکنید. اگر پنلی Modal است، نمونه حاضر برای آن کافی نیست؛ مدیریت Focus، بستن و پس‌زمینه تعاملی لازم است. این پنل فقط توضیح در همان جریان صفحه است. نام «پنل» نباید با Dialog کامل اشتباه شود. اگر کارکرد دیگری می‌خواهید، HTML، وضعیت و رفتار مرتبط را هم اضافه کنید، نه فقط شکل ظاهری را تغییر دهید.

خطاهای رایج در نگهداری

Shorthandها می‌توانند مقدارهای قبلی را بازنویسی کنند؛ هنگام ترکیب چند قاعده، ترتیب و مقدار نهایی را بخوانید. نام Keyframes تکراری در محدوده عمومی ممکن است رفتار را عوض کند. سبک‌ها را با محدوده و نام روشن نگه دارید. اگر نمونه بعدی فقط CSS را تغییر می‌دهد، باید بگوید همان HTML قبلی استفاده می‌شود. Selector تازه بدون Markup متناظر آموزش کامل نیست.

حرکت را با محتوای واقعی بسنجید: متن بلند، پنل کوچک و دستگاه متفاوت ممکن است محدودیت را آشکار کنند. این مقاله دستور اجرای تست روی سایت شما نیست و ادعای آن را ندارد. برای طراحی، راهنمای Mobile First به نیاز صفحه کوچک کمک می‌کند. انتخاب نهایی باید تغییر را روشن کند، امکان انجام کار را حفظ کند و بار غیرضروری بر توجه کاربر نگذارد.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!