انیمیشن فوکوس با View Transitions
خلاصهٔ کاملتر
ایده اصلی این مقاله اینه که وقتی کاربر روی کیبورد Tab میزنه و فوکوس بین المانهای صفحه جابهجا میشه، بهجای اینکه حلقه فوکوس یهدفعه ناپدید و دوباره پدیدار بشه، بهصورت انیمیشن از یه المان به المان دیگه «پرواز» کنه. نویسنده خودش هم صادقانه میگه این ایده احتمالاً ضروری نیست و حرکت اضافهای به صفحه اضافه میکنه — ولی سایت WebAIM (که کاملاً درباره دسترسپذیری وب هست) دقیقاً همین کار رو انجام داده و اسمش رو گذاشته «focus trace» یا «flying focus».
رویکردهای قدیمیتر مثل کار Ben Nadel از getBoundingClientRect در جاوااسکریپت استفاده میکردن: موقعیت و ابعاد المان فوکوسشده رو اندازه میگرفتن و بعد بین مقادیر جدید انیمیت میکردن. این روش از نظر پرفورمنس چندان ایدهآل نیست. Chris Coyier بهجاش سراغ View Transitions API رفته — ابزاری که بهت میده تغییرات DOM رو با انیمیشنهای روان همراه کنی.
منطق کار سادهست: اگه یه المان view-transition-name داشته باشه، و داخل startViewTransition() اون المان جابهجا یا تغییر کنه، مرورگر خودش انیمیشن tween بین حالت قبل و بعد رو میسازه. پس کافیه داخل تابع View Transition فقط .focus() رو روی المان بعدی صدا بزنیم تا همه چیز جادویی کار کنه. برای این کار نویسنده کلید Tab رو هایجک میکنه:
document.addEventListener('keydown', (e) => {
if (e.key !== 'Tab') return;
if (!document.startViewTransition) return; // graceful fallback
const focusables = [...document.querySelectorAll(
'a[href], button:not([disabled]), input:not([disabled]), ...'
)].filter(el => el.offsetParent !== null);
const i = focusables.indexOf(document.activeElement);
if (i === -1) return;
e.preventDefault();
const dir = e.shiftKey ? -1 : 1;
const next = focusables[(i + dir + focusables.length) % focusables.length];
document.startViewTransition(() => next.focus());
});یه چالش اینه که وقتی انیمیشن رو کُند میکنیم، یه cross-fade عجیب دیده میشه — محتوای داخل المان هم انیمیت میشه که خواسته نیست. نویسنده با CSS مثل ::view-transition-group(focus-ring) میتونه مدت انیمیشن رو کنترل کنه، ولی اذعان میکنه که حل کامل این مشکل بصری هنوز پیدا نشده و ایدههایی مثل جعلی کردن outline یا تیره کردن وسط رو بررسی میکنه.
نکات کلیدی:
- هدف: انیمیت کردن حلقه فوکوس بین المانها با افکت پرواز بهجای ظاهر شدن ناگهانی
- ابزار: View Transitions API با
startViewTransition()وview-transition-name - محدودیت: فقط Tab رو پوشش میده، نه همه روشهای فوکوس
- نکته دسترسپذیری: رعایت
prefers-reduced-motionبرای کاربرانی که حرکت کمتر ترجیح میدن ضروریه - مشکل بصری: cross-fade روی محتوای داخل المان هنوز راهحل کاملی نداره




