افکت پارالکس فقط با CSS و بدون جاوااسکریپت
خلاصهٔ کاملتر
مقاله دربارهی یه روش تازه برای ساختن افکت پارالکس هست؛ همون افکتی که توش عناصر پسزمینه با سرعت متفاوتی نسبت به محتوای جلویی حرکت میکنن و حس عمق میسازن. روش سنتی همیشه این بود که یه لیسنر رویداد اسکرول توی JavaScript بذاری و هر فریم موقعیتها رو دوباره حساب کنی و عنصر رو بالا و پایین کنی.
نکتهی اصلی اینه که حالا با تایملاینهای انیمیشن اسکرولمحور (scroll-driven animation) در CSS میشه کل این کار رو بهصورت اعلانی (declarative) انجام داد. دو تا مزیت داره: پرفورمنس بهتر، چون خارج از ترد اصلی اجرا میشه؛ و سادگی، چون کل افکت به یه بلوک کوچیک استایل تبدیل میشه که با یه کلاس روی عنصر اعمال میشه.
قلب ماجرا اتریبیوت view-timeline-name هست. این یه view progress timeline میسازه؛ تایملاینی که پیشرفتش با میزان عبور عنصر از داخل ویوپورت اندازهگیری میشه — لحظهای که عنصر شروع به وارد شدن میکنه ۰٪ و وقتی کامل خارج شد ۱۰۰٪. با view-timeline-axis: block هم بهش میگی حرکت رو روی محور عمودی دنبال کنه. بعد روی فرزند، animation-timeline ساعت انیمیشن رو از زمان به این تایملاین سوییچ میکنه:
.parallax > * {
animation: parallax auto linear both;
animation-timeline: --parallax-tl;
animation-range: cover;
}نویسنده تأکید میکنه که animation-timeline بخشی از شورتهند animation نیست و باید جدا و بعد از شورتهند تعریف شه، وگرنه شورتهند مقدارش رو ریست میکنه. توی کیفریمها هم فرزند با آفست پیشفرض از translate: 0 -20% به translate: 0 20% سُر میخوره و چون با نرخ متفاوتی از ظرف اطرافش حرکت میکنه، حس عمق به وجود میاد.
یه ظرافت مهم، اسکیل کردن برای جلوگیری از فضای خالیه. چون فرزند به اندازهی درصد آفست از ارتفاع خودش جابهجا میشه، اگه دقیقاً هماندازهی ظرفش باشه موقع جابهجایی یه نوار خالی لو میره. راهحل اینه که فرزند رو بزرگتر کنی تا حاشیه برای حرکت داشته باشه — به اندازهی دو برابر آفست. نکتهی شیک اینه که هم translate و هم scale از یه متغیر واحد به اسم --parallax-offset میخونن، پس فقط یه مقدار رو تنظیم میکنی و فضای خالی هیچوقت برنمیگرده:
scale: calc(1 + var(--parallax-offset, 20) * 2 / 100);با آفست پیشفرض ۲۰، فرزند با ۱۴۰٪ اندازه رندر میشه و اضافهاش با overflow: hidden روی ظرف بریده میشه. will-change: translate هم به مرورگر هشدار میده که این عنصر قراره جابهجا شه تا از قبل به یه لایهی جدا منتقلش کنه. در آخر، چون پارالکس حرکت گرهخورده به اسکروله و بعضیها ترجیح میدن نباشه، نویسنده توصیه میکنه با prefers-reduced-motion: reduce انیمیشن و اسکیل رو خاموش کنی.
نکات کلیدی:
- پارالکس سنتی به لیسنر اسکرول و محاسبهی هر فریم در JS نیاز داشت
- انیمیشن اسکرولمحور CSS همون کار رو اعلانی و خارج از ترد اصلی انجام میده
- view-timeline-name یه تایملاین میسازه که با عبور عنصر از ویوپورت پیش میره
- animation-timeline باید جدا و بعد از شورتهند animation تعریف شه
- اسکیل کردن فرزند جلوی فضای خالی رو میگیره و prefers-reduced-motion رو رعایت کن




