লোডিং বার কম্পোনেন্ট তৈরি করা

<progress> এলিমেন্ট ব্যবহার করে কীভাবে কালার অ্যাডাপ্টিভ ও অ্যাক্সেসিবল লোডিং বার তৈরি করা যায় তার একটি প্রাথমিক ওভারভিউ।

এই পোস্টে আমি <progress> এলিমেন্ট ব্যবহার করে কীভাবে কালার অ্যাডাপ্টিভ ও অ্যাক্সেসিবল লোডিং বার তৈরি করা যায় সেই বিষয়ে আমার চিন্তাভাবনা শেয়ার করতে চাই। ডেমো ব্যবহার করে দেখুন এবং সোর্স দেখুন!

Chrome-এ লাইট ও ডার্ক, অনির্দিষ্ট, ক্রমবর্ধমান ও সম্পূর্ণ হওয়ার ডেমো দেখানো হয়েছে।

আপনি ভিডিও দেখতে চাইলে, এই পোস্টের YouTube ভার্সন এখানে দেওয়া হল:

এক নজরে

<progress> এলিমেন্টটি ব্যবহারকারীদের সম্পূর্ণ হওয়ার বিষয়ে ভিজ্যুয়াল এবং অডিও প্রতিক্রিয়া প্রদান করে। এই ভিজ্যুয়াল ফিডব্যাক বিভিন্ন পরিস্থিতিতে মূল্যবান, যেমন: ফর্ম পূরণ করার প্রসেস, ডাউনলোড বা আপলোড সংক্রান্ত তথ্য দেখানো, এমনকি প্রসেস কতটা সম্পূর্ণ হয়েছে তা জানা না থাকলেও কাজ যে এখনও চলছে তা দেখানো।

এই GUI চ্যালেঞ্জ আগে থেকে থাকা HTML <progress> এলিমেন্টের সাথে কাজ করেছে যাতে অ্যাক্সেসিবিলিটির ক্ষেত্রে কিছু পরিশ্রম বাঁচানো যায়। রঙ এবং লেআউট বিল্ট-ইন এলিমেন্টের জন্য কাস্টমাইজেশনের সীমা বাড়ায়, যাতে কম্পোনেন্টকে আধুনিকীকরণ করা যায় এবং ডিজাইন সিস্টেমের মধ্যে এটি আরও ভালভাবে ফিট করে।

প্রতিটি ব্রাউজারে লাইট ও ডার্ক ট্যাব, উপর থেকে নিচ পর্যন্ত 
    অ্যাডাপ্টিভ আইকনের ওভারভিউ প্রদান করে: 
    Safari, Firefox, Chrome.
Firefox, Safari, iOS Safari, Chrome ও Android Chrome-এ লাইট ও ডার্ক স্কিমে ডেমো দেখানো হয়েছে।

Markup

আমি <progress> এলিমেন্টকে <label>-এর মধ্যে র‍্যাপ করার সিদ্ধান্ত নিয়েছি যাতে আমি স্পষ্ট সম্পর্ক অ্যাট্রিবিউট এড়িয়ে গিয়ে অন্তর্নিহিত সম্পর্ক ব্যবহার করতে পারি। এছাড়াও, আমি লোডিং স্টেট দ্বারা প্রভাবিত একটি পেরেন্ট এলিমেন্ট লেবেল করেছি, যাতে স্ক্রিন রিডার প্রযুক্তি ব্যবহারকারীকে সেই তথ্য রিলে করতে পারে।

<progress></progress>

value না থাকলে, এলিমেন্টের প্রোগ্রেস অনির্ধারিত। max অ্যাট্রিবিউটের ডিফল্ট মান হল ১, তাই অগ্রগতি ০ থেকে ১-এর মধ্যে হয়। max-এর মান ১০০ সেট করলে, রেঞ্জ ০-১০০ সেট হবে। আমি ০ এবং ১ সীমার মধ্যে থাকার সিদ্ধান্ত নিয়েছি, প্রগ্রেস ভ্যালু ০.৫ বা ৫০% এ অনুবাদ করেছি।

লেবেল-র‍্যাপ করা প্রোগ্রেস

একটি অন্তর্নিহিত সম্পর্কে, একটি প্রোগ্রেস এলিমেন্টকে এইরকম একটি লেবেল দ্বারা মোড়ানো হয়:

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

আমার ডেমোতে আমি শুধুমাত্র স্ক্রিন রিডার-এর জন্য লেবেল অন্তর্ভুক্ত করার বিকল্প বেছে নিয়েছি। এটি করার জন্য লেবেল টেক্সটকে <span>-এর মধ্যে র‍্যাপ করা হয় এবং কিছু স্টাইল প্রয়োগ করা হয় যাতে এটি স্ক্রিনে দেখা না যায়:

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

WebAIM থেকে নিম্নলিখিত CSS সহ:

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

স্ক্রিন রেডি অনলি এলিমেন্ট প্রকাশ করে devtools-এর স্ক্রিনশট।

লোডিং প্রোগ্রেস দ্বারা প্রভাবিত এলাকা

আপনার দৃষ্টিশক্তি ভাল হলে, সম্পর্কিত এলিমেন্ট ও পৃষ্ঠার অংশের সাথে প্রগ্রেস ইন্ডিকেটর সহজেই যুক্ত করতে পারবেন, তবে দৃষ্টিশক্তির সমস্যা যুক্ত ব্যবহারকারীদের ক্ষেত্রে এটি ততটা স্পষ্ট নয়। লোড করা সম্পূর্ণ হলে পরিবর্তন হবে এমন সবচেয়ে উপরের এলিমেন্টে aria-busy অ্যাট্রিবিউট অ্যাসাইন করে এটি উন্নত করুন। এছাড়াও, aria-describedby ব্যবহার করে প্রোগ্রেস ও লোডিং জোনের মধ্যে সম্পর্ক নির্দেশ করুন।

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

জাভাস্ক্রিপ্ট থেকে, টাস্কের শুরুতে aria-busy থেকে true-এ টগল করুন এবং শেষ হয়ে গেলে false-এ টগল করুন।

Aria অ্যাট্রিবিউট যোগ করা

<progress> এলিমেন্টের অন্তর্নিহিত ভূমিকা progressbar হলেও, আমি এটি সেইসব ব্রাউজারের জন্য স্পষ্ট করে দিয়েছি যেগুলিতে এই অন্তর্নিহিত ভূমিকা নেই। এছাড়াও, আমি এলিমেন্টকে অজানা অবস্থায় স্পষ্টভাবে রাখার জন্য indeterminate অ্যাট্রিবিউট যোগ করেছি, যা এলিমেন্টে কোনও value সেট করা নেই তা দেখার চেয়ে আরও স্পষ্ট।

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

জাভাস্ক্রিপ্ট থেকে প্রগ্রেস এলিমেন্ট ফোকাসযোগ্য করতে tabindex="-1" ব্যবহার করুন। এটি স্ক্রিন রিডার প্রযুক্তির জন্য গুরুত্বপূর্ণ, কারণ প্রগ্রেস পরিবর্তন হওয়ার সাথে সাথে প্রগ্রেস ফোকাস দিলে, আপডেট করা প্রগ্রেস কতদূর পৌঁছেছে তা ব্যবহারকারীকে ঘোষণা করবে।

স্টাইল

স্টাইলিংয়ের ক্ষেত্রে প্রোগ্রেস এলিমেন্ট একটু জটিল। বিল্ট-ইন HTML এলিমেন্টে বিশেষ লুকানো অংশ থাকে যা বেছে নেওয়া কঠিন হতে পারে এবং প্রায়শই সেট করার জন্য শুধুমাত্র সীমিত সংখ্যক প্রপার্টি অফার করে।

লেআউট

লেআউট স্টাইলগুলি প্রগ্রেস এলিমেন্টের আকার এবং লেবেলের অবস্থানে কিছু নমনীয়তার অনুমতি দেওয়ার উদ্দেশ্যে তৈরি করা হয়েছে। সম্পূর্ণ হওয়ার একটি বিশেষ স্ট্যাটাস যোগ করা হয়েছে যা সহায়ক হতে পারে, তবে অতিরিক্ত ভিজ্যুয়াল কিউয়ের প্রয়োজন নেই।

<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-এর চেয়ে ছোট)। এটি প্রয়োজন হলে আরও বড় করাও সহজ: শুধু ৩ থেকে ৪-এ পরিবর্তন করুন, তাহলে 1e4px 10000px-এর সমতুল্য হবে।

overflow: hidden ব্যবহার করা হয় এবং এটি একটি বিতর্কিত স্টাইল। এটি কিছু জিনিস সহজ করে তুলেছে, যেমন ট্র্যাকে border-radius মান পাস করার প্রয়োজন নেই, এবং ট্র্যাক ফিল এলিমেন্ট; তবে এর অর্থ এই যে প্রগ্রেসের কোনও চাইল্ড এলিমেন্টের বাইরে থাকতে পারবে না। এই কাস্টম প্রগ্রেস এলিমেন্টের আরেকটি ইটারেশন overflow: hidden ছাড়াই করা যেতে পারে এবং এটি অ্যানিমেশন বা আরও ভালভাবে সম্পূর্ণ করার অবস্থার জন্য কিছু সুযোগ খুলে দিতে পারে।

প্রগতি সম্পূর্ণ

CSS সিলেক্টর এখানে ভ্যালুর সাথে সর্বাধিকের তুলনা করে কঠিন কাজটি করে এবং যদি সেগুলি মিলে যায়, তাহলে প্রগ্রেস সম্পূর্ণ হয়। সম্পূর্ণ হলে, একটি ছদ্ম-এলিমেন্ট তৈরি করা হয় এবং প্রগ্রেস এলিমেন্টের শেষে যোগ করা হয়, যা সম্পূর্ণ হওয়ার জন্য একটি চমৎকার অতিরিক্ত ভিজ্যুয়াল ইঙ্গিত প্রদান করে।

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);
}

১০০% লোডিং বারের স্ক্রিনশট এবং শেষে একটি টিক চিহ্ন দেখানো হচ্ছে।

রঙ

ব্রাউজার প্রগ্রেস এলিমেন্টের জন্য নিজস্ব রঙ নিয়ে আসে এবং শুধুমাত্র একটি CSS প্রপার্টি ব্যবহার করে লাইট ও ডার্ক থিমের সাথে মানিয়ে নেয়। এটি কিছু বিশেষ ব্রাউজার-নির্দিষ্ট নির্বাচকের মাধ্যমে তৈরি করা যেতে পারে।

লাইট ও ডার্ক ব্রাউজার স্টাইল

আপনার সাইটকে ডার্ক ও লাইট অ্যাডাপ্টিভ <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> এলিমেন্টের অংশ বেছে নিয়ে স্টাইল কাস্টমাইজ করুন। প্রোগ্রেস এলিমেন্ট ব্যবহার করা হল একটি সিঙ্গেল ট্যাগ, তবে এটি কয়েকটি চাইল্ড এলিমেন্ট দিয়ে তৈরি যা CSS সিউডো সিলেক্টরের মাধ্যমে দেখানো হয়। আপনি সেটিং চালু করলে, Chrome DevTools আপনাকে এইসব এলিমেন্ট দেখাবে:

  1. DevTools চালু করতে আপনার পৃষ্ঠায় ডানদিকের বোতামে ক্লিক করে এলিমেন্ট পরীক্ষা করুন বিকল্প বেছে নিন।
  2. DevTools উইন্ডোর উপরে ডানদিকের কোণে সেটিংস গিয়ারে ক্লিক করুন।
  3. এলিমেন্ট হেডিংয়ের মধ্যে ইউজার এজেন্ট শ্যাডো DOM দেখান চেকবক্স খুঁজে নিয়ে চালু করুন।

DevTools-এ কোথায় ইউজার এজেন্ট শ্যাডো DOM এক্সপোজ করার সুবিধা চালু করতে হবে তার স্ক্রিনশট।

Safari ও Chromium স্টাইল

WebKit-ভিত্তিক ব্রাউজার যেমন Safari এবং Chromium ::-webkit-progress-bar এবং ::-webkit-progress-value প্রকাশ করে, যা CSS-এর একটি সাবসেট ব্যবহার করার অনুমতি দেয়। আপাতত, আগে তৈরি করা কাস্টম প্রপার্টি ব্যবহার করে 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-ভিত্তিক ব্রাউজারে কাজ করে।

অ্যানিমেশন

ব্রাউজারের বিল্ট-ইন সিউডো সিলেক্টর নিয়ে কাজ করার সময়, প্রায়শই অনুমোদিত CSS প্রপার্টির সীমিত সেট থাকে।

ট্র্যাক ফিল-আপ অ্যানিমেট করা হচ্ছে

প্রোগ্রেস এলিমেন্টের 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-এর জন্য একটি ছদ্ম-এলিমেন্ট তৈরি করা হয় এবং একটি গ্রেডিয়েন্ট প্রয়োগ করা হয় যা তিনটি ব্রাউজারের জন্যই অ্যানিমেট করা হয়।

কাস্টম প্রপার্টি

কাস্টম প্রপার্টি অনেক কিছুর জন্য দারুণ, তবে আমার প্রিয় একটি হল অন্যথায় জাদুকরী চেহারার CSS মানকে একটি নাম দেওয়া। নিচে একটি বেশ জটিল 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 রাখতেও সাহায্য করবে কারণ আমরা আবার এই ব্রাউজার-নির্দিষ্ট সিলেক্টরগুলিকে একসাথে গ্রুপ করতে পারব না।

কীফ্রেম

লক্ষ্য হল একটি অসীম অ্যানিমেশন যা সামনে এবং পিছনে যায়। শুরু ও শেষের কীফ্রেম CSS-এ সেট করা হবে। অ্যানিমেশন তৈরি করতে, যেটি বারবার যেখান থেকে শুরু হয়েছিল সেখানে ফিরে আসে, তার জন্য শুধু একটি কীফ্রেম প্রয়োজন, সেটি হল 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);
}

জাভাস্ক্রিপ্ট

<progress> এলিমেন্টের সাথে জাভাস্ক্রিপ্ট গুরুত্বপূর্ণ ভূমিকা পালন করে। এটি এলিমেন্টে পাঠানো ভ্যালু নিয়ন্ত্রণ করে এবং স্ক্রিন রিডারের জন্য ডকুমেন্টে পর্যাপ্ত তথ্য আছে কিনা তা নিশ্চিত করে।

const state = {
  val: null
}

ডেমোতে প্রগ্রেস কন্ট্রোল করার জন্য বোতাম থাকে; সেগুলি state.val আপডেট করে এবং তারপরে DOM আপডেট করার জন্য একটি ফাংশন কল করে।

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

setProgress()

এই ফাংশনে UI/UX অর্কেস্ট্রেশন হয়। setProgress() ফাংশন তৈরি করে শুরু করুন। কোনও প্যারামিটারের প্রয়োজন নেই কারণ এটির কাছে state অবজেক্ট, প্রোগ্রেস এলিমেন্ট ও <main> জোনের অ্যাক্সেস আছে।

const setProgress = () => {
  
}

<main> জোনে লোডিং স্ট্যাটাস সেট করা হচ্ছে

প্রোগ্রেস সম্পূর্ণ হয়েছে কিনা তার উপর নির্ভর করে, সংশ্লিষ্ট <main> এলিমেন্টকে aria-busy অ্যাট্রিবিউটে আপডেট করতে হবে:

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
  }
}

জাভাস্ক্রিপ্ট ডেসিমাল ম্যাথ সংক্রান্ত সমস্যার সমাধান করা

যেহেতু আমি প্রগ্রেস ডিফল্ট সর্বোচ্চ ১-এর সাথে লেগে থাকার সিদ্ধান্ত নিয়েছি, তাই ডেমো ইনক্রিমেন্ট এবং ডিক্রিমেন্ট ফাংশন দশমিক গণিত ব্যবহার করে। জাভাস্ক্রিপ্ট এবং অন্যান্য ভাষা, সবসময় এই কাজে পারদর্শী নয়। এখানে একটি 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 ভয়েস ওভার অ্যাপের স্ক্রিনশট 
  ব্যবহারকারীকে লোডিং বারের প্রোগ্রেস পড়ে শোনাচ্ছে।

উপসংহার

আমি কীভাবে করেছি তা তো জানলে, তুমি কীভাবে করবে‽ 🙂

আরেকটি সুযোগ পেলে আমি অবশ্যই কিছু পরিবর্তন করতে চাই। আমার মনে হয়, বর্তমান কম্পোনেন্ট ক্লিন-আপ করার সুযোগ আছে এবং <progress> এলিমেন্টের সিউডো-ক্লাস স্টাইল সংক্রান্ত সীমাবদ্ধতা ছাড়াই একটি কম্পোনেন্ট তৈরি করার চেষ্টা করার সুযোগ আছে। এটি এক্সপ্লোর করার মতো!

আসুন, আমাদের দৃষ্টিভঙ্গিকে বৈচিত্র্যময় করে তুলি এবং ওয়েবে তৈরি করার সব উপায় সম্পর্কে জানি।

একটি ডেমো তৈরি করুন, আমাকে টুইট করুন লিঙ্ক, এবং আমি এটি যোগ করব নিচের কমিউনিটি রিমিক্স বিভাগে!

কমিউনিটি রিমিক্স