রিচ মিডিয়া পিকার (কাস্টমাইজ করা যায় এমন বাছাই)

নেটিভ <select> এলিমেন্টকে স্টাইল করা ঐতিহাসিকভাবে কঠিন ছিল এবং এতে শুধুমাত্র প্লেন টেক্সট বিকল্প থাকতে পারত। appearance: base-select প্রপার্টি <select> এলিমেন্টের জন্য কাস্টমাইজ করা যায় এমন স্টেট বেছে নেওয়ার জন্য একটি ডিক্লারেটিভ, CSS-অনলি উপায় অফার করে। এটি ডেভেলপারদের <option> এলিমেন্টের মধ্যে ছবি, SVG এবং জটিল লেআউটের মতো রিচ HTML কন্টেন্ট অন্তর্ভুক্ত করার অনুমতি দেয়, পাশাপাশি নেটিভ কীবোর্ড অ্যাক্সেসিবিলিটি এবং ফর্ম ইন্টিগ্রেশন বজায় রাখে। ভারী, কাস্টম-বিল্ট সিলেক্ট কম্পোনেন্টকে স্ট্যান্ডার্ড, নেটিভ এলিমেন্ট দিয়ে পরিবর্তন করতে এই প্যাটার্ন ব্যবহার করুন।

কীভাবে প্রয়োগ করতে হয়

Customizable Select API ব্যবহার করে রিচ মিডিয়া পিকার প্রয়োগ করতে:

  1. বেস স্টাইল চালু করুন: ::picker(select) ছদ্ম-এলিমেন্ট ব্যবহার করে <select> এলিমেন্ট এবং এর ইন্টার্নাল পিকার, দুটিতেই appearance: base-select প্রয়োগ করুন। এটি <select>-এর মধ্যে থাকা কন্টেন্টের জন্য ব্রাউজারের HTML পার্সার পরিবর্তন করে।
  2. বোতামের কন্টেন্ট নির্ধারণ করা: পিকার বন্ধ থাকলে কী দেখানো হবে তা নির্ধারণ করতে <select>-এর মধ্যে স্ট্যান্ডার্ড <button> এবং <selectedcontent> এলিমেন্ট ব্যবহার করুন। <selectedcontent> এলিমেন্ট বেছে নেওয়া বিকল্পের কন্টেন্ট অটোমেটিক মিরর করে। আপনি যদি বর্তমানে বেছে নেওয়া রিচ কন্টেন্ট বোতামে দেখাতে চান, তাহলে এটি প্রয়োজন।
  3. বিকল্পের মধ্যে রিচ কন্টেন্ট ব্যবহার করা: আপনি এখন <option> ট্যাগের মধ্যে ছবি, SVG এবং অন্যান্য HTML ট্যাগ রাখতে পারবেন। এই API-এর আগে, ব্রাউজার <option> ট্যাগ থেকে ট্যাগ সরিয়ে দিত এবং শুধু প্লেন টেক্সট দেখাত।
  4. পপওভার স্টাইল করা: ::picker(select) ছদ্ম-এলিমেন্ট টার্গেট করে ড্রপ-ডাউন বিকল্পের তালিকা স্টাইল করুন। এটি সবচেয়ে উপরের লেয়ারে রেন্ডার করে, অর্থাৎ আপনাকে z-index নিয়ে চিন্তা করতে হবে না। অ্যাঙ্কর পজিশনিং API ব্যবহার করে বিকল্পগুলি নেটিভভাবে পজিশন করা হয়।

উদাহরণ কোড: রিচ রোল পিকার

<label for="role-picker">Select your role</label>
<select class="custom-select" name="role" id="role-picker">
  <button>
    <selectedcontent></selectedcontent> <!-- Mirrors the selected option's content automatically so you do not need JS to update the button -->
  </button>

  <!-- Define concise aria-label values on options whose mirrored rich content would otherwise read awkwardly as a concatenated string -->
  <option value="frontend" aria-label="Frontend Developer">
    <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
      <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
    </svg>
    <div class="option-text">
      <span class="option-title">Frontend Developer</span>
      <span class="option-desc">React, Vue, CSS</span>
    </div>
  </option>

  <option value="backend" aria-label="Backend Developer">
    <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor">
      <rect x="2" y="12" width="20" height="14" rx="2" ry="2"></rect>
    </svg>
    <div class="option-text">
      <span class="option-title">Backend Developer</span>
      <span class="option-desc">Node.js, Python</span>
    </div>
  </option>
</select>
select.custom-select,
select.custom-select::picker(select) {
  appearance: base-select; /* MUST opt-in both the select and its picker to enable the customizable state, otherwise browser standard rendering applies */
}

select.custom-select {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 12px;
  background-color: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  color: #f1f5f9;
  cursor: pointer;
}

select.custom-select::picker(select) {
  background-color: #0f172a;
  border: 1px solid #334155;
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);
  width: anchor-size(width); /* Uses Anchor Positioning API to keep the dropdown precisely aligned to the button trigger width */
}

select.custom-select option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: 4px;
  cursor: pointer;
}

select.custom-select option:hover {
  background-color: #1e293b;
}

/* Remove standard OS checkmark for base-select */
select.custom-select option::before {
  display: none;
}

/* MANDATORY: Provide multiple visual indicators (e.g., prominent background color and bold title font) to communicate the checked state cleanly */
select.custom-select option:checked {
  background-color: #3b82f6;
  color: #ffffff;
}
select.custom-select option:checked .option-title {
  font-weight: 700;
}

স্ট্র্যাটেজিক প্রয়োগ ও পেশাদার পদ্ধতি

  • আপনার জটিল বিকল্প লেআউট (আইকন, বিবরণ, ছবি) প্রয়োজন হলে appearance: base-select ব্যবহার করুন, যা আগে শুধুমাত্র ভারী জাভাস্ক্রিপ্ট UI ফ্রেমওয়ার্কের মাধ্যমে সম্ভব ছিল।
  • পারফর্ম্যান্সের ক্ষেত্রে কোনও সমস্যা লক্ষ্য করলে, অ্যাড-হক এলিমেন্ট ব্যবহার করবেন না; ব্রাউজার নেটিভ কীবোর্ড ফোকাস নেটিভভাবে ম্যানেজ করে।
  • টপ-লেয়ার রেন্ডারিংয়ের জন্য DO অ্যাকাউন্ট। পিকারটি উপরের স্তরে রেন্ডার করে, যার অর্থ এটি পৃষ্ঠা কন্টেন্টের আপেক্ষিক z-index ওভাররাইড করে।
  • .custom-select selectedcontent .option-desc { display: none; } স্টাইল করার মাধ্যমে, বোতামের স্ট্যাটাসে সেকেন্ডারি বিবরণ (যেমন, বর্ণনা) অনেক বেশি জায়গা নিলে, তা লুকিয়ে রাখুন।
  • লেআউট আচরণ পরীক্ষা করুন। appearance: base-select সেট করলে, ডিফল্ট ব্রাউজার আচরণ সরিয়ে দেয়, যা সবচেয়ে দীর্ঘ বিকল্পের প্রস্থের উপর ভিত্তি করে বেছে নেওয়ার সাইজ নির্ধারণ করে। লেআউট শিফ্ট প্রতিরোধ করতে আপনাকে নির্দিষ্ট প্রস্থ সেট করতে বা ফ্লেক্স/গ্রিড কনস্ট্রেন্ট ব্যবহার করতে হতে পারে।
  • আপনার <select>-এ name অ্যাট্রিবিউট এবং সংশ্লিষ্ট <label> আছে কিনা তা নিশ্চিত করুন। এটি নিশ্চিত করে যে কাস্টম UI থাকলেও, কম্পোনেন্টটি স্ক্রিন রিডারের জন্য অ্যাক্সেসযোগ্য থাকে এবং স্ট্যান্ডার্ড ফর্ম জমা দেওয়ার সাথে সঠিকভাবে কাজ করে।
  • ফর্ম জমা দেওয়ার প্রক্রিয়া যাতে আগের মতোই কাজ করে তা নিশ্চিত করতে বিকল্পে স্ট্যান্ডার্ড value অ্যাট্রিবিউট ব্যবহার করুন।

ফলব্যাক স্ট্র্যাটেজি

কাস্টমাইজ করা যায় এমন <select>-এর জন্য ফলব্যাক ও ব্রাউজার সাপোর্ট

যেসব ব্রাউজারে এখনও appearance: base-select কাজ করে না, সেখানে <select> এলিমেন্ট স্ট্যান্ডার্ড অপারেটিং সিস্টেম ড্রপডাউনে অবনমিত হয়।

  • টেক্সট নয় এমন কন্টেন্ট উপেক্ষা করা হয়েছে: পুরনো ব্রাউজার <option> ট্যাগের মধ্যে HTML ট্যাগ (যেমন <svg> বা <div>) বাদ দিয়ে শুধু টেক্সট নোড দেখায়। <option>-এর টেক্সট কন্টেন্ট যেন পাঠযোগ্য এবং অর্থপূর্ণ হয় তা নিশ্চিত করুন।
  • HTML স্ট্রাকচার ম্যানেজ করা: স্ট্যান্ডার্ড পার্সার <select>-এর মধ্যে <button> এবং <selectedcontent> ট্যাগ উপেক্ষা করতে পারে বা সেগুলিকে ভুল হিসেবে বিবেচনা করতে পারে। আপনি যদি স্ট্যান্ডার্ড টেক্সটকে রিডেবল ফলব্যাক হিসেবে দেখেন, তাহলে প্রোগ্রেসিভ এনহ্যান্সমেন্টের জন্য কোনও ভারী জাভাস্ক্রিপ্ট পলিফিলের প্রয়োজন নেই।
document.addEventListener("DOMContentLoaded", () => {
  // Check if browser supports base-select value
  if (!CSS.supports("appearance", "base-select")) {
    // Custom select overrides are not supported natively.
  }
});