স্টাইল করা প্রোগ্রেস বার তৈরি করুন

<progress> এলিমেন্ট হল কোনও টাস্ক সম্পূর্ণ হওয়ার প্রগ্রেস দেখানোর সিম্যান্টিক উপায়, যেমন তথ্য ডাউনলোড বা আপলোড করা অথবা মাল্টি-স্টেপ প্রসেসের কোনও অংশ সম্পূর্ণ করা। নেটিভ এলিমেন্ট ব্যবহার করলে তা অ্যাক্সেসিবিলিটির ক্ষেত্রে সাহায্য করে, কারণ স্ক্রিন রিডারে অন্তর্নিহিত role="progressbar" থাকে এবং এটি ভ্যালু ঘোষণা করতে পারে।

এই গাইড স্টাইল কাস্টমাইজেশন সহ সম্পূর্ণ স্টাইল করা অনুভূমিক প্রগ্রেস বার প্রয়োগ করে।

প্রগ্রেস বার নাকি প্রগ্রেস রিং?

  • জায়গা কম থাকলে বা বর্গাকার অ্যাস্পেক্ট রেশিও পছন্দ হলে, বৃত্তাকার প্রোগ্রেস বার (প্রোগ্রেস রিং) ব্যবহার করার কথা বিবেচনা করুন: প্রোগ্রেস রিং
  • বেশিরভাগ অনির্দিষ্ট প্রোগ্রেস সিনারিওর জন্য স্পিনার ব্যবহার করুন (লোডিং স্পিনার)। অনির্দিষ্ট প্রগ্রেস বার তখনই ব্যবহার করুন যখন অনির্দিষ্ট অবস্থা সাময়িক এবং শীঘ্রই নির্দিষ্ট প্রগ্রেস বার দ্বারা প্রতিস্থাপিত হবে (যেমন, আপলোডের ক্ষেত্রে মেটাডেটার জন্য অপেক্ষা করা, যাতে প্রগ্রেস % দেখানো যায়)

Markup

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

সম্পূর্ণ কাস্টম স্টাইলিং

১. বেসিক সেট-আপ

  • বাধ্যতামূলক: কাস্টম স্টাইলিং চালু করতে appearance: none ব্যবহার করুন।
  • border: 0 solid-এর সাথে UA বর্ডার রিসেট করুন
  • এলিমেন্টের বর্ডার-রেডিয়াসে অ্যাক্টিভ বার ক্লিপ করতে, overflow: clip ব্যবহার করুন অথবা বারে একই border-radius প্রয়োগ করুন। বারে border-radius: inherit ব্যবহার করবেন না, যা শ্যাডো DOM-এ এলিমেন্টের নির্দিষ্ট কাঠামোর উপর নির্ভর করে।
progress {
  /* Reset default browser styles */
  appearance: none;
  border: 0 solid;
  /* Clip bar to element’s border-radius  */
  overflow: clip;
}

২. স্টাইল বেছে নেওয়া

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

৩. অনির্ধারিত স্ট্যাটাস স্টাইলিং

অনির্ধারিত অবস্থার জন্য কাস্টম অ্যানিমেশন যোগ করুন: ফিল সিউডো-এলিমেন্টকে একটি ছোট সেগমেন্টে পরিণত করুন এবং ট্র্যাক বরাবর স্লাইড করুন।

  • ফিল স্টাইল করুন; progress-এ ব্যাকগ্রাউন্ড হিসেবে এটি আবার তৈরি করবেন না।
  • অনির্দিষ্ট ফিল শুধুমাত্র তার অ্যানিমেশনের মাধ্যমে বিদ্যমান: কীফ্রেমগুলি একটি বাস্তব inline-size (এটি Chromium-এর UA ইনলাইন inline-size-কে হারায়) দিয়ে এর দৈর্ঘ্য সেট করে এবং এটিকে translate দিয়ে সরায়। দৈর্ঘ্যের জন্য scale ব্যবহার করবেন না; এটি ফিলে আঁকা যেকোনও প্যাটার্নকে বিকৃত করে।
  • translate শতাংশ ফিল-এর নিজস্ব প্রস্থের সাপেক্ষে সমাধান করে, তাই পরিবর্তে ট্র্যাক ইউনিটে পজিশন প্রকাশ করুন: progress-কে একটি ইনলাইন-সাইজ কন্টেনার করুন এবং কীফ্রেমে cqi ব্যবহার করুন। from, to-এ margin-right: auto অন্তর্ভুক্ত করুন যাতে Chromium, RTL-এর ক্ষেত্রেও ফিজিক্যাল লেফটে ফিল আউট লেআউট করে।
  • ফিল সরানোর জন্য মার্জিন নয়, ট্রান্সফর্ম ব্যবহার করুন।
    • ট্রান্সফর্ম অ্যানিমেশনকে কম্পোজিটরে রাখে (যদি না inline-size-ও অ্যানিমেট করা হয়)
    • RTL-এ মার্জিন ব্রেক হয়, দুটি আলাদা কারণে:
    • Firefox শুধুমাত্র তার ফিজিক্যাল বাঁদিকের মার্জিন ব্যবহার করে অনির্দিষ্ট ফিল পজিশন করে, তাই RTL-এ margin-inline-start-এর কোনও প্রভাব নেই এবং ফিল কখনই সরে না।
    • Chromium ও WebKit-এ, যা ফিল আউটকে সাধারণ ব্লক হিসেবে দেখায়, একবার মার্জিন ফিলকে ট্র্যাকের শেষ পর্যন্ত ঠেলে দিলে মার্জিন ট্র্যাকের থেকে বেশি যোগ করে। স্ট্যান্ডার্ড CSS, RTL-এ margin-left উপেক্ষা করে সেই সমস্যার সমাধান করে, তাই সেগমেন্টটি স্লাইড করে বেরিয়ে যাওয়ার পরিবর্তে কিনারায় চলে যায়।
    • লেআউটের পরে translate প্রয়োগ করা হয়, তাই কোনও সমস্যাই প্রযোজ্য নয়।
  • RTL-এ মোশন মিরর করতে (Chrome-এর নেটিভ বারের মতো), :dir(rtl)-এর অধীনে অ্যানিমেশন রিভার্স করুন:
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 প্রপার্টি হল প্রোগ্রেসিভ এনহ্যান্সমেন্ট। যেসব ব্রাউজারে এই প্রপার্টি কাজ করে না, সেগুলি এটি উপেক্ষা করবে এবং ডিফল্ট UI কালার ব্যবহার করবে।

accent-color কাজ না করলে এবং প্রোগ্রেস বার স্টাইল করার প্রয়োজন হলে, প্রোগ্রেস বারে পছন্দের স্টাইল প্রয়োগ করতে কাস্টমাইজ করা স্টাইলিং পদ্ধতি ব্যবহার করুন।

revert-rule-এর জন্য ফলব্যাক ও ব্রাউজার সহায়তা

revert-rule কাজ না করলে, animation: var(--progress-bar-animation, revert-rule) animation-name: revert-rule-এ ফিরে যায় এবং --progress-bar-animation সেট করা না থাকলে 0s সময়সীমা থাকে, যা কোনও @keyframes revert-rule না থাকলে ক্ষতিকর নয়।