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

<progress> एलिमेंट की मदद से, ऐसे लोडिंग बार के बारे में खास जानकारी जिसमें रंगों के हिसाब से और आसानी से इस्तेमाल किए जा सकने वाले लोडिंग बार बनाए जा सकते हैं.

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

Chrome पर, हल्के और गहरे रंग के साथ-साथ, 'जानकारी नहीं है', 'बढ़ रहा है', और 'पूरा हो गया' स्टेटस का डेमो.

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

खास जानकारी

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

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

हर ब्राउज़र में लाइट और डार्क टैब, जो ऊपर से नीचे तक, 
    अडैप्टिव आइकॉन की खास जानकारी देते हैं: 
    Safari, Firefox, Chrome.
डेमो को Firefox, Safari, iOS Safari, Chrome, और Android Chrome पर, लाइट और डार्क स्कीम में दिखाया गया है.

मार्कअप

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

<progress></progress>

अगर कोई value नहीं है, तो एलिमेंट की प्रोग्रेस अनजान है. max एट्रिब्यूट की डिफ़ॉल्ट वैल्यू 1 होती है. इसलिए, प्रोग्रेस 0 से 1 के बीच होती है. उदाहरण के लिए, max को 100 पर सेट करने पर, रेंज 0 से 100 पर सेट हो जाएगी. मैंने 0 और 1 की सीमा के अंदर जाना चुना और प्रोग्रेस की वैल्यू को 0.5 या 50% किया.

लेबल में रैप की गई प्रोग्रेस

इंप्लिसिट संबंध में, प्रोग्रेस एलिमेंट को इस तरह के लेबल से रैप किया जाता है:

<label>Loading progress<progress></progress></label>

अपने डेमो में, मैंने सिर्फ़ स्क्रीन रीडर के लिए लेबल शामिल करने का विकल्प चुना था. इसके लिए, लेबल टेक्स्ट को <span> में रैप करें और उसमें कुछ स्टाइल लागू करें. इससे वह स्क्रीन के बाहर भी दिखेगा:

<label>
  <span class="sr-only">Loading progress</span>
  <progress></progress>
</label>

WebAIM के साथ जुड़े सीएसएस के साथ:

.sr-only {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

सिर्फ़ स्क्रीन के लिए तैयार एलिमेंट दिखाने वाले डेवलपर टूल का स्क्रीनशॉट.

डेटा लोड होने की प्रोसेस के स्टेटस पर असर पड़ा है

अगर आपकी आंखों की रोशनी अच्छी है, तो प्रोग्रेस इंडिकेटर को मिलते-जुलते एलिमेंट और पेज के हिस्सों से जोड़ना आसान हो सकता है. हालांकि, जिन लोगों की आंखों की रोशनी कम है उनके लिए यह इतना आसान नहीं है. सबसे ऊपर मौजूद उस एलिमेंट को aria-busy एट्रिब्यूट असाइन करके इसे बेहतर बनाएं जो लोड होने के बाद बदल जाएगा. इसके अलावा, aria-describedby की मदद से, प्रोग्रेस और लोडिंग ज़ोन के बीच संबंध दिखाएं.

<main id="loading-zone" aria-busy="true">
  …
  <progress aria-describedby="loading-zone"></progress>
</main>

JavaScript से, टास्क की शुरुआत में aria-busy को true पर और पूरा हो जाने पर false पर टॉगल करें.

ARIA एट्रिब्यूट जोड़े गए

<progress> एलिमेंट की भूमिका progressbar है. हालांकि, मैंने उन ब्राउज़र के लिए इसे साफ़ तौर पर बताया है जिनमें यह भूमिका नहीं है. मैंने एलिमेंट को साफ़ तौर पर 'जानकारी नहीं है' स्थिति में रखने के लिए, एट्रिब्यूट indeterminate भी जोड़ा है. यह एलिमेंट के लिए value सेट न होने की तुलना में ज़्यादा साफ़ तौर पर जानकारी देता है.

<label>
  Loading 
  <progress 
    indeterminate 
    role="progressbar" 
    aria-describedby="loading-zone"
    tabindex="-1"
  >unknown</progress>
</label>

JavaScript से प्रोग्रेस एलिमेंट पर फ़ोकस करने के लिए, tabindex="-1" का इस्तेमाल करें. यह स्क्रीन रीडर टेक्नोलॉजी के लिए ज़रूरी है, क्योंकि प्रोग्रेस में बदलाव होने पर फ़ोकस देने से, उपयोगकर्ता को यह जानकारी मिलेगी कि अपडेट की गई प्रोग्रेस कितनी तक पहुंची है.

स्टाइल

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

लेआउट

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

<progress> लेआउट

प्रोग्रेस एलिमेंट की चौड़ाई में कोई बदलाव नहीं किया जाता, ताकि डिज़ाइन में ज़रूरत के हिसाब से इसे छोटा और बड़ा किया जा सके. appearance और border को none पर सेट करके, बिल्ट-इन स्टाइल हटाए जाते हैं. ऐसा इसलिए किया जाता है, ताकि एलिमेंट को सभी ब्राउज़र पर नॉर्मलाइज़ किया जा सके, क्योंकि हर ब्राउज़र के एलिमेंट की अपनी स्टाइल होती है.

progress {
  --_track-size: min(10px, 1ex);
  --_radius: 1e3px;

  /*  reset  */
  appearance: none;
  border: none;

  position: relative;
  height: var(--_track-size);
  border-radius: var(--_radius);
  overflow: hidden;
}

_radius के लिए 1e3px की वैल्यू, बड़ी संख्या को दिखाने के लिए वैज्ञानिक संख्या के नोटेशन का इस्तेमाल करती है, ताकि border-radius को हमेशा राउंड किया जा सके. यह 1000px के बराबर है. मुझे इसका इस्तेमाल करना पसंद है क्योंकि मेरा लक्ष्य इतने बड़े मान का उपयोग करना है कि मैं इसे सेट कर सकूं और भूल जाऊं (और इसमें 1000px से कम लिखना भी आसान है). ज़रूरत पड़ने पर इसे और भी बड़ा करना भी आसान है: बस 3 को 4 में बदलें, फिर 1e4px 10000px के बराबर होगी.

overflow: hidden का इस्तेमाल किया जाता है और यह एक विवादित स्टाइल है. इससे कुछ चीज़ें आसान हो गईं, जैसे कि ट्रैक और ट्रैक फ़िल एलिमेंट में border-radius वैल्यू पास करने की ज़रूरत नहीं पड़ना. हालांकि, इसका मतलब यह भी था कि प्रोग्रेस बार के कोई भी चाइल्ड एलिमेंट, एलिमेंट के बाहर नहीं हो सकता. इस कस्टम प्रोग्रेस एलिमेंट को overflow: hidden के बिना भी इस्तेमाल किया जा सकता है. इससे ऐनिमेशन या प्रोसेस पूरी होने की बेहतर स्थितियों के लिए कुछ अवसर मिल सकते हैं.

प्रोसेस पूर्ण

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

progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
  content: "✓";
  
  position: absolute;
  inset-block: 0;
  inset-inline: auto 0;
  display: flex;
  align-items: center;
  padding-inline-end: max(calc(var(--_track-size) / 4), 3px);

  color: white;
  font-size: calc(var(--_track-size) / 1.25);
}

लोडिंग बार के 100% होने और आखिर में सही का निशान दिखाने का स्क्रीनशॉट.

रंग

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

ब्राउज़र के हल्के और गहरे रंग वाले स्टाइल

अपनी साइट को डार्क और लाइट ऐडेप्टिव <progress> एलिमेंट में ऑप्ट इन करने के लिए, color-scheme की ज़रूरत होती है.

progress {
  color-scheme: light dark;
}

किसी एक प्रॉपर्टी की प्रोग्रेस को भरने के लिए इस्तेमाल किया जाने वाला रंग

<progress> एलिमेंट की रंगत बदलने के लिए, accent-color का इस्तेमाल करें.

progress {
  accent-color: rebeccapurple;
}

ध्यान दें कि accent-color के आधार पर, ट्रैक के बैकग्राउंड का रंग हल्के से गहरे में बदलता है. ब्राउज़र, सही कंट्रास्ट का इस्तेमाल कर रहा है: काफ़ी अच्छा.

पूरी तरह से पसंद के मुताबिक हल्के और गहरे रंग

<progress> एलिमेंट पर दो कस्टम प्रॉपर्टी सेट करें. एक ट्रैक के रंग के लिए और दूसरी ट्रैक की प्रोग्रेस के रंग के लिए. prefers-color-scheme मीडिया क्वेरी में, ट्रैक और ट्रैक की प्रोग्रेस के लिए नई कलर वैल्यू दें.

progress {
  --_track: hsl(228 100% 90%);
  --_progress: hsl(228 100% 50%);
}

@media (prefers-color-scheme: dark) {
  progress {
    --_track: hsl(228 20% 30%);
    --_progress: hsl(228 100% 75%);
  }
}

फ़ोकस स्टाइल

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

progress:focus-visible {
  outline-color: var(--_progress);
  outline-offset: 5px;
}

लोडिंग बार का स्क्रीनशॉट, जिसके आस-पास फ़ोकस रिंग मौजूद है. सभी रंग एक जैसे हों.

सभी ब्राउज़र पर कस्टम स्टाइल

<progress> एलिमेंट के उन हिस्सों को चुनकर स्टाइल को पसंद के मुताबिक बनाएं जिन्हें हर ब्राउज़र दिखाता है. प्रोग्रेस एलिमेंट का इस्तेमाल करने पर, एक टैग बनता है. हालांकि, यह कुछ चाइल्ड एलिमेंट से बना होता है, जिन्हें सीएसएस सूडो सिलेक्टर की मदद से दिखाया जाता है. सेटिंग चालू करने पर, Chrome DevTools आपको ये एलिमेंट दिखाएगा:

  1. DevTools खोलने के लिए, अपने पेज पर राइट क्लिक करें और एलिमेंट की जांच करें चुनें.
  2. DevTools विंडो के सबसे ऊपर दाएं कोने में मौजूद, सेटिंग गियर पर क्लिक करें.
  3. एलिमेंट हेडिंग में जाकर, उपयोगकर्ता एजेंट के लिए शैडो डोमेन दिखाएं चेकबॉक्स ढूंढें और उसे चालू करें.

DevTools में, उपयोगकर्ता एजेंट के शैडो DOM को एक्सपोज़ करने की सुविधा चालू करने की जगह का स्क्रीनशॉट.

Safari और Chromium स्टाइल

Safari और Chromium जैसे वेबवर्क पर आधारित ब्राउज़र, ::-webkit-progress-bar और ::-webkit-progress-value को एक्सपोज़ करते हैं. इनकी मदद से, सीएसएस के सबसेट का इस्तेमाल किया जा सकता है. फ़िलहाल, पहले बनाई गई कस्टम प्रॉपर्टी का इस्तेमाल करके background-color सेट करें. ये प्रॉपर्टी, रोशनी और अंधेरे के हिसाब से ढल जाती हैं.

/*  Safari/Chromium  */
progress[value]::-webkit-progress-bar {
  background-color: var(--_track);
}

progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
}

प्रोग्रेस एलिमेंट के अंदरूनी एलिमेंट दिखाने वाला स्क्रीनशॉट.

Firefox के स्टाइल

Firefox, सिर्फ़ <progress> एलिमेंट पर ::-moz-progress-bar स्यूडो सिलेक्टर दिखाता है. इसका मतलब यह भी है कि हम ट्रैक को सीधे तौर पर रंग नहीं सकते.

/*  Firefox  */
progress[value]::-moz-progress-bar {
  background-color: var(--_progress);
}

Firefox का स्क्रीनशॉट और प्रोग्रेस एलिमेंट के हिस्सों को ढूंढने की जगह.

डीबगिंग कॉर्नर का स्क्रीनशॉट, जिसमें Safari, iOS Safari, 
  Firefox, Chrome, और Android पर Chrome के लिए, लोडिंग बार काम करते हुए दिखाया गया है.

ध्यान दें कि Firefox में ट्रैक का रंग accent-color सेट है, जबकि iOS Safari में हल्का नीला ट्रैक है. गहरे रंग वाले मोड में भी ऐसा ही होता है: Firefox में गहरे रंग का ट्रैक होता है, लेकिन उसमें हमारे तय किए गए कस्टम रंग नहीं होते. साथ ही, यह Webkit पर आधारित ब्राउज़र में काम करता है.

ऐनिमेशन

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

ऐनिमेशन के ज़रिए ट्रैक भरा जा रहा है

प्रोग्रेस एलिमेंट के inline-size में ट्रांज़िशन जोड़ने पर, यह Chromium पर काम करता है, लेकिन Safari पर नहीं. Firefox अपने ::-moz-progress-bar पर भी ट्रांज़िशन प्रॉपर्टी का इस्तेमाल नहीं करता.

/*  Chromium Only 😢  */
progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
  transition: inline-size .25s ease-out;
}

:indeterminate स्थिति को ऐनिमेट किया जा रहा है

यहां मैं थोड़ा और क्रिएटिव हूं, ताकि मैं ऐनिमेशन दे सकूं. Chromium के लिए एक स्यूडो-एलिमेंट बनाया जाता है और एक ग्रेडिएंट लागू किया जाता है, जो तीनों ब्राउज़र के लिए आगे-पीछे ऐनिमेशन किया जाता है.

कस्टम प्रॉपर्टी

कस्टम प्रॉपर्टी कई चीज़ों के लिए बेहतरीन होती हैं, लेकिन मेरी पसंदीदा प्रॉपर्टी में से एक सीएसएस वैल्यू को जादुई रूप से नाम देना है. यहां एक ऐसा linear-gradient दिया गया है जो काफ़ी जटिल है, लेकिन इसका नाम अच्छा है. इसके मकसद और इस्तेमाल के उदाहरणों को साफ़ तौर पर समझा जा सकता है.

progress {
  --_indeterminate-track: linear-gradient(to right,
    var(--_track) 45%,
    var(--_progress) 0%,
    var(--_progress) 55%,
    var(--_track) 0%
  );
  --_indeterminate-track-size: 225% 100%;
  --_indeterminate-track-animation: progress-loading 2s infinite ease;
}

कस्टम प्रॉपर्टी से कोड को DRY बनाए रखने में भी मदद मिलेगी, क्योंकि हम ब्राउज़र के हिसाब से इन सिलेक्टर को एक साथ ग्रुप नहीं कर सकते.

मुख्य फ़्रेम

इसका लक्ष्य, हमेशा लूप में चलने वाला ऐनिमेशन बनाना है. शुरू और खत्म होने के कीफ़्रेम, सीएसएस में सेट किए जाएंगे. ऐसा ऐनिमेशन बनाने के लिए, सिर्फ़ एक मुख्य फ़्रेम की ज़रूरत होती है. यह मुख्य फ़्रेम, 50% पर होता है. यह ऐनिमेशन, शुरू होने के बाद बार-बार उसी जगह पर वापस आता है!

@keyframes progress-loading {
  50% {
    background-position: left; 
  }
}

हर ब्राउज़र को टारगेट करना

हर ब्राउज़र, <progress> एलिमेंट पर स्यूडो-एलिमेंट बनाने या प्रोग्रेस बार को ऐनिमेट करने की अनुमति नहीं देता. स्यूडो-एलिमेंट के बजाय, ज़्यादातर ब्राउज़र में ट्रैक को ऐनिमेट किया जा सकता है. इसलिए, मैं छद्म-एलिमेंट को बेस के तौर पर और ऐनिमेट होने वाले बार में अपग्रेड करता हूं.

Chromium का स्यूडो-एलिमेंट

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

progress:indeterminate::after {
  content: "";
  inset: 0;
  position: absolute;
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Safari का प्रोग्रेस बार

Safari के लिए, कस्टम प्रॉपर्टी और ऐनिमेशन, सुडो-एलिमेंट प्रोग्रेस बार पर लागू किए जाते हैं:

progress:indeterminate::-webkit-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Firefox का प्रोग्रेस बार

Firefox के लिए, कस्टम प्रॉपर्टी और ऐनिमेशन, सुडो-एलिमेंट प्रोग्रेस बार पर भी लागू होते हैं:

progress:indeterminate::-moz-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}

JavaScript

<progress> एलिमेंट के साथ JavaScript अहम भूमिका निभाता है. यह एलिमेंट में भेजी गई वैल्यू को कंट्रोल करता है. साथ ही, यह पक्का करता है कि दस्तावेज़ में स्क्रीन रीडर के लिए ज़रूरी जानकारी मौजूद हो.

const state = {
  val: null
}

डेमो में, प्रोग्रेस को कंट्रोल करने के लिए बटन दिए गए हैं. ये state.val को अपडेट करते हैं और फिर DOM को अपडेट करने के लिए किसी फ़ंक्शन को कॉल करते हैं.

document.querySelector('#complete').addEventListener('click', e => {
  state.val = 1
  setProgress()
})

setProgress()

इस फ़ंक्शन में यूज़र इंटरफ़ेस (यूआई)/यूज़र अनुभव (यूएक्स) को ऑर्केस्ट्रेट किया जाता है. setProgress() फ़ंक्शन बनाकर शुरुआत करें. इसके लिए किसी पैरामीटर की ज़रूरत नहीं है, क्योंकि इसके पास state ऑब्जेक्ट, प्रोग्रेस एलिमेंट, और <main> ज़ोन का ऐक्सेस होता है.

const setProgress = () => {
  
}

<main> ज़ोन पर लोड होने की स्थिति सेट करना

प्रोग्रेस पूरी हो गई है या नहीं, इस आधार पर aria-busy एट्रिब्यूट के लिए, <main> एलिमेंट की वैल्यू को अपडेट करना ज़रूरी है:

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)
}

अगर लोड करने की रकम की जानकारी नहीं है, तो एट्रिब्यूट हटाएं

अगर वैल्यू अज्ञात है या सेट नहीं है, तो null इस इस्तेमाल में, value और aria-valuenow एट्रिब्यूट हटाएं. इससे <progress> की स्थिति 'जानकारी नहीं है' पर सेट हो जाएगी.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }
}

JavaScript में दशमलव वाले गणित से जुड़ी समस्याएं ठीक करना

मैंने प्रोग्रेस के लिए डिफ़ॉल्ट तौर पर 1 को चुना है. इसलिए, डेमो में प्रगति बढ़ाने और घटाने वाले फ़ंक्शन, दशमलव वाले गणित का इस्तेमाल करते हैं. JavaScript और दूसरी भाषाएँ, इसके लिए हमेशा अच्छी नहीं होतीं. यहां एक roundDecimals() फ़ंक्शन दिया गया है, जो गणित के नतीजे से अतिरिक्त वैल्यू हटा देगा:

const roundDecimals = (val, places) =>
  +(Math.round(val + "e+" + places)  + "e-" + places)

वैल्यू को राउंड करें, ताकि उसे दिखाया जा सके और उसे पढ़ा जा सके:

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"
}

स्क्रीन रीडर और ब्राउज़र की स्थिति के लिए वैल्यू सेट करना

वैल्यू का इस्तेमाल, DOM में तीन जगहों पर किया जाता है:

  1. <progress> एलिमेंट का value एट्रिब्यूट.
  2. aria-valuenow एट्रिब्यूट.
  3. <progress> का अंदरूनी टेक्स्ट कॉन्टेंट.
const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent
}

प्रोग्रेस पर फ़ोकस करना

वैल्यू अपडेट होने के बाद, जिन लोगों को देखने की क्षमता है उन्हें प्रोग्रेस में बदलाव दिखेगा. हालांकि, स्क्रीन रीडर का इस्तेमाल करने वाले लोगों को अब तक बदलाव की सूचना नहीं दी गई है. <progress> एलिमेंट पर फ़ोकस करें और ब्राउज़र अपडेट का एलान करेगा!

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent

  progress.focus()
}

Mac OS Voice Over ऐप्लिकेशन का स्क्रीनशॉट 
  जिसमें उपयोगकर्ता को लोडिंग बार की प्रोग्रेस पढ़कर सुनाई जा रही है.

नतीजा

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

अगर मुझे एक और मौका मिले, तो मैं कुछ बदलाव करना चाहूंगा. मुझे लगता है कि मौजूदा कॉम्पोनेंट को बेहतर बनाया जा सकता है. साथ ही, <progress> एलिमेंट के सूडो-क्लास स्टाइल की सीमाओं के बिना, एक नया कॉम्पोनेंट बनाया जा सकता है. इसे एक्सप्लोर करना ज़रूरी है!

आइए, अलग-अलग तरीकों का इस्तेमाल करके, वेब पर कॉन्टेंट बनाने के सभी तरीके जानें.

डेमो बनाएं और मुझे ट्वीट करें लिंक भेजें. हम इसे कम्यूनिटी रीमिक्स सेक्शन में जोड़ देंगे!

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