کوچک شدن سرصفحه هنگام پیمایش کردن

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

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

نحوه ایجاد سرصفحه کوچک‌شونده هنگام پیمایش:

  1. ایجاد سرصفحه ثابت: با عنصر سرصفحه‌ای شروع کنید که در بالای صفحه ثابت است و ارتفاع ازپیش تعریف‌شده‌ای دارد.

    <header>HEADER</header>
    
    header {
      position: fixed;
      height: 200px;
      top: 0;
      left: 0;
      right: 0;
    }
    
  2. پویانمایی کوچک شدن را تعریف کنید: پویانمایی CSS ایجاد کنید که ارتفاع سرایند را تغییر دهد.

    @keyframes shrink {
      to {
        height: 50px;
      }
    }
    
  3. اعمال کردن پویانمایی و خط زمان پیمایش: پویانمایی را به سرایند پیوست کنید و از تابع scroll() برای پیوند دادن آن به موقعیت پیمایش سند استفاده کنید.

    header {
      animation: shrink auto linear both;
      animation-timeline: scroll(block root);
    }
    
  4. تنظیم کردن animation-range: از ویژگی animation-range برای مشخص کردن فاصله پیمایش که پویانمایی باید در آن رخ دهد استفاده کنید. برای مثال، برای کوچک کردن سرصفحه در ۱۵۰ پیکسل اول پیمایش، از animation-range: 0px 150px; استفاده می‌کنید.

    header {
      animation-range: 0px 150px;
    }
    

نکته: برای جلوگیری از پنهان شدن محتوای پس‌از سرایند توسط آن، یک padding-top به body (یا محفظه محتوای اصلی) اضافه کنید که برابر با ارتفاع اولیه سرایند باشد.

نکته: برای اطمینان از اینکه محتوای صفحه هم‌زمان با کوچک شدن سرصفحه پیمایش می‌شود، animation-range-end را روی تفاوت بین اندازه شروع و پایان تنظیم کنید. این کار تضمین می‌کند که پویانمایی دقیقاً زمانی تکمیل شود که سرصفحه به اندازه نهایی خود می‌رسد. در این نسخه نمایشی، سرصفحه از 200px به 50px کوچک می‌شود، بنابراین animation-range-end روی 150px تنظیم شده است.

کد نمونه

@keyframes shrink {
  to {
    height: 50px;
  }
}

header {
  animation: shrink auto linear both;
  animation-timeline: scroll(block root);
  animation-range: 0px 150px;
}

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

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

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

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

  • اختیاری درباره پیمایشگر صریح باشید: وقتی نزدیک‌ترین پیمایشگر جد را هدف قرار نمی‌دهید، درباره اینکه می‌خواهید از کدام پیمایشگر با scroll(root) یا scroll(self) استفاده کنید صریح باشید.
    • وقتی root، nearest، یا self کافی نیستند، از scroll-timeline نام‌گذاری‌شده استفاده کنید.
  • اختیاری به‌طور صریح محور موردنظر برای ردیابی را مشخص کنید: وقتی محور پیش‌فرض block را هدف قرار نمی‌دهید (مثلاً در پیمایشگر افقی)، به‌طور صریح مشخص کنید که کدام محور باید با scroll(block) یا scroll(inline) ردیابی شود.

به‌طور خاص برای این مورد استفاده:

  • عنصری که پویانمایی می‌کنید نباید position: static یا position: relative باشد، وقتی‌که از درصد در animation-range استفاده می‌کنید.
    • دلیلش این است که این عناصر «در جریان» درنظر گرفته می‌شوند. کوچک کردن این عناصر هنگام پیمایش، کل فاصله پیمایش را کاهش می‌دهد و درنتیجه بر مقدار محاسبه‌شده (برای مثال) 10% در پیمایش تأثیر می‌گذارد.

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

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

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

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

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

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

// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: scroll()) and (animation-range: 0% 100%)')) {
  const header = document.querySelector('header');

  const initialHeight = 200;
  const finalHeight = 50;
  const scrollDistance = 150;

  window.addEventListener('scroll', () => {
    const scrollY = window.scrollY;
    const scrollPercent = Math.min(1, scrollY / scrollDistance);
    const newHeight = initialHeight - (initialHeight - finalHeight) * scrollPercent;

    header.style.height = `${newHeight}px`;
  });
}