اسکرول به خوبی کنترل شده با CSS Scroll Snap

با تعریف موقعیت‌های اسکرول اسنپ، تجربه‌های اسکرول کنترل‌شده‌ای ایجاد کنید.

ویژگی Scroll Snap در CSS به توسعه‌دهندگان وب این امکان را می‌دهد که با تعریف موقعیت‌های اسکرول اسنپ، تجربه‌های اسکرول کنترل‌شده‌ای ایجاد کنند. مقالات صفحه‌بندی‌شده و تصاویر چرخان دو نمونه رایج از این مورد هستند. CSS Scroll Snap یک API با کاربرد آسان و سازگار برای ساخت این الگوهای UX محبوب ارائه می‌دهد.

پیشینه

موردی برای اسکرول اسنپینگ

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

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

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

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

مثالی از استفاده از اسکرول اسنپ در CSS به همراه یک تصویر چرخان.
مثالی از استفاده از scroll snap در css با یک تصویر چرخشی. در اینجا scroll snapping تضمین می‌کند که در پایان پیمایش، مرکز افقی تصویر با مرکز افقی ظرف پیمایش هم‌تراز باشد.

اسکرول اسنپ در CSS

ضربه زدن به اسکرول، عمل تنظیم جابجایی اسکرول یک ظرف اسکرول برای قرار گرفتن در موقعیت ضربه زدن دلخواه پس از اتمام عملیات اسکرول است.

یک ظرف اسکرول را می‌توان با استفاده از ویژگی scroll-snap-type به حالت snapping اسکرول درآورد. این به مرورگر می‌گوید که باید snap کردن این ظرف اسکرول را به موقعیت‌های snap تولید شده توسط فرزندانش در نظر بگیرد. scroll-snap-type محوری را که اسکرول روی آن اتفاق می‌افتد تعیین می‌کند: x ، y یا both ، و strictness snapping: mandatory ، proximity . بعداً در مورد این موارد بیشتر صحبت خواهیم کرد.

با تعریف یک تراز دلخواه برای یک عنصر، می‌توان یک موقعیت snap ایجاد کرد. این موقعیت، فاصله‌ی اسکرول است که در آن نزدیکترین محفظه‌ی اسکرول والد و عنصر مطابق با محور داده شده تراز می‌شوند. ترازبندی‌های زیر در هر محور امکان‌پذیر است: start ، end ، center .

ترازبندی start به این معنی است که لبه شروع snapport ظرف اسکرول باید با لبه شروع snap area عنصر هم‌تراز باشد. به طور مشابه، ترازبندی‌های end و center به این معنی است که لبه پایان یا مرکز snapport ظرف اسکرول باید با لبه پایان یا مرکز snap area عنصر هم‌تراز باشد.

مثالی از ترازبندی‌های مختلف روی محور اسکرول افقی.

مثال‌های زیر نحوه‌ی استفاده از این مفاهیم را نشان می‌دهند.

یک مورد استفاده رایج برای اسکرول اسنپ، یک چرخ فلک تصویر است. برای مثال، برای ایجاد یک چرخ فلک تصویر افقی که هنگام اسکرول کردن به هر تصویر می‌چسبد، می‌توانیم کانتینر اسکرول را طوری تعیین کنیم که دارای یک scroll-snap-type اجباری در محور افقی باشد. هر تصویر را روی scroll-snap-align: center تنظیم کنید تا مطمئن شوید که اسنپ کردن، تصویر را در مرکز چرخ فلک قرار می‌دهد.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gal>ler<y"
  img src>=&q<uot;cat.jpg">
  <img src="dog.jpg"
  img> <src=>&quot;another_cute_animal.jpg"
/div

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

مثال: صفحه محصول سفر کرده

یکی دیگر از موارد رایج که می‌تواند از قابلیت scroll snapping بهره‌مند شود، صفحاتی با چندین بخش منطقی برای پیمایش عمودی است، به عنوان مثال، یک صفحه محصول معمولی. scroll-snap-type: y proximity; برای مواردی از این دست مناسب‌تر است. این قابلیت وقتی کاربر به وسط یک بخش خاص پیمایش می‌کند، مزاحمتی ایجاد نمی‌کند، بلکه وقتی به اندازه کافی نزدیک می‌شود، به بخش جدیدی توجه می‌کند.

در اینجا نحوه دستیابی به این هدف آورده شده است:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

پیمایش پدینگ و حاشیه

صفحه محصول دارای یک هدر بالایی با موقعیت ثابت است. همچنین در طراحی خواسته شده است که هنگام باز شدن اسکرول، بخشی از بخش بالایی قابل مشاهده باقی بماند تا به کاربران در مورد محتوای بالا، سرنخ طراحی ارائه دهد.

ویژگی scroll-padding یک ویژگی جدید css است که می‌تواند برای تنظیم ناحیه قابل مشاهده مؤثر ظرف اسکرول یا snapport استفاده شود، که هنگام محاسبه ترازبندی‌های snap اسکرول استفاده می‌شود. این ویژگی یک inset در برابر کادر padding ظرف اسکرول تعریف می‌کند. در مثال ما، inset اضافی 15vh به بالا اضافه شده است که به مرورگر دستور می‌دهد موقعیت پایین‌تری، 15vh پایین‌تر از لبه بالایی ظرف اسکرول، را به عنوان لبه شروع عمودی خود برای snap کردن اسکرول در نظر بگیرد. هنگام snap کردن، لبه شروع عنصر هدف snap با این موقعیت جدید هم‌تراز می‌شود و در نتیجه فضای بالایی باقی می‌ماند.

ویژگی scroll-margin مقدار اولیه مورد استفاده برای تنظیم کادر مؤثر snap target را مشابه نحوه عملکرد scroll-padding در محفظه پیمایش snap تعریف می‌کند.

شاید متوجه شده باشید که این دو ویژگی کلمه " snap " را در خود ندارند. این کار عمدی است زیرا آنها در واقع کادر را برای همه عملیات پیمایش مربوطه تغییر می‌دهند و فقط عمل جابجایی پیمایش را انجام نمی‌دهند. برای مثال، کروم هنگام محاسبه اندازه صفحه برای عملیات پیمایش صفحه‌بندی مانند PageDown و PageUp و همچنین هنگام محاسبه مقدار پیمایش برای عملیات Element.scrollIntoView() آنها را در نظر می‌گیرد.

تعامل با سایر APIهای پیمایش

API اسکرول DOM

عمل snapping اسکرول بعد از تمام عملیات اسکرول، از جمله آنهایی که توسط اسکریپت آغاز می‌شوند، اتفاق می‌افتد. وقتی از APIهایی مانند Element.scrollTo استفاده می‌کنید، مرورگر موقعیت اسکرول مورد نظر برای عملیات را محاسبه می‌کند، سپس منطق snapping مناسب را برای یافتن مکان نهایی snapped اعمال می‌کند. بنابراین، نیازی نیست که اسکریپت کاربر محاسبات دستی برای snapping انجام دهد.

پیمایش روان

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

رفتار پیمایش بیش از حد

API رفتار Overscroll نحوه‌ی زنجیروار اسکرول کردن بین عناصر مختلف را کنترل می‌کند و تحت تأثیر scroll snap قرار نمی‌گیرد.

هشدارها و بهترین شیوه‌ها

از استفاده از snapping اجباری زمانی که عناصر هدف فاصله زیادی از هم دارند، خودداری کنید. این کار می‌تواند باعث شود محتوای بین موقعیت‌های snap غیرقابل دسترس شود.

در بسیاری از موارد، scroll-snapping می‌تواند به عنوان یک بهبود و بدون نیاز به تشخیص ویژگی اضافه شود. در صورت نیاز، @supports یا CSS.supports برای تشخیص پشتیبانی از CSS Scroll Snap استفاده کنید. از استفاده از scroll-snap-type که در مشخصات منسوخ شده نیز وجود دارد، خودداری کنید.

تشخیص ویژگی در CSS

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

تشخیص ویژگی در جاوا اسکریپت

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

فرض نکنید که APIهای اسکرول کردن برنامه‌نویسی‌شده مانند Element.scrollTo همیشه در آفست اسکرول درخواستی به پایان می‌رسند. اسکرول اسنپینگ ممکن است آفست اسکرول را پس از اتمام اسکرول کردن برنامه‌نویسی‌شده تنظیم کند. توجه داشته باشید که این فرض حتی قبل از اسکرول اسنپینگ هم خوب نبود، زیرا ممکن بود اسکرول کردن به دلایل دیگری قطع شود، اما این موضوع به ویژه در مورد اسکرول اسنپینگ صادق است.

کارهای آینده

تجربه اسکرول کردن، موضوع اصلی یک نظرسنجی اخیر توسط تیم کروم بود. نتایج این نظرسنجی، چندین حوزه را شناسایی کرد که برای کاهش شکاف بین کتابخانه‌های افزونه و CSS نیاز به کار بیشتر دارند. کارهای آینده بر روی scroll-snap تمرکز خواهد داشت، از جمله:

  1. در دسترس بودن API و سازگاری با مرورگرهای مختلف.
  2. روی APIهای جدید CSS مانند scroll-start کار کنید.
  3. روی رویدادهای جدید جاوااسکریپت مانند snapChanged() کار کنید.