स्टाइल वाला प्रोग्रेस बार बनाना

<progress> एलिमेंट, किसी टास्क के पूरा होने की प्रोग्रेस को दिखाने का एक सिमैंटिक तरीका है. जैसे, जानकारी डाउनलोड या अपलोड करना या कई चरणों वाली प्रोसेस का कोई हिस्सा पूरा करना. नेटिव एलिमेंट का इस्तेमाल करने से, सुलभता में मदद मिलती है. ऐसा इसलिए, क्योंकि स्क्रीन रीडर में पहले से ही role="progressbar" मौजूद होता है और वे वैल्यू की जानकारी दे सकते हैं.

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

प्रोग्रेस बार या प्रोग्रेस दिखाने वाली रिंग?

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

मार्कअप

  1. नेटिव <progress> एलिमेंट का इस्तेमाल करें: इससे पहले से मौजूद सुलभता सुविधाएं और प्लैटफ़ॉर्म के हिसाब से एक जैसा व्यवहार मिलता है.
  2. अगर डिफ़ॉल्ट 0-1 स्केल के बजाय किसी दूसरे स्केल की ज़रूरत है, तो max का इस्तेमाल करें.
  3. प्रोग्रेस की किसी खास वैल्यू के लिए, value एट्रिब्यूट सेट करें. अनिश्चित स्थिति के लिए value को छोड़ दें. उदाहरण के लिए, ज़्यादा ठोस सुझाव/राय मिलने से पहले.
  4. प्रोग्रेस एलिमेंट को किसी लेबल से जोड़ने के लिए, <label for="...">, aria-labelledby या aria-label का इस्तेमाल करें.

आपको किस तरह का कस्टमाइज़ेशन चाहिए?

अगर आपको सीमित स्टाइलिंग करनी है, तो ये प्रॉपर्टी काफ़ी हैं:

  • प्रोग्रेस बार का रंग बदलने के लिए accent-color
  • प्रोग्रेस बार की चौड़ाई बदलने के लिए, width / inline-size
  • height/block-size को अलग-अलग तरह से लागू किया जाता है — पहले टेस्ट करें
  • वर्टिकल बार के लिए writing-mode: vertical-lr.
  • पेंट करने के बाद लागू होने वाले इफ़ेक्ट: opacity, filter, clip-path, मास्क, ट्रांसफ़ॉर्म, box-shadow वगैरह.

अगर सीमित स्टाइलिंग से काम चल जाता है, तो अगले सेक्शन को छोड़ दें.

चेतावनी: कुछ प्रॉपर्टी (जैसे, border-radius, background, border) डिफ़ॉल्ट प्रोग्रेस बार की स्टाइल को बिना किसी सूचना के बंद कर देंगी. अगर आपको ऊपर बताई गई प्रॉपर्टी के अलावा, स्टाइलिंग की ज़रूरत है, तो आपको पूरी तरह से कस्टम स्टाइलिंग लागू करनी होगी. इसके बारे में अगले सेक्शन में बताया गया है. "शायद यह काम कर जाए" सोचकर, ज़्यादा स्टाइलिंग लागू न करें.

पसंद के मुताबिक स्टाइलिंग

1. बुनियादी सेटअप

  • ज़रूरी: पसंद के मुताबिक स्टाइल बनाने की सुविधा चालू करने के लिए, appearance: none का इस्तेमाल करें.
  • border: 0 solid के साथ यूक्रेन की सीमाओं को रीसेट करें
  • ऐक्टिव बार को एलिमेंट के बॉर्डर-रेडियस पर क्लिप करने के लिए, overflow: clip का इस्तेमाल करें या बार पर वही border-radius लागू करें. बार पर border-radius: inherit का इस्तेमाल न करें. यह शैडो डीओएम में एलिमेंट के खास स्ट्रक्चर पर निर्भर करता है.
progress {
  /* Reset default browser styles */
  appearance: none;
  border: 0 solid;
  /* Clip bar to element’s border-radius  */
  overflow: clip;
}

2. शैलीकृत करना

  • ट्रैक को स्टाइल करने के लिए, progress एलिमेंट का इस्तेमाल करें.
  • प्रोग्रेस बार को टारगेट करने के लिए, ब्राउज़र के हिसाब से सही सूडो-एलिमेंट का इस्तेमाल करें: WebKit/Blink के लिए ::-webkit-progress-value और Firefox के लिए ::-moz-progress-bar.
  • ज़रूरी: -webkit- और -moz- स्यूडो-एलिमेंट को एक ही नियम में ग्रुप न करें. नियम को अमान्य माना जाएगा और उसे अनदेखा कर दिया जाएगा. :is() और :where() यहां काम नहीं करते, क्योंकि इनमें सूडो-एलिमेंट काम नहीं करते.
  • ब्राउज़र को टारगेट करने वाला हर सूडो-एलिमेंट, सिर्फ़ एक बार दिखना चाहिए. स्टेट के हिसाब से किए जाने वाले कस्टमाइज़ेशन (जैसे, इंडिटर्मिनेट सेगमेंट का साइज़ और ऐनिमेशन), progress एलिमेंट पर सेट की गई कस्टम प्रॉपर्टी के ज़रिए रूट किए जाने चाहिए.
  • ज़रूरी नहीं: फ़िल पर ट्रांज़िशन inline-size, ताकि तय की गई वैल्यू में होने वाले बदलाव, जंप करने के बजाय ऐनिमेट हों. Firefox, लेआउट में फ़िल को साइज़ देता है और उसे अनदेखा कर देता है. इससे कोई नुकसान नहीं होता.
progress {
  --progress-bar-radius: 1e5px;
  border-radius: var(--progress-bar-radius);
  /* Apply color for custom progress track (background) */
  background: var(--progress-bar-track, var(--color-neutral-90));
  /* Subtle depth on the empty part of the track */
  box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.1);
}

/* Let <progress> styling show through */
progress::-webkit-progress-bar {
  background: transparent;
}

/* Webkit, Chrome */
progress::-webkit-progress-value {
  background: var(--progress-bar-fill, var(--accent-color));
  border-radius: var(--progress-bar-radius);
  transition: inline-size 0.3s;
}

/* Firefox */
progress::-moz-progress-bar {
  background: var(--progress-bar-fill, var(--accent-color));
  border-radius: var(--progress-bar-radius);
  transition: inline-size 0.3s;
}

3. अनिश्चित स्थिति की स्टाइलिंग

अनिश्चित स्थिति के लिए कस्टम ऐनिमेशन जोड़ना: फ़िल स्यूडो-एलिमेंट को एक छोटे सेगमेंट में बदलें और उसे ट्रैक के साथ स्लाइड करें.

  • फ़िल को खुद स्टाइल करें; इसे progress पर बैकग्राउंड के तौर पर फिर से न बनाएं.
  • अनिश्चित फ़िल सिर्फ़ अपने ऐनिमेशन के ज़रिए मौजूद होता है: कीफ़्रेम इसकी लंबाई को असल inline-size के साथ सेट करते हैं (यह Chromium के यूए इनलाइन inline-size को मात देता है) और इसे translate के साथ मूव करते हैं. लंबाई के लिए scale का इस्तेमाल न करें. इससे फ़िल पर पेंट किया गया कोई भी पैटर्न खराब हो जाता है.
  • translate प्रतिशत, फ़िल की अपनी चौड़ाई के हिसाब से रिज़ॉल्व होते हैं. इसलिए, पोज़िशन को ट्रैक यूनिट में दिखाएं: progress को इनलाइन-साइज़ कंटेनर बनाएं और कीफ़्रेम में cqi का इस्तेमाल करें. margin-right: auto को from, to में शामिल करें, ताकि Chromium, आरटीएल में भी फ़िल आउट को बाईं ओर रखे.
  • फ़िल को मूव करने के लिए, मार्जिन के बजाय ट्रांसफ़ॉर्म का इस्तेमाल करें.
    • ट्रांसफ़ॉर्म, ऐनिमेशन को कंपोज़िटर में रखते हैं. हालांकि, ऐसा तब नहीं होता, जब inline-size को भी ऐनिमेट किया जा रहा हो
    • आरटीएल में मार्जिन दो अलग-अलग वजहों से टूटते हैं:
    • Firefox, इंडिटरमिनेट फ़िल को सिर्फ़ अपने फ़िज़िकल लेफ़्ट मार्जिन का इस्तेमाल करके पोज़िशन करता है. इसलिए, आरटीएल में margin-inline-start का कोई असर नहीं पड़ता और फ़िल कभी मूव नहीं होता.
    • Chromium और WebKit में, फ़िल को सामान्य ब्लॉक के तौर पर दिखाया जाता है. जब मार्जिन, फ़िल को ट्रैक के आखिर से आगे धकेलता है, तो मार्जिन, ट्रैक से ज़्यादा हो जाते हैं. स्टैंडर्ड सीएसएस, आरटीएल में margin-left को अनदेखा करके इस समस्या को हल करती है. इससे सेगमेंट, स्लाइड होने के बजाय किनारे पर चला जाता है.
    • translate को लेआउट के बाद लागू किया जाता है. इसलिए, इनमें से कोई भी समस्या लागू नहीं होती.
  • दाएं से बाएं लिखे जाने वाले टेक्स्ट में मोशन को मिरर करने के लिए, :dir(rtl) में ऐनिमेशन को उलटें. Chrome का नेटिव बार भी ऐसा ही करता है:
progress:dir(rtl) {
  --progress-bar-indeterminate-animation: progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear reverse;
}
  • progress पर सार्वजनिक --progress-bar-indeterminate-* प्रॉपर्टी तय करें (उनके नाम से ही पता चलता है कि वे स्टेट से जुड़ी हैं), ताकि उपभोक्ता :indeterminate के बारे में जाने बिना उन्हें बदल सकें.
  • सेगमेंट की लंबाई में बदलाव करने के लिए (उदाहरण के लिए, लीडिंग एज आगे बढ़ता है और ट्रेलिंग एज उसे पकड़ लेता है), --progress-bar-indeterminate-animation को एक साथ दो ऐनिमेशन पर सेट करें: एक ऐसा ऐनिमेशन जिसके कीफ़्रेम cqi (पोज़िशन) में translate को ऐनिमेट करते हैं और दूसरा ऐसा ऐनिमेशन जिसके कीफ़्रेम inline-size (लंबाई) को ऐनिमेट करते हैं. इससे हर ऐनिमेशन को अपने कीफ़्रेम और ईज़िंग मिलती है. एक ही कीफ़्रेम सूची में दोनों किनारों को आकार देने की कोशिश न करें. हर कीफ़्रेम के लिए animation-timing-function, उस कीफ़्रेम की हर प्रॉपर्टी पर लागू होता है.
  • --progress-bar-animation, दोनों स्थितियों में लागू होता है. इसका इस्तेमाल, तय की गई चमक जैसे इफ़ेक्ट के लिए किया जा सकता है. revert-rule का इस्तेमाल, सेट किए जाने पर ही ओवरराइड करने के लिए किया जाता है. इससे कंपोज़ेबिलिटी को बढ़ाया जा सकता है.
  • अनिश्चित ऐनिमेशन को कभी बंद न करें (animation: none Chromium में शून्य-चौड़ाई वाला फ़िल छोड़ता है). अगर आपको मोशन कम करना है, तो इसकी स्पीड कम करें.
progress {
  /* Lets the fill position itself in track units (cqi) */
  container-type: inline-size;
  /* Segment length relative to the track */
  --progress-bar-indeterminate-size: 30%;
  --progress-bar-indeterminate-animation-duration: 1.5s;

  /* Respect prefers-reduced-motion */
  @media (prefers-reduced-motion: reduce) {
    --progress-bar-indeterminate-animation-duration: 10s;
  }
}

progress:indeterminate {
  --progress-bar-animation: var(
      --progress-bar-indeterminate-animation,
      progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear
    );
}

/* Add to the existing pseudo-element rules */
progress::-webkit-progress-value {
  animation: var(--progress-bar-animation, revert-rule);
}

progress::-moz-progress-bar {
  animation: var(--progress-bar-animation, revert-rule);
}

/* Physical: left to right regardless of direction (reverse under :dir(rtl) to mirror). */
@keyframes progress-bar-indeterminate {
  from, to {
    inline-size: var(--progress-bar-indeterminate-size);
    /* Pin to the physical left; Chromium would otherwise lay the fill out at the inline start */
    margin-right: auto;
  }
  from { translate: -100%; } /* Own width: fully outside the left edge */
  to { translate: 100cqi; }  /* Track width: fully outside the right edge */
}

सुलभता से जुड़ी अन्य ज़रूरी बातें

ऊपर बताए गए दिशा-निर्देशों के अलावा:

  • उपयोगकर्ता का ध्यान भटकाए बिना, टास्क पूरा होने की सूचना दें: <progress> पर tabindex सेट न करें या .focus() को कॉल न करें. ऐसा इसलिए, क्योंकि यह इंटरैक्टिव नहीं है और इस पर फ़ोकस ले जाने से, कीबोर्ड का इस्तेमाल करने वाले उपयोगकर्ताओं को परेशानी होती है. बैकग्राउंड में चल रहे किसी टास्क के पूरा होने की सूचना देने के लिए, स्टेटस एलिमेंट (role="status" या aria-live="polite") को अपडेट करें.
  • <progress> के अंदर फ़ॉलबैक टेक्स्ट न जोड़ें: <progress> के अंदर मौजूद टेक्स्ट को मॉडर्न ब्राउज़र अनदेखा कर देते हैं. साथ ही, सहायक टेक्नोलॉजी इसका इस्तेमाल नहीं करती हैं.
  • बिना लेबल वाले सामान्य <div> पर aria-busy + aria-describedby का इस्तेमाल न करें. aria-busy में स्क्रीन रीडर की सुविधा हर समय एक जैसा काम नहीं करती. साथ ही, सहायक टेक्नोलॉजी, बिना नाम वाले <div> पर मौजूद aria-describedby को अनदेखा कर देती हैं. अगर लोड होने के दौरान किसी क्षेत्र का कॉन्टेंट तैयार नहीं है, तो उसे hidden या aria-hidden="true" से छिपाएं.
  • कस्टम स्टाइल जोड़ते समय, प्रोग्रेस बार और ट्रैक के बीच सही कंट्रास्ट रखें.
  • अनिश्चित स्थिति दिखाने के लिए अन्य विकल्पों पर विचार करें: अन्य कॉन्टेंट के साथ दिखाए जाने वाले अनिश्चित प्रोग्रेस बार के ऐनिमेशन, कुछ उपयोगकर्ताओं का ध्यान भटका सकते हैं.

फ़ॉलबैक रणनीतियां

accent-color के लिए फ़ॉलबैक और ब्राउज़र सहायता

accent-color प्रॉपर्टी, परतदार वृद्धि है. इस प्रॉपर्टी के साथ काम न करने वाले ब्राउज़र, इसे अनदेखा कर देंगे और अपने डिफ़ॉल्ट यूज़र इंटरफ़ेस (यूआई) के रंगों का इस्तेमाल करेंगे.

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

revert-rule के लिए फ़ॉलबैक और ब्राउज़र सहायता

अगर revert-rule काम नहीं करता है, तो animation: var(--progress-bar-animation, revert-rule), animation-name: revert-rule पर वापस आ जाता है. साथ ही, --progress-bar-animation के सेट न होने पर, 0s की अवधि के साथ वापस आ जाता है. यह एक नुकसान न पहुंचाने वाला नो-ऑप है, जो @keyframes revert-rule के मौजूद न होने पर होता है.