CSS Scroll Snap के साथ अच्छी तरह से नियंत्रित स्क्रोलिंग

स्क्रोल स्नैपिंग की पोज़िशन तय करके, स्क्रोल करने के बेहतर अनुभव बनाएं.

सीएसएस स्क्रोल स्नैप सुविधा की मदद से, वेब डेवलपर स्क्रोल स्नैपिंग की पोज़िशन तय करके, स्क्रोल करने के बेहतर अनुभव बना सकते हैं. पेज नंबर वाले लेख और इमेज कैरसेल, इसके दो सामान्य उदाहरण हैं. CSS स्क्रोल स्नैप, इन लोकप्रिय यूज़र एक्सपीरियंस पैटर्न को बनाने के लिए, इस्तेमाल में आसान और एक जैसा एपीआई उपलब्ध कराता है.

बैकग्राउंड

स्क्रोल स्नैपिंग के लिए केस

स्क्रोल करना, वेब पर कॉन्टेंट से इंटरैक्ट करने का एक लोकप्रिय और सामान्य तरीका है. यह प्लैटफ़ॉर्म का नेटिव तरीका है. इससे स्क्रीन पर एक बार में दिखने वाली जानकारी से ज़्यादा जानकारी ऐक्सेस की जा सकती है. यह मोबाइल प्लैटफ़ॉर्म पर खास तौर पर ज़रूरी हो जाता है, क्योंकि यहां स्क्रीन का साइज़ सीमित होता है. इसलिए, इसमें कोई हैरानी नहीं है कि वेब ऑथर, डीप हैरारकी के बजाय स्क्रोल की जा सकने वाली फ़्लैट सूचियों में कॉन्टेंट को व्यवस्थित करना ज़्यादा पसंद करते हैं.

स्क्रोल करने की मुख्य कमी यह है कि इसमें सटीक जानकारी नहीं मिलती. ऐसा बहुत कम होता है कि स्क्रोलिंग किसी पैराग्राफ़ या वाक्य के साथ अलाइन हो. पेज पर नंबर डाले गए कॉन्टेंट या आइटम के हिसाब से व्यवस्थित किए गए कॉन्टेंट के लिए, यह समस्या और भी ज़्यादा गंभीर हो जाती है. ऐसा तब होता है, जब स्क्रोलिंग पेज या इमेज के बीच में खत्म हो जाती है और वह कुछ हद तक दिखती रहती है. इन मामलों में, स्क्रोलिंग को कंट्रोल करने की सुविधा का इस्तेमाल किया जा सकता है.

वेब डेवलपर लंबे समय से, स्क्रोल को कंट्रोल करने के लिए JavaScript पर आधारित समाधानों का इस्तेमाल कर रहे हैं, ताकि इस कमी को दूर किया जा सके. हालांकि, JavaScript पर आधारित समाधान, पूरी तरह से सटीक समाधान नहीं दे पाते. इसकी वजह यह है कि उनमें स्क्रोल करने की सुविधा को पसंद के मुताबिक बनाने के लिए प्रिमिटिव या कंपोज़िट स्क्रोलिंग का ऐक्सेस नहीं होता. सीएसएस स्क्रोल स्नैप, तेज़, भरोसेमंद, और इस्तेमाल में आसान समाधान उपलब्ध कराता है. यह सभी ब्राउज़र पर एक जैसा काम करता है.

सीएसएस स्क्रोल स्नैप की मदद से, वेब ऑथर हर स्क्रोल कंटेनर को स्क्रोल ऑपरेशन के लिए सीमाओं के साथ मार्क कर सकते हैं. इसके बाद, ब्राउज़र स्क्रोल करने की कार्रवाई, स्क्रोल कंटेनर के लेआउट और दिखने की स्थिति, और स्नैप पोज़िशन की जानकारी के आधार पर, सबसे सही एंड पोज़िशन चुनते हैं. इसके बाद, वे उस पोज़िशन पर आसानी से ऐनिमेशन करते हैं. हमारे पिछले उदाहरण पर वापस जाएं. जब उपयोगकर्ता कैरसेल को स्क्रोल करना बंद कर देता है, तो दिखने वाली इमेज अपनी जगह पर आ जाती है. JavaScript को स्क्रोल में कोई बदलाव करने की ज़रूरत नहीं होती.

इमेज कैरसेल के साथ सीएसएस स्क्रोल स्नैप का इस्तेमाल करने का उदाहरण.
इमेज कैरसेल के साथ css स्क्रोल स्नैप का इस्तेमाल करने का उदाहरण. यहां स्क्रोल स्नैपिंग यह पक्का करती है कि स्क्रोल करने के आखिर में, इमेज का हॉरिज़ॉन्टल सेंटर, स्क्रोल कंटेनर के हॉरिज़ॉन्टल सेंटर के साथ अलाइन हो.

CSS Scroll Snap

स्क्रोल स्नैपिंग, स्क्रोल कंटेनर के स्क्रोल ऑफ़सेट को अडजस्ट करने की प्रोसेस है. इससे स्क्रोल करने की प्रोसेस पूरी होने के बाद, स्क्रोल कंटेनर को पसंदीदा स्नैप पोज़िशन पर सेट किया जा सकता है.

scroll-snap-type प्रॉपर्टी का इस्तेमाल करके, स्क्रोल कंटेनर को स्क्रोल स्नैपिंग के लिए ऑप्ट-इन किया जा सकता है. इससे ब्राउज़र को पता चलता है कि उसे इस स्क्रोल कंटेनर को, इसके डिसेंडेंट से जनरेट हुई स्नैप पोज़िशन पर स्नैप करना चाहिए. scroll-snap-type इससे यह तय होता है कि स्क्रोलिंग किस ऐक्सिस पर होगी: x, y या both. साथ ही, स्नैपिंग कितनी सख्त होगी: mandatory, proximity. इनके बारे में ज़्यादा जानकारी बाद में दी जाएगी.

किसी एलिमेंट पर मनचाहा अलाइनमेंट सेट करके, स्नैप पोज़िशन बनाई जा सकती है. यह पोज़िशन, स्क्रोल ऑफ़सेट होती है. इस पर, सबसे नज़दीकी पैरंट स्क्रोल कंटेनर और एलिमेंट, दिए गए ऐक्सिस के लिए तय किए गए अलाइनमेंट के मुताबिक अलाइन होते हैं. हर ऐक्सिस पर ये अलाइनमेंट किए जा सकते हैं: start, end, center.

start अलाइनमेंट का मतलब है कि स्क्रोल कंटेनर के स्नैप पोर्ट का शुरुआती किनारा, एलिमेंट के स्नैप एरिया के शुरुआती किनारे के साथ फ़्लश होना चाहिए. इसी तरह, end और center अलाइनमेंट का मतलब है कि स्क्रोल कंटेनर के स्नैपपोर्ट के आखिरी किनारे या बीच के हिस्से को एलिमेंट के स्नैप एरिया के आखिरी किनारे या बीच के हिस्से के साथ अलाइन किया जाना चाहिए.

हॉरिज़ॉन्टल स्क्रोलिंग ऐक्सिस पर अलग-अलग अलाइनमेंट का उदाहरण.

यहां दिए गए उदाहरणों में, इन सिद्धांतों का इस्तेमाल करने का तरीका बताया गया है.

स्क्रोल स्नैपिंग का इस्तेमाल आम तौर पर इमेज कैरसेल के लिए किया जाता है. उदाहरण के लिए, अगर आपको हॉरिज़ॉन्टल इमेज कैरसेल बनाना है, जिसमें स्क्रोल करने पर हर इमेज स्नैप होती है, तो हम स्क्रोल कंटेनर को हॉरिज़ॉन्टल ऐक्सिस पर 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="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

स्नैप पोज़िशन किसी एलिमेंट से जुड़ी होती हैं. इसलिए, स्नैपिंग एल्गोरिदम यह तय कर सकता है कि एलिमेंट और स्क्रोल कंटेनर के साइज़ के हिसाब से, कब और कैसे स्नैप करना है. उदाहरण के लिए, मान लें कि कोई इमेज कैरसेल से बड़ी है. स्नैपिंग के लिए इस्तेमाल किया जाने वाला सामान्य एल्गोरिदम, उपयोगकर्ता को पूरी इमेज देखने के लिए पैन करने से रोक सकता है. हालांकि, स्पेसिफ़िकेशन के मुताबिक, इस स्थिति का पता लगाने के लिए लागू करने की ज़रूरत होती है. साथ ही, उपयोगकर्ता को उस इमेज में स्वतंत्र रूप से स्क्रोल करने की अनुमति देनी होती है. ऐसा करने पर, इमेज के किनारों पर ही स्नैप किया जा सकेगा.

उदाहरण: प्रॉडक्ट पेज पर उपयोगकर्ता का सफ़र

स्क्रोल स्नैपिंग का इस्तेमाल, ऐसे पेजों पर भी किया जा सकता है जिनमें कई लॉजिकल सेक्शन होते हैं. इन सेक्शन को वर्टिकल तरीके से स्क्रोल किया जा सकता है. उदाहरण के लिए, सामान्य प्रॉडक्ट पेज. 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 प्रॉपर्टी एक नई सीएसएस प्रॉपर्टी है. इसका इस्तेमाल, स्क्रोल कंटेनर या स्नैपपोर्ट के दिखने वाले हिस्से को अडजस्ट करने के लिए किया जा सकता है. स्नैपपोर्ट का इस्तेमाल, स्क्रोल स्नैप अलाइनमेंट का हिसाब लगाते समय किया जाता है. यह प्रॉपर्टी, स्क्रोल कंटेनर के पैडिंग बॉक्स के अंदर की ओर एक इनसेट तय करती है. हमारे उदाहरण में, सबसे ऊपर 15vh additional inset जोड़ा गया है. इससे ब्राउज़र को यह निर्देश मिलता है कि वह स्क्रोल कंटेनर के सबसे ऊपरी किनारे के नीचे, 15vh नीचे की पोज़िशन को स्क्रोल स्नैपिंग के लिए वर्टिकल स्टार्ट एज के तौर पर इस्तेमाल करे. स्नैप करते समय, स्नैप टारगेट एलिमेंट का शुरुआती किनारा, इस नई जगह के साथ अलाइन हो जाएगा. इस वजह से, ऊपर की ओर जगह बच जाएगी.

scroll-margin प्रॉपर्टी, आउटसेट की उस वैल्यू को तय करती है जिसका इस्तेमाल स्नैप टारगेट के इफ़ेक्टिव बॉक्स को अडजस्ट करने के लिए किया जाता है. यह ठीक उसी तरह काम करता है जिस तरह scroll-padding, स्नैप स्क्रोल कंटेनर पर काम करता है.

आपने शायद ध्यान दिया हो कि इन दोनों प्रॉपर्टी में "snap" शब्द नहीं है. ऐसा जान-बूझकर किया गया है, क्योंकि ये सभी स्क्रोल कार्रवाइयों के लिए बॉक्स में बदलाव करते हैं. ये सिर्फ़ स्क्रोल स्नैपिंग नहीं हैं. उदाहरण के लिए, Chrome इनका इस्तेमाल तब करता है, जब उसे पेजिंग स्क्रोल ऑपरेशन के लिए पेज के साइज़ का हिसाब लगाना होता है. जैसे, PageDown और PageUp. साथ ही, Chrome इनका इस्तेमाल तब भी करता है, जब उसे Element.scrollIntoView() ऑपरेशन के लिए स्क्रोल की रकम का हिसाब लगाना होता है.

स्क्रोल करने की सुविधा देने वाले अन्य एपीआई के साथ इंटरैक्शन

DOM Scrolling API

स्क्रॉल स्नैपिंग, स्क्रॉल करने की सभी कार्रवाइयों के बाद होती है. इनमें स्क्रिप्ट से शुरू की गई कार्रवाइयां भी शामिल हैं. Element.scrollTo जैसे एपीआई का इस्तेमाल करते समय, ब्राउज़र स्क्रोल करने की सही जगह का हिसाब लगाएगा. इसके बाद, स्नैपिंग की सही लॉजिक लागू करके, स्नैप की गई आखिरी जगह का पता लगाएगा. इसलिए, स्नैपिंग के लिए उपयोगकर्ता स्क्रिप्ट को मैन्युअल तरीके से कोई भी हिसाब लगाने की ज़रूरत नहीं होती.

आसानी से स्क्रोल करने की सुविधा

स्मूद स्क्रोलिंग, प्रोग्राम के हिसाब से स्क्रोल करने की प्रोसेस को कंट्रोल करती है. वहीं, स्क्रोल स्नैप, स्क्रोल करने की जगह तय करता है. ये दोनों, स्क्रोल करने के अलग-अलग पहलुओं को कंट्रोल करते हैं. इसलिए, इनका इस्तेमाल एक साथ किया जा सकता है और ये एक-दूसरे के पूरक होते हैं.

ओवरस्क्रोल का व्यवहार

Overscroll behavior API यह कंट्रोल करता है कि कई एलिमेंट में स्क्रोलिंग कैसे की जाती है. इस पर स्क्रोल स्नैप का कोई असर नहीं पड़ता.

चेतावनी और सबसे सही तरीके

जब टारगेट एलिमेंट एक-दूसरे से काफ़ी दूर हों, तब स्नैपिंग की सुविधा का इस्तेमाल न करें. इस वजह से, स्नैप पोज़िशन के बीच मौजूद कॉन्टेंट को ऐक्सेस नहीं किया जा सकता.

ज़्यादातर मामलों में, स्क्रोल-स्नैपिंग को बेहतर बनाने के लिए जोड़ा जा सकता है. इसके लिए, सुविधा का पता लगाने की ज़रूरत नहीं होती. अगर ज़रूरत हो, तो सीएसएस स्क्रोल स्नैप के साथ काम करने वाले ब्राउज़र का पता लगाने के लिए, @supports या CSS.supports का इस्तेमाल करें. scroll-snap-type का इस्तेमाल न करें. यह एट्रिब्यूट, बंद हो चुके स्पेसिफ़िकेशन में भी मौजूद है.

सीएसएस में सुविधा का पता लगाना

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

JavaScript में सुविधा का पता लगाना

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

यह न मान लें कि प्रोग्राम के हिसाब से स्क्रोल करने वाले एपीआई, जैसे कि Element.scrollTo, हमेशा स्क्रोल करने के लिए अनुरोध किए गए ऑफ़सेट पर खत्म होते हैं. प्रोग्राम के हिसाब से स्क्रोल करने की प्रोसेस पूरी होने के बाद, स्क्रोल स्नैपिंग की वजह से स्क्रोल ऑफ़सेट में बदलाव हो सकता है. ध्यान दें कि स्क्रोल स्नैप से पहले भी यह एक सही अनुमान नहीं था, क्योंकि स्क्रोलिंग में अन्य वजहों से भी रुकावट आ सकती है. हालांकि, स्क्रोल स्नैपिंग के मामले में ऐसा खास तौर पर होता है.

आने वाले समय में किए जाने वाले काम

Chrome टीम ने हाल ही में एक सर्वे किया था, जिसमें स्क्रोल करने के अनुभव पर फ़ोकस किया गया था. सर्वे के नतीजों से पता चला कि प्लगिन लाइब्रेरी और सीएसएस के बीच के अंतर को कम करने के लिए, कई क्षेत्रों में और काम करने की ज़रूरत है. आने वाले समय में, scroll-snap पर फ़ोकस किया जाएगा. इसमें ये शामिल हैं:

  1. एपीआई की उपलब्धता और अलग-अलग ब्राउज़र के साथ काम करने की सुविधा.
  2. scroll-start जैसे नए CSS API पर काम करें.
  3. snapChanged() जैसे नए JS इवेंट पर काम करें.