افزودن جلوه‌های ورود و خروج به عناصر هنگام ورود یا خروج از درگاه پیمایش

جلوه‌های ورود و خروج پویانمایی‌هایی هستند که وقتی عنصری وارد نمای هدف می‌شود یا آن را ترک می‌کند راه‌اندازی می‌شوند. از این ویژگی می‌توان برای ایجاد تجربه‌های کاربری جذاب و پویا استفاده کرد. برای مثال، می‌توانید از جلوه ورودی برای محو کردن عنصر هنگام پیمایش به نمای دید، یا از جلوه خروجی برای کوچک کردن آن هنگام پیمایش به خارج از نمای دید استفاده کنید.

نحوه پیاده‌سازی

برای افزودن جلوه‌های ورود و خروج به یک عنصر، باید چند خصوصیت CSS را ترکیب کنید. در اینجا راهنمای گام‌به‌گام آورده شده است:

  1. @keyframes جداگانه‌ای برای پویانمایی‌های ورود و خروج ایجاد کنید. پویانمایی ورودی زمانی اعمال می‌شود که عنصر وارد نمای دید شود و پویانمایی خروجی زمانی اعمال می‌شود که عنصر از نمای دید خارج شود.

    @keyframes slide-in {
      from { transform: translateX(-100%); }
    }
    @keyframes slide-out {
      to { transform: translateX(100%); }
    }
    
  2. قاب‌های کلیدی ورودی و خروجی را به عنصر پیوست کنید. می‌توانید این کار را با تعریف چند پویانمایی در ویژگی animation انجام دهید.

    • به پویانمایی ورودی یک animation-fill-mode از backwards بدهید تا حالت اولیه خود را قبل‌از شروع پویانمایی اعمال کند.
    • به پویانمایی خروج animation-fill-mode از forwards بدهید تا پس‌از تکمیل پویانمایی، حالت نهایی خود را حفظ کند.
    .animated-element {
      animation:
        slide-in 1s linear backwards,
        slide-out 1s linear forwards;
    }
    
  3. یک View Timeline ایجاد کنید و آن را به پویانمایی‌ها پیوند دهید. «خط زمان نما» نوعی خط زمان است که به رؤیت‌پذیری عنصری در ناحیه نمایش پیوند داده شده است. می‌توانید بااستفاده از تابع view() یکی ایجاد کنید و سپس بااستفاده از ویژگی animation-timeline آن را در پویانمایی‌هایتان اعمال کنید.

    .animated-element {
      animation-timeline: view();
    }
    

    به‌طور پیش‌فرض، view() عنصر را در محور block ردیابی می‌کند. اگر لازم است آن را در محور inline ردیابی کنید، می‌توانید از view(inline) استفاده کنید.

  4. پویانمایی‌ها را به محدوده‌های entry و exit محدود کنید. ویژگی animation-range به شما امکان می‌دهد مشخص کنید پویانمایی باید در کدام بخش از خط زمان اجرا شود.

    • محدوده entry زمان بین اولین ورود عنصر به ناحیه نمایش تا زمانی که کاملاً نمایان می‌شود را پوشش می‌دهد.
    • محدوده exit زمان شروع خروج عنصر از نمای هدف تا پنهان شدن کامل آن را پوشش می‌دهد.
    .animated-element {
      animation-range: entry, exit;
    }
    

کد نمونه

این کد فرزندان مستقیم پیمایشگر را هنگام پیمایش بااستفاده از خط زمان نمای ناشناس پویانمایی می‌کند:

@media (prefers-reduced-motion: no-preference) {
  @supports ((animation-timeline: view()) and (animation-range: entry)) {
    @keyframes grow {
      from {
        scale: 0.5;
      }
    }
    @keyframes shrink {
      to {
        scale: 0.5;
      }
    }

    .scroller > * {
      animation:
        grow auto linear backwards,
        shrink auto linear forwards;
      animation-timeline: view(inline);
      animation-range: entry, exit;
    }
  }
}

As the elements enter the scrollport the grow animation is played, and as they leave the scrollport the shrink animation is played.

کد زیر همان نتیجه بصری را دارد، اما فرزندان مستقیم پیمایشگر را هنگام پیمایش بااستفاده از named view-timeline پویانمایی می‌کند:

@media (prefers-reduced-motion: no-preference) {
  @supports ((animation-timeline: view()) and (animation-range: entry)) {
    @keyframes grow {
      from {
        scale: 0.5;
      }
    }
    @keyframes shrink {
      to {
        scale: 0.5;
      }
    }

    .scroller > * {
      view-timeline: --tl inline;
      animation:
        grow auto linear backwards,
        shrink auto linear forwards;
      animation-timeline: --tl;
      animation-range: entry, exit;
    }
  }
}

روال‌های مطلوب

هنگام استفاده از پویانمایی‌های پیمایش‌محور، مهم است که چند روال مطلوب را دنبال کنید تا تجربه‌ای روان و دسترس‌پذیر را تضمین کنید:

  • باید تشخیص ویژگی را اضافه کنید: همه مرورگرها از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند. از @supports ((animation-timeline: view()) and (animation-range: entry)) برای بررسی پشتیبانی و ارائه بازگشت به روش پیش‌فرض برای مرورگرهایی که از آن پشتیبانی نمی‌کنند استفاده کنید.
    • بررسی (animation-range: entry) باید در اینجا گنجانده شود تا مرورگرهایی که فقط پشتیبانی جزئی دارند فیلتر شوند.
    • از بسته scroll-timeline-polyfill برای راهبرد جایگزین استفاده نکنید زیرا ویژگی‌های آن کامل نیست و مشکلات شناخته‌شده زیادی دارد.
    • اگر پویانمایی فقط تزئینی درنظر گرفته می‌شود، «ارتقای پیش‌رو» را انتخاب کنید و گزینه جایگزین ارائه ندهید.
  • باید به اولویت‌های کاربر احترام بگذارید: برخی‌از کاربران ترجیح می‌دهند حرکت کمتری در وب داشته باشند. از پُرسمان رسانه prefers-reduced-motion برای غیرفعال کردن یا کاهش پویانمایی‌ها برای این کاربران استفاده کنید.
  • باید سعی کنید فقط دارایی‌های CSS کارا را پویانمایی کنید: برای داشتن روان‌ترین پویانمایی‌ها، فقط دارایی‌هایی را پویانمایی کنید که رشته ترکیب‌کننده مرورگر می‌تواند آن‌ها را مدیریت کند، مثل transform و opacity. پویانمایی کردن ویژگی‌های دیگر مثل width یا height می‌تواند به مشکلات عملکردی منجر شود.
  • باید از ترتیب صحیح اعلام استفاده کنید: هنگام استفاده از ویژگی خلاصه animation، animation-timeline را بعداز آن اعلام کنید تا از بازنشانی خط زمان توسط خلاصه جلوگیری شود.

هنگام استفاده از تابع view() برای ایجاد پویانمایی پیمایش‌محور:

  • اختیاری به‌طور صریح محور موردنظر برای ردیابی را مشخص کنید: وقتی محور پیش‌فرض block را هدف قرار نمی‌دهید (مثلاً در پیمایشگر افقی)، به‌طور صریح مشخص کنید که کدام محور باید با view(block) یا view(inline) ردیابی شود.
  • وقتی پویانمایی روی خود سوژه ردیابی‌شده اعمال نمی‌شود، از خط زمان نمای نام‌گذاری‌شده استفاده کنید.

هنگام استفاده از ویژگی view-timeline برای ایجاد پویانمایی پیمایش‌محور:

  • باید از CSS <dashed-ident> برای نام استفاده کنید.
  • اختیاری محور موردنظر برای ردیابی را به‌طور صریح مشخص کنید: وقتی محور پیش‌فرض block را هدف قرار نمی‌دهید (مثلاً در پیمایشگر افقی)، به‌طور صریح مشخص کنید که کدام محور با view-timeline-axis ردیابی شود.
  • باید مطمئن شوید که دامنه جستجو کار می‌کند: وقتی عنصری که view-timeline را اعلام می‌کند، جد درخت مسطح عنصر پویانمایی‌شده نیست، بااستفاده از timeline-scope در جد مشترک، نمایان بودن نام view-timeline را بالا ببرید.

وقتی چند عنصر یا فرزند سوژه ردیابی‌شده باید پویانمایی شوند، view-timeline نام‌گذاری‌شده را ترجیح دهید.

پشتیبانی مرورگر و راهبردهای جایگزین

بنابراین، معمولاً به یک استراتژی جایگزین نیاز است.

برای مرورگرهایی که از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند، می‌توانید از یک جایگزین برای بازآفرینی جلوه‌های دیداری استفاده کنید. جایگزین‌ها معمولاً با شنونده پیمایش (برای جلوه‌های ScrollTimeline) یا IntersectionObserver API (برای جلوه‌های ViewTimeline) ساخته می‌شوند.

در مرورگرهایی که پشتیبانی داخلی از پویانمایی‌های پیمایش‌محور دارند، همیشه از پیاده‌سازی CSS بومی استفاده کنید زیرا عملکرد بهتری دارند.

توجه داشته باشید که همه جلوه‌ها را نمی‌توان بااستفاده از رویکرد جایگزین بازآفرینی کرد.

به‌طور خاص برای این مورد استفاده، دستورگان زیر برای مرورگرهایی که از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند، جایگزین را اعمال می‌کند. این کد از IntersectionObserver برای ردیابی رؤیت‌پذیری عنصر .wrapper استفاده می‌کند و ویژگی transform لایه‌ها را براساس موقعیت پیمایش به‌روز می‌کند.

<script>
  if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
    const observer = new IntersectionObserver(
      (entries) => {
        for (const entry of entries) {
          // This matches the effect as defined in the CSS example above.
          // Customize this further if needed.
          entry.target.style.scale = 0.5 + entry.intersectionRatio * 0.5;
        }
      },
      {
        threshold: Array.from({ length: 101 }, (_, i) => i / 100),
      }
    );

    document.querySelectorAll('.scroller > *').forEach((el) => {
      observer.observe(el);
    });
  }
</script>