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

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

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

बैकग्राउंड

स्क्रोल स्नैपिंग का इस्तेमाल क्यों करना चाहिए

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

स्क्रोल करने की मुख्य कमी यह है कि इसमें सटीक जानकारी नहीं मिलती. ऐसा बहुत कम होता है कि स्क्रोल करने पर, कोई पैराग्राफ़ या वाक्य सही से अलाइन हो. यह समस्या तब और ज़्यादा बढ़ जाती है, जब पेज पर मौजूद कॉन्टेंट को अलग-अलग पेजों या आइटम के हिसाब से बांटा गया हो और स्क्रोल करने पर, पेज या इमेज का आधा हिस्सा ही दिखे. इन मामलों में, स्क्रोल करने के अनुभव को बेहतर बनाने से फ़ायदा मिलता है.

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

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

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

सीएसएस स्क्रोल स्नैप

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

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

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

आपने ध्यान दिया होगा कि इन दोनों प्रॉपर्टी में "snap" शब्द नहीं है. ऐसा जान-बूझकर किया गया है, क्योंकि ये स्क्रोल करने से जुड़ी सभी ज़रूरी कार्रवाइयों के लिए बॉक्स में बदलाव करते हैं. ये सिर्फ़ स्क्रोल स्नैपिंग नहीं करते. उदाहरण के लिए, Chrome इनका इस्तेमाल पेजिंग स्क्रोल ऑपरेशन के लिए पेज का साइज़ कैलकुलेट करते समय करता है. जैसे, PageDown और PageUp. साथ ही, 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.
  3. snapChanged() जैसे नए JS इवेंट पर काम करें.