सीएसएस डीप-डाइव - फ़्रेम-परफ़ेक्ट कस्टम स्क्रोलबार के लिए matrix3d()

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

कम शब्दों में कहा जाए तो

क्या आपको छोटी-छोटी बातों से फ़र्क़ नहीं पड़ता? क्या आपको सिर्फ़ Nyan cat का डेमो देखना है और लाइब्रेरी चाहिए? आपको हमारे GitHub रेपो में, डेमो का कोड मिल जाएगा.

LAM;WRA (लंबा और गणितीय; फिर भी पढ़ा जाएगा)

कुछ समय पहले, हमने पैरलॅक्स स्क्रोलर बनाया था (क्या आपने वह लेख पढ़ा है? यह बहुत अच्छा है, इसे देखना ज़रूर चाहिए!). सीएसएस 3D ट्रांसफ़ॉर्म का इस्तेमाल करके, एलिमेंट को पीछे धकेलने पर, वे हमारी स्क्रोलिंग स्पीड से धीमी गति से आगे बढ़ते हैं.

रीकैप

चलिए, पैरलॅक्स स्क्रोलर के काम करने के तरीके की खास जानकारी से शुरुआत करते हैं.

ऐनिमेशन में दिखाए गए तरीके से, हमने पैरलॅक्स इफ़ेक्ट हासिल किया. इसके लिए, हमने एलिमेंट को ज़ेड ऐक्सिस के साथ 3D स्पेस में “पीछे” धकेला. किसी दस्तावेज़ को स्क्रोल करना, Y-ऐक्सिस के साथ ट्रांसलेट करना होता है. इसलिए, अगर हम 100 पिक्सल नीचे की ओर स्क्रोल करते हैं, तो हर एलिमेंट 100 पिक्सल ऊपर की ओर ट्रांसलेट हो जाएगा. यह सभी एलिमेंट पर लागू होता है, भले ही वे “ज़्यादा पीछे” हों. हालांकि, इसकी वजह यह है कि वे कैमरे से ज़्यादा दूर हैं, इसलिए स्क्रीन पर उनकी गति 100 पिक्सल से कम होगी. इससे, पैरलॅक्स इफ़ेक्ट दिखेगा.

बेशक, किसी एलिमेंट को वापस स्पेस में ले जाने पर भी वह छोटा दिखेगा. हम एलिमेंट को फिर से स्केल करके इसे ठीक करते हैं. पैरालैक्स स्क्रोलर बनाते समय, हमने पूरी गणना कर ली थी. इसलिए, हम पूरी जानकारी दोबारा नहीं देंगे.

पहला चरण: हमें क्या करना है?

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

पहला चरण: इसे रिवर्स मोड में डालना

ठीक है, हम पैरलॅक्स स्क्रोलिंग वाले लेख में बताए गए तरीके से, सीएसएस 3D ट्रांसफ़ॉर्म की मदद से, एलिमेंट को स्क्रोलिंग स्पीड से धीमी गति से मूव कर सकते हैं. क्या हम दिशा को उलट भी सकते हैं? हमने पाया कि ऐसा किया जा सकता है. यही वजह है कि हम फ़्रेम के हिसाब से, कस्टम स्क्रोलबार बनाने के लिए इस तरीके का इस्तेमाल कर रहे हैं. यह समझने के लिए कि यह कैसे काम करता है, हमें पहले CSS 3D की कुछ बुनियादी बातों के बारे में बताना होगा.

गणित के हिसाब से किसी भी तरह का पर्सपेक्टिव प्रोजेक्शन पाने के लिए, आपको एक जैसे निर्देशांक का इस्तेमाल करना पड़ेगा. हम इस बारे में ज़्यादा जानकारी नहीं देंगे कि ये क्या हैं और ये कैसे काम करते हैं. हालांकि, इन्हें w नाम के चौथे निर्देशांक के साथ 3D निर्देशांक की तरह माना जा सकता है. अगर आपको पर्सपेक्टिव में बदलाव नहीं करना है, तो यह कोऑर्डिनेट 1 होना चाहिए. हमें w की जानकारी के बारे में चिंता करने की ज़रूरत नहीं है, क्योंकि हम 1 के अलावा किसी और वैल्यू का इस्तेमाल नहीं करने वाले हैं. इसलिए, अब सभी पॉइंट चार डाइमेंशन वाले वैक्टर [x, y, z, w=1] हैं. साथ ही, मैट्रिक भी 4x4 होनी चाहिए.

सीएसएस में, होमोजेनिएस कोऑर्डिनेट का इस्तेमाल तब किया जाता है, जब matrix3d() फ़ंक्शन का इस्तेमाल करके, ट्रांसफ़ॉर्म प्रॉपर्टी में अपना 4x4 मैट्रिक्स तय किया जाता है. matrix3d में 16 आर्ग्युमेंट होते हैं, क्योंकि मैट्रिक्स 4x4 होती है. इसमें एक के बाद एक कॉलम तय किए जाते हैं. इसलिए, इस फ़ंक्शन का इस्तेमाल करके, रोटेशन, ट्रांसलेशन वगैरह को मैन्युअल तरीके से तय किया जा सकता है. हालांकि, इसकी मदद से w कोऑर्डिनेट में भी बदलाव किया जा सकता है!

matrix3d() का इस्तेमाल करने से पहले, हमें 3D संदर्भ की ज़रूरत होती है – क्योंकि 3D संदर्भ के बिना, पर्सपेक्टिव में कोई बदलाव नहीं होगा और एक जैसे निर्देशांक की ज़रूरत नहीं होगी. 3D कॉन्टेक्स्ट बनाने के लिए, हमें एक कंटेनर की ज़रूरत होती है. इसमें perspective और कुछ ऐसे एलिमेंट होने चाहिए जिन्हें नए बनाए गए 3D स्पेस में ट्रांसफ़ॉर्म किया जा सके. उदाहरण के लिए, यह:

सीएसएस कोड का एक हिस्सा, जो सीएसएस के
    पर्सपेक्टिव एट्रिब्यूट का इस्तेमाल करके किसी डिव को खराब कर देता है.

पर्सपेक्टिव कंटेनर में मौजूद एलिमेंट को सीएसएस इंजन इस तरह प्रोसेस करता है:

  • किसी एलिमेंट के हर कोने (वर्टिक्स) को, पर्सपेक्टिव कंटेनर के हिसाब से एक जैसे निर्देशांक [x,y,z,w] में बदलें.
  • एलिमेंट के सभी ट्रांसफ़ॉर्म को दाईं से बाईं ओर मैट्रिक्स के तौर पर लागू करें.
  • अगर पर्सपेक्टिव एलिमेंट को स्क्रोल किया जा सकता है, तो स्क्रोल मैट्रिक लागू करें.
  • पर्सपेक्टिव मैट्रिक्स लागू करें.

स्क्रोल मैट्रिक, y-ऐक्सिस के साथ ट्रांसलेशन है. अगर हम 400 पिक्सल तक स्क्रोल करें, तो सभी एलिमेंट को 400 पिक्सल तक ऊपर ले जाना होगा. पर्सपेक्टिव मैट्रिक एक ऐसा मैट्रिक होता है जो 3D स्पेस में पीछे की ओर मौजूद पॉइंट को, वैनिशिंग पॉइंट के ज़्यादा करीब “खींचता” है. इससे, चीज़ों को दूर होने पर छोटा दिखाने और अनुवाद करते समय उन्हें “धीमी गति से चलने” का दोनों इफ़ेक्ट मिलता है. इसलिए, अगर किसी एलिमेंट को पीछे धकेला जाता है, तो 400 पिक्सल के ट्रांसलेशन से एलिमेंट, स्क्रीन पर सिर्फ़ 300 पिक्सल तक जाएगा.

अगर आपको पूरी जानकारी चाहिए, तो आपको सीएसएस के ट्रांसफ़ॉर्म रेंडरिंग मॉडल के बारे में स्पेसिफ़िकेशन पढ़ना चाहिए. हालांकि, इस लेख के लिए, मैंने ऊपर दिए गए एल्गोरिदम को आसान बनाया है.

हमारा बॉक्स, perspective एट्रिब्यूट की वैल्यू p वाले पर्सपेक्टिव कंटेनर के अंदर है. मान लें कि कंटेनर को स्क्रोल किया जा सकता है और इसे n पिक्सल नीचे स्क्रोल किया गया है.

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

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

हालांकि, स्क्रोलबार के लिए हमें इसके उलट करना है – जब हम नीचे स्क्रोल कर रहे हों, तब हमें अपने एलिमेंट को नीचे ले जाना है. यहां हम एक ट्रिक का इस्तेमाल कर सकते हैं: अपने बॉक्स के कोनों के w निर्देशांक को उलटना. अगर w कोऑर्डिनेट -1 है, तो सभी ट्रांसलेशन, विपरीत दिशा में लागू होंगे. तो हम यह कैसे करें? सीएसएस इंजन, हमारे बॉक्स के कोनों को एक जैसे निर्देशांक में बदलता है और w को 1 पर सेट करता है. अब matrix3d() का समय आ गया है!

.box {
  transform:
    matrix3d(
      1, 0, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, -1
    );
}

यह मैट्रिक, w को नेगेटिव करने के अलावा कुछ नहीं करेगी. इसलिए, जब सीएसएस इंजन ने हर कोने को [x,y,z,1] फ़ॉर्म के वेक्टर में बदल दिया है, तो मैट्रिक उसे [x,y,z,-1] में बदल देगी.

चौथी पंक्ति के तीसरे कॉलम में p के ऊपर माइनस एक वाली चार पंक्तियों और चार कॉलम वाली आइडेंटिटी मैट्रिक्स, दूसरी पंक्ति के चौथे कॉलम में n के ऊपर माइनस वाली चार पंक्तियों और चार कॉलम वाली आइडेंटिटी मैट्रिक्स, चौथी पंक्ति के चौथे कॉलम में माइनस एक वाली चार पंक्तियों और चार कॉलम वाली आइडेंटिटी मैट्रिक्स, चार डाइमेंशन वाले वेक्टर x, y, z, 1 के बराबर होती है. चौथी पंक्ति के तीसरे कॉलम में p के ऊपर माइनस एक वाली चार पंक्तियों और चार कॉलम वाली आइडेंटिटी मैट्रिक्स, दूसरी पंक्ति के चौथे कॉलम में n के ऊपर माइनस वाली चार पंक्तियों और चौथी पंक्ति के चौथे कॉलम में माइनस एक वाली चार पंक्तियों वाली आइडेंटिटी मैट्रिक्स, चार डाइमेंशन वाले वेक्टर x, y प्लस n, z, माइनस z के बराबर होती है.

मैंने एलिमेंट ट्रांसफ़ॉर्म मैट्रिक का असर दिखाने के लिए, बीच में एक चरण जोड़ा है. अगर आपको मैट्रिक के हिसाब से गणित का इस्तेमाल करने में परेशानी होती है, तो कोई बात नहीं. अहम बात यह है कि आखिरी लाइन में, हम स्क्रोल ऑफ़सेट n को अपने y कोऑर्डिनेट में घटाने के बजाय जोड़ते हैं. नीचे स्क्रोल करने पर, एलिमेंट नीचे ट्रांसलेट हो जाएगा.

हालांकि, अगर हम अपने उदाहरण में सिर्फ़ यह मैट्रिक डालते हैं, तो एलिमेंट नहीं दिखेगा. ऐसा इसलिए है, क्योंकि सीएसएस स्पेसिफ़िकेशन के मुताबिक, w < 0 वाला कोई भी वर्टिक्स, एलिमेंट को रेंडर होने से रोकता है. साथ ही, हमारा z कोऑर्डिनेट फ़िलहाल 0 है और p 1 है, इसलिए w -1 होगा.

सौभाग्य से, हम z की वैल्यू चुन सकते हैं! यह पक्का करने के लिए कि हमें w=1 मिले, हमें z = -2 सेट करना होगा.

.box {
  transform:
    matrix3d(
      1, 0, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, -1
    )
    translateZ(-2px);
}

देखिए, हमारा बॉक्स वापस आ गया है!

दूसरा चरण: आइटम को मूव करना

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

<div class="container">
    <div class="box"></div>
    <span class="spacer"></span>
</div>

<style>
/* … all the styles from the previous example … */
.container {
    overflow: scroll;
}
.spacer {
    display: block;
    height: 500px;
}
</style>

अब बॉक्स को स्क्रोल करें! लाल बॉक्स नीचे की ओर बढ़ता है.

तीसरा चरण: उसे साइज़ दें

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

आम तौर पर, स्क्रोलबार में एक “थंब” और एक “ट्रैक” होता है. हालांकि, ट्रैक हमेशा दिखता नहीं है. थंबनेल की ऊंचाई, कॉन्टेंट के दिखने के प्रतिशत के हिसाब से तय होती है.

<script>
    const scroller = document.querySelector('.container');
    const thumb = document.querySelector('.box');
    const scrollerHeight = scroller.getBoundingClientRect().height;
    thumb.style.height = /* ??? */;
</script>

scrollerHeight, स्क्रोल किए जा सकने वाले एलिमेंट की ऊंचाई है, जबकि scroller.scrollHeight, स्क्रोल किए जा सकने वाले कॉन्टेंट की कुल ऊंचाई है. scrollerHeight/scroller.scrollHeight, कॉन्टेंट के दिखने वाले हिस्से का हिस्सा है. थंबनेल में वर्टिकल स्पेस का अनुपात, दिखने वाले कॉन्टेंट के अनुपात के बराबर होना चाहिए:

थंब डॉट स्टाइल के बिंदु की ऊंचाई, स्क्रोलर की ऊंचाई के बराबर होती है, अगर और सिर्फ़ अगर थंब डॉट स्टाइल के बिंदु की ऊंचाई, स्क्रोलर की ऊंचाई के स्क्रोलर बिंदु की स्क्रोल ऊंचाई के बराबर होती है.
<script>
    // …
    thumb.style.height =
    scrollerHeight * scrollerHeight / scroller.scrollHeight + 'px';
    // Accommodate for native scrollbars
    thumb.style.right =
    (scroller.clientWidth - scroller.getBoundingClientRect().width) + 'px';
</script>

थंबनेल का साइज़ अच्छा लग रहा है, लेकिन यह बहुत तेज़ी से चल रहा है. यहां हम पैरलॅक्स स्क्रोलर से अपनी तकनीक हासिल कर सकते हैं. अगर हम एलिमेंट को और पीछे ले जाते हैं, तो स्क्रोल करते समय वह धीमी गति से चलेगा. हम साइज़ को बड़ा करके, उसे ठीक कर सकते हैं. लेकिन हमें इसे कितनी दूर तक पीछे धकेलना चाहिए? चलिए, हिसाब लगाते हैं! वादा है, आखिरी बार.

अहम जानकारी यह है कि हम चाहते हैं कि पूरी तरह से स्क्रोल करने पर, अंगूठे के सबसे नीचे वाले हिस्से का अलाइनमेंट, स्क्रोल किए जा सकने वाले एलिमेंट के सबसे नीचे वाले हिस्से से हो. दूसरे शब्दों में: अगर हमने scroller.scrollHeight - scroller.height पिक्सल स्क्रोल किए हैं, तो हमें अपने अंगूठे को scroller.height - thumb.height तक ट्रांसलेट करना है. स्क्रोलर के हर पिक्सल के लिए, हम चाहते हैं कि हमारा अंगूठा एक पिक्सल का एक हिस्सा ही आगे-पीछे करे:

फ़ैक्टर, स्क्रोलर बिंदु की ऊंचाई में थंब बिंदु की ऊंचाई को घटाने के बाद, स्क्रोलर बिंदु की स्क्रोल ऊंचाई में स्क्रोलर बिंदु की ऊंचाई को घटाने के बराबर होता है.

यही हमारा स्केलिंग फ़ैक्टर है. अब हमें स्केलिंग फ़ैक्टर को z ऐक्सिस के साथ ट्रांसलेशन में बदलना होगा. हमने पैरलॅक्स स्क्रोलिंग वाले लेख में पहले ही ऐसा कर लिया है. स्पेसिफ़िकेशन के काम के सेक्शन के मुताबिक: स्केलिंग फ़ैक्टर, p/(p − z) के बराबर होता है. इस इक्वेशन को z के लिए हल करके, यह पता लगाया जा सकता है कि हमें z ऐक्सिस के साथ अपने अंगूठे को कितना ट्रांसलेट करना है. हालांकि, ध्यान रखें कि w निर्देशांक की वजह से, हमें z के साथ एक और -2px का अनुवाद करना होगा. यह भी ध्यान रखें कि किसी एलिमेंट के ट्रांसफ़ॉर्मेशन, दाईं से बाईं ओर लागू किए जाते हैं. इसका मतलब है कि हमारे खास मैट्रिक से पहले के सभी ट्रांसलेशन, उलटे नहीं किए जाएंगे. हालांकि, हमारे खास मैट्रिक के बाद के सभी ट्रांसलेशन, उलटे किए जाएंगे! आइए, इसे कोड में बदलते हैं!

<script>
    // ... code from above...
    const factor =
    (scrollerHeight - thumbHeight)/(scroller.scrollHeight - scrollerHeight);
    thumb.style.transform = `
    matrix3d(
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, -1
    )
    scale(${1/factor})
    translateZ(${1 - 1/factor}px)
    translateZ(-2px)
    `;
</script>

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

iOS के लिए क्या है?

आह, मेरा पुराना दोस्त iOS Safari. पैरलॅक्स स्क्रोलिंग की तरह ही, हमें यहां भी एक समस्या आ रही है. हम किसी एलिमेंट पर स्क्रोल कर रहे हैं, इसलिए हमें -webkit-overflow-scrolling: touch की जानकारी देनी होगी. हालांकि, इससे 3D फ़्लैट हो जाता है और हमारा पूरा स्क्रोलिंग इफ़ेक्ट काम करना बंद कर देता है. हमने पैरलॅक्स स्क्रोलर में इस समस्या को हल किया है. इसके लिए, हमने iOS Safari का पता लगाया और position: sticky का इस्तेमाल किया. हम यहां भी यही तरीका अपनाएंगे. अपनी याददाश्त को रीफ़्रेश करने के लिए, पैरलॅक्स वाला लेख पढ़ें.

ब्राउज़र स्क्रोलबार के बारे में क्या?

कुछ सिस्टम पर, हमें हमेशा मौजूद नेटिव स्क्रोलबार का इस्तेमाल करना होगा. अब तक, स्क्रोलबार को छिपाया नहीं जा सकता था. हालांकि, नॉन-स्टैंडर्ड स्यूडो-सिलेक्टर की मदद से ऐसा किया जा सकता है. इसलिए, इसे छिपाने के लिए, हमें कुछ हैकिंग (गिनती के बिना) का सहारा लेना होगा. हम अपने स्क्रोलिंग एलिमेंट को overflow-x: hidden के साथ कंटेनर में रैप करते हैं और स्क्रोलिंग एलिमेंट को कंटेनर से ज़्यादा चौड़ा बनाते हैं. ब्राउज़र का नेटिव स्क्रोलबार अब दिखने बंद हो गया है.

फ़िन

इन सभी चीज़ों को एक साथ जोड़कर, अब हम फ़्रेम के हिसाब से पसंद के मुताबिक स्क्रोलबार बना सकते हैं. जैसे, Nyan cat के डेमो में मौजूद स्क्रोलबार.

अगर आपको Nyan cat नहीं दिख रहा है, तो इसका मतलब है कि आपको एक गड़बड़ी का सामना करना पड़ रहा है. हमने इस गड़बड़ी को ढूंढकर, उसे दर्ज कर लिया है. Nyan cat को दिखाने के लिए, थंब पर क्लिक करें. Chrome, ग़ैर-ज़रूरी कामों से बचने में काफ़ी अच्छा है. जैसे, स्क्रीन से बाहर की चीज़ों को पेंट करना या ऐनिमेशन देना. बुरी खबर यह है कि मैट्रिक्स की तरह की हमारी गतिविधियों की वजह से, Chrome को लगता है कि न्यान कैट का GIF फ़ाइल, स्क्रीन पर नहीं है. उम्मीद है कि यह समस्या जल्द ही ठीक हो जाएगी.

बस हो गया. इसमें काफ़ी काम था. पूरी जानकारी पढ़ने के लिए धन्यवाद. इसे काम कराने के लिए, कुछ असली तरकीबें अपनानी पड़ती हैं. ऐसा शायद ही कभी किया जाना चाहिए. हालांकि, अगर उपयोगकर्ताओं को पसंद के मुताबिक स्क्रोलबार देना ज़रूरी है, तो ऐसा किया जा सकता है. हालांकि, यह जानकर अच्छा लगा कि ऐसा किया जा सकता है, है न? कस्टम स्क्रोलबार बनाने में इतनी मुश्किल आना, इस बात का सबूत है कि सीएसएस को इस पर काम करना होगा. लेकिन घबराएं नहीं! आने वाले समय में, Houdini के AnimationWorklet की मदद से, स्क्रीन पर स्क्रोल करने पर दिखने वाले इस तरह के इफ़ेक्ट को आसानी से बनाया जा सकेगा.