मीडिया स्क्रोलर कॉम्पोनेंट बनाना

टीवी, फ़ोन, डेस्कटॉप वगैरह के लिए, रिस्पॉन्सिव हॉरिज़ॉन्टल स्क्रोल व्यू बनाने के तरीके की बुनियादी जानकारी.

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

डेमो

अगर आपको वीडियो देखना पसंद है, तो यहां इस पोस्ट का YouTube वर्शन दिया गया है:

खास जानकारी

हम एक हॉरिज़ॉन्टल स्क्रोल लेआउट बना रहे हैं. इसका मकसद, मीडिया या प्रॉडक्ट के थंबनेल होस्ट करना है. यह कॉम्पोनेंट, एक साधारण <ul> सूची के तौर पर शुरू होता है. हालांकि, सीएसएस की मदद से इसे एक बेहतर और आसानी से स्क्रोल किए जा सकने वाले कॉम्पोनेंट में बदल दिया जाता है. इसमें इमेज दिखाई जाती हैं और उन्हें ग्रिड में स्नैप किया जाता है. रोविंग-इंडेक्स इंटरैक्शन को आसान बनाने के लिए JavaScript को जोड़ा गया है, ताकि कीबोर्ड इस्तेमाल करने वाले उपयोगकर्ताओं को 100 से ज़्यादा आइटम के एक हिस्से से दूसरे पर जाने में परेशानी न हो. साथ ही, मीडिया स्क्रोलर को हलके टाइटल स्क्रोलर में बदलने के लिए, एक्सपेरिमेंट वाली मीडिया क्वेरी prefers-reduced-data का इस्तेमाल किया जाता है.

सुलभ मार्कअप से शुरू करना

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

<ul> एलिमेंट वाली सूची डिलीवर करने के लिए:

<ul class="horizontal-media-scroller">
  <li></li>
  <li></li>
  <li></li>
  ...
<ul>

<a> एलिमेंट का इस्तेमाल करके, सूची के आइटम को इंटरैक्टिव बनाएं:

<li>
  <a href="#">
    ...
  </a>
</li>

किसी इमेज और उसके कैप्शन को वाक्य की तरह दिखाने के लिए <figure> एलिमेंट का इस्तेमाल करें:

<figure>
  <picture>
    <img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
  </picture>
  <figcaption>Legends</figcaption>
</figure>

<img> पर alt और loading एट्रिब्यूट देखें. मीडिया स्क्रोलर के लिए वैकल्पिक टेक्स्ट, यूज़र एक्सपीरियंस (यूएक्स) को बेहतर बनाने का एक मौका है. इससे थंबनेल के बारे में ज़्यादा जानकारी मिलती है. इसके अलावा, अगर इमेज लोड नहीं होती है, तो वैकल्पिक टेक्स्ट फ़ॉलबैक टेक्स्ट के तौर पर काम करता है. साथ ही, यह स्क्रीन रीडर जैसी सहायक तकनीक का इस्तेमाल करने वाले उपयोगकर्ताओं के लिए बोला गया यूज़र इंटरफ़ेस (यूआई) उपलब्ध कराता है. अनुपालन करने वाले वैकल्पिक टेक्स्ट के लिए पांच बुनियादी नियम के बारे में ज़्यादा जानें.

loading एट्रिब्यूट में lazy कीवर्ड का इस्तेमाल किया जा सकता है. इससे यह पता चलता है कि इमेज सोर्स को सिर्फ़ तब फ़ेच किया जाना चाहिए, जब इमेज व्यूपोर्ट में हो. यह बड़ी सूचियों के लिए वाकई अच्छा हो सकता है, क्योंकि उपयोगकर्ता सिर्फ़ उन आइटम के लिए इमेज डाउनलोड करेंगे जिन्हें स्क्रोल करके देखा गया है.

उपयोगकर्ता की कलर स्कीम की प्राथमिकता के हिसाब से काम करना

color-scheme का इस्तेमाल <meta> टैग के तौर पर करके, ब्राउज़र को यह बताएं कि आपका पेज, हल्के और गहरे रंग वाली, दोनों तरह के उपयोगकर्ता-एजेंट स्टाइल के बारे में बताता है. यह मुफ़्त में उपलब्ध डार्क मोड या लाइट मोड है. यह इस बात पर निर्भर करता है कि आप इसे किस तरह देखते हैं:

<meta name="color-scheme" content="dark light">

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

https://web.dev/color-scheme/ पर जाकर, थॉमस स्टाइनर से ज़्यादा जानकारी पाएं.

कॉन्टेंट जोड़ें

ul > li > a > figure > picture > img के ऊपर दिए गए कॉन्टेंट स्ट्रक्चर के हिसाब से, अगला टास्क स्क्रोल करने के लिए इमेज और टाइटल जोड़ना है. मैंने डेमो में स्टैटिक प्लेसहोल्डर इमेज और टेक्स्ट का इस्तेमाल किया है. हालांकि, इसे अपने पसंदीदा डेटा सोर्स से भी इस्तेमाल किया जा सकता है.

सीएसएस की मदद से स्टाइल जोड़ना

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

स्क्रोलर लेआउट बनाना

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

2
स्क्रोल करने वाली पंक्तियां दिखाई गई हैं. एक में एलिप्सिस नहीं है, जिसका मतलब है कि यह लंबा है और हर टाइटल को आसानी से पढ़ा जा सकता है. दूसरा टाइटल छोटा है और कई टाइटल में बिंदु के साथ काट दिया गया है.

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

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
  margin: 0;
}

इसके बाद, <picture> एलिमेंट इस कस्टम प्रॉपर्टी का इस्तेमाल करके, हमारा बेस आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बनाता है: बॉक्स:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

मीडिया स्क्रोलर को बेहतर बनाने के लिए, कुछ और छोटी-मोटी स्टाइल जोड़ें:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  & > li {
    display: inline-block; /* removes the list-item bullet */
  }

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

overflow सेटिंग, <ul> को सेट अप करती है, ताकि उसकी सूची में स्क्रोल किया जा सके और कीबोर्ड नेविगेशन का इस्तेमाल किया जा सके. इसके बाद, हर डायरेक्ट चाइल्ड <li> एलिमेंट से ::marker हटा दिया जाता है. इसके लिए, inline-block का नया डिसप्ले टाइप मिलता है.

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

img {
  /* smash into whatever box it's in */
  inline-size: 100%;
  block-size: 100%;

  /* don't squish but do cover the space */
  object-fit: cover;

  /* soften the edges */
  border-radius: 1ex;
  overflow: hidden;

  /* if empty, show a gradient placeholder */
  background-image:
    linear-gradient(
      to bottom,
      hsl(0 0% 40%),
      hsl(0 0% 20%)
    );
}

स्क्रोल पैडिंग

पेज के कॉन्टेंट के साथ अलाइनमेंट और किनारे से किनारे तक स्क्रोल करने की सुविधा, एक बेहतर और कम कॉम्पोनेंट के लिए ज़रूरी है.

हमारी टाइपोग्राफ़ी और लेआउट लाइनों के हिसाब से, एज-टू-एज स्क्रोल लेआउट को पूरा करने के लिए, scroll-padding से मेल खाने वाले padding का इस्तेमाल करें:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}

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

आखिरी सूची आइटम के इनलाइन-एंड साइड पर एक बॉक्स हाइलाइट किया गया है. इससे पता चलता है कि पैडिंग और एलिमेंट की चौड़ाई एक जैसी है, ताकि मनमुताबिक अलाइनमेंट बनाया जा सके.

ब्राउज़र को चकमा देने वाले पेज पर, स्क्रोलर के आखिर में पैडिंग (जगह) लगाने के लिए, मैं हर सूची के आखिरी हिस्से को टारगेट करूंगा और एक छद्म एलिमेंट जोड़ूंगा. यह एलिमेंट, मनचाही पैडिंग (जगह) के बराबर होगा.

.horizontal-media-scroller > li:last-of-type figure {
  position: relative;

  &::after {
    content: "";
    position: absolute;

    inline-size: var(--gap);
    block-size: 100%;

    inset-block-start: 0;
    inset-inline-end: calc(var(--gap) * -1);
  }
}

लॉजिकल प्रॉपर्टी का इस्तेमाल करने से, मीडिया स्क्रोलर किसी भी लेखन मोड और दस्तावेज़ की दिशा में काम कर सकता है.

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

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

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block-end: calc(var(--gap) / 2);

  scroll-snap-type: inline mandatory;

  & figure {
    scroll-snap-align: start;
  }
}

फ़ोकस

इस कॉम्पोनेंट को बनाने की प्रेरणा, टीवी, ऐप्लिकेशन स्टोर वगैरह पर इसकी लोकप्रियता से मिली है. कई वीडियो गेम प्लैटफ़ॉर्म, अपनी मुख्य होम स्क्रीन के लेआउट के तौर पर, इस तरह के मीडिया स्क्रोलर का इस्तेमाल करते हैं. यहां फ़ोकस एक बहुत ही बड़ा UX है, जिसमें कोई छोटा-सा योगदान नहीं है. कल्पना करें कि आपने अपने सोफ़े पर रिमोट का इस्तेमाल करके, मीडिया स्क्रोलर का इस्तेमाल किया है. इस इंटरैक्शन को बेहतर बनाने के लिए, इन बातों का ध्यान रखें:

.horizontal-media-scroller a {
  outline-offset: 12px;

  &:focus {
    outline-offset: 7px;
  }

  @media (prefers-reduced-motion: no-preference) {
    & {
      transition: outline-offset .25s ease;
    }
  }
}

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

रोविंग इंडेक्स

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

डेमो के पहले स्क्रोलर में 300 आइटम हैं. हम अगले सेक्शन पर जाने के लिए, लोगों को इन सभी सेक्शन को पार करने के बजाय, बेहतर तरीके से मदद कर सकते हैं.

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

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

यह डेमो, दस्तावेज़ में स्क्रोलर के लिए क्वेरी करता है और हर स्क्रोलर के लिए rovingIndex() फ़ंक्शन को कॉल करता है. अगर फ़ोकस टारगेट डायरेक्ट वंशज नहीं हैं, तो rovingIndex() एलिमेंट को पास करें, ताकि आपको रोविंग अनुभव मिल सके. जैसे, लिस्ट कंटेनर और टारगेट क्वेरी सिलेक्टर.

document.querySelectorAll('.horizontal-media-scroller')
  .forEach(scroller =>
    rovingIndex({
      element: scroller,
      target: 'a',
}))

इस इफ़ेक्ट के बारे में ज़्यादा जानने के लिए, ओपन सोर्स लाइब्रेरी roving-ux देखें.

आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात)

इस पोस्ट के लिखने के समय तक, aspect-ratio के लिए सहायता Firefox में फ़्लैग के पीछे है लेकिन Chromium ब्राउज़र या सेट टॉप बॉक्स में उपलब्ध है. मीडिया स्क्रोलर ग्रिड लेआउट में सिर्फ़ दिशा और स्पेस का इस्तेमाल किया जाता है. इसलिए, मीडिया क्वेरी के हिसाब से साइज़ बदला जा सकता है. इससे यह जांच की जाती है कि वीडियो के आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) सही है या नहीं. कुछ और डाइनैमिक मीडिया स्क्रोलर में प्रगतिशील बेहतर बनाने की सुविधा.

16:9 और 4:3 के आसपेक्ट रेशियो वाले डिज़ाइन के बगल में, 4:4 आसपेक्ट रेशियो वाला बॉक्स दिखाया गया है

@supports (aspect-ratio: 1) {
  .horizontal-media-scroller figure > picture {
    inline-size: auto; /* for a block-size driven ratio */
    aspect-ratio: 1; /* boxes by default */

    @nest section:nth-child(2) & {
      aspect-ratio: 16/9;
    }

    @nest section:nth-child(3) & {
      /* double the size of the others */
      block-size: calc(var(--size) * 2);
      aspect-ratio: 4/3;

      /* adjust size to fit more items into the viewport */
      @media (width <= 480px) {
        block-size: calc(var(--size) * 1.5);
      }
    }
  }
}

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

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

कम डेटा का इस्तेमाल करना

यह अगली तकनीक, Canary में सिर्फ़ फ़्लैग के पीछे उपलब्ध है. हालांकि, हम आपको बताना चाहते हैं कि सीएसएस की कुछ लाइनों की मदद से, पेज लोड होने में लगने वाले समय और डेटा के इस्तेमाल को कैसे कम किया जा सकता है. लेवल 5 की prefers-reduced-data मीडिया क्वेरी से यह पूछा जाता है कि क्या डिवाइस में डेटा सेवर मोड जैसी किसी कम डेटा स्थिति में है. अगर ऐसा है, तो उस दस्तावेज़ में बदलाव करके इमेज को छिपाया जा सकता है.

ALT_TEXT_HERE

figure {
  @media (prefers-reduced-data: reduce) {
    & {
      min-inline-size: var(--size);

      & > picture {
        display: none;
      }
    }
  }
}

कॉन्टेंट अब भी नेविगेट किया जा सकता है. हालांकि, इसके लिए बड़ी इमेज डाउनलोड करने की ज़रूरत नहीं होती. prefers-reduced-data सीएसएस जोड़ने से पहले, साइट की इमेज यहां दी गई है:

(सात अनुरोध, 131 मिलीसेकंड में 100 केबी के संसाधन)

ALT_TEXT_HERE

prefers-reduced-data CSS जोड़ने के बाद, साइट की परफ़ॉर्मेंस यहां दी गई है:

ALT_TEXT_HERE

(71 अनुरोध, 1.07 सेकंड में 1.2 एमबी के संसाधन)

64 कम अनुरोध होते हैं, जो इस ब्राउज़र टैब के व्यूपोर्ट (चौड़ी स्क्रीन के डिसप्ले पर की गई जांच) के ~60 चित्र होंगे, पेज लोड में करीब 80% का इज़ाफ़ा होगा और तार पर डेटा का 10% ज़्यादा होगा. काफ़ी असरदार सीएसएस.

नतीजा

अब आपको पता है कि मैंने इसे कैसे किया, तो आप इसे कैसे करेंगे?! 🙂

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

सोर्स

कम्यूनिटी रीमिक्स

फ़िलहाल, यहां कोई कॉन्टेंट मौजूद नहीं है!