অ্যাক্সেসযোগ্য ওয়েব কম্পোনেন্ট

শ্যাডো বাউন্ডারি সিম্যান্টিক ও ARIA-এর কাজ করার পদ্ধতি পরিবর্তন করে। দুটি ব্যর্থতা প্রাধান্য পায়: শ্যাডো ট্রির মধ্যে অনুপস্থিত শব্দার্থবিদ্যা এবং ARIA রেফারেন্স যা নীরবে ভেঙে যায় কারণ তারা শ্যাডো রুট অতিক্রম করতে পারে না।

সিম্যান্টিক মার্ক-আপ থেকে শুরু করুন: টেমপ্লেটের মধ্যে আসল <button>, <nav>, <ul> ব্যবহার করুন যাতে বেশিরভাগ সিম্যান্টিক ফ্রিতে পাওয়া যায় এবং ফাঁকা জায়গার জন্য ElementInternals/ARIA রিজার্ভ করুন।

ElementInternals ARIA মিক্সিনের মাধ্যমে ডিফল্ট সিম্যান্টিক্স

হোস্টে ARIA অ্যাট্রিবিউট লেখার পরিবর্তে ElementInternals-এর মাধ্যমে JS-এ কাস্টম এলিমেন্টের ভূমিকা ও ARIA স্টেট সেট করুন। এটি কম্পোনেন্টের মালিকানাধীন ডিফল্ট হিসেবে শব্দার্থবিদ্যা রাখে, তবুও একজন গ্রাহককে লাইট DOM-এ অ্যাট্রিবিউট সহ তাদের ওভাররাইড করতে দেয়।

class ToggleSwitch extends HTMLElement {
  #internals;
  constructor() {
    super();
    this.#internals = this.attachInternals();
    this.#internals.role = 'switch';          // default role, no host attribute needed
    this.#internals.ariaChecked = 'false';    // exposed to the accessibility tree
    this.addEventListener('click', () => this.toggle());
    this.addEventListener('keydown', (e) => {
      if (e.key === ' ') { e.preventDefault(); this.toggle(); }
    });
  }
  connectedCallback() {
    // Put the host in the tab order on connect (setting tabIndex in the constructor throws on createElement).
    if (!this.hasAttribute('tabindex')) this.tabIndex = 0;
  }
  toggle() {
    const on = this.#internals.ariaChecked !== 'true';
    this.#internals.ariaChecked = String(on);
  }
}
customElements.define('toggle-switch', ToggleSwitch);

এটি ARIA অ্যাট্রিবিউট দিয়ে DOM দূষিত করা এড়ায় এবং গ্রাহকদের ভুলবশত সেগুলি ওভাররাইট করা থেকে আটকায়, যেখানে অ্যাক্সেসিবিলিটি ট্রি এখনও সঠিক ভূমিকা এবং অবস্থা দেখতে পায়।

ফোকাস ম্যানেজমেন্ট ও delegatesFocus

  • যখন হোস্ট এলিমেন্ট নিজেই ইন্টার‍্যাক্টিভ কন্ট্রোল এবং ElementInternals-এর মাধ্যমে ভূমিকা ও স্ট্যাটাস বহন করে (যেমন উপরে ToggleSwitch), তখন হোস্টকে connectedCallback-এর মধ্যে ট্যাব অর্ডারে রাখুন (if (!this.hasAttribute('tabindex')) this.tabIndex = 0 — কনস্ট্রাক্টরে কখনই নয়, যা document.createElement-এ থ্রো করে) যাতে ফোকাস হোস্টের উপর পড়ে এবং সহায়ক প্রযুক্তি এর ভূমিকা ও স্ট্যাটাস ঘোষণা করে। স্ট্যাটিক, ইন্টার‍্যাক্টিভ নয় এমন কম্পোনেন্টের (যেমন, কলআউট বা কার্ড) জন্য হোস্টে tabindex সেট করবেন না।
  • যখন কম্পোনেন্ট একটি অভ্যন্তরীণ ফোকাসযোগ্য কন্ট্রোলকে র‍্যাপ করে যার সিম্যান্টিক্স আছে (অথবা static formAssociated = true সহ ফর্ম-সম্পর্কিত কাস্টম এলিমেন্টে), তখন delegatesFocus: true-এর সাথে শ্যাডো রুট অ্যাটাচ করুন। হোস্টকে ফোকাস করা (এবং ফর্ম-সম্পর্কিত এলিমেন্টের জন্য একটি সংশ্লিষ্ট <label>-এ ক্লিক করা) তারপর ফোকাসকে প্রথম ফোকাসযোগ্য চাইল্ডে ফরওয়ার্ড করে এবং :focus হোস্টের সাথে মেলে। হোস্টে কোনও ভূমিকা/স্টেটের সাথে delegatesFocus: true একত্রিত করবেন না, অন্যথায় ফোকাস ভিতরের এলিমেন্টে চলে যাবে এবং হোস্টের স্টেট এড়িয়ে যাবে।
  • ফোকাস রোভিং বা নতুন দেখানো অঞ্চলে ফোকাস সরানোর জন্য, টার্গেট tabindex="-1" দিন এবং .focus() কল করুন; ট্যাব অর্ডারের উপর নির্ভর না করে প্রোগ্রাম্যাটিক্যালি-ফোকাস করা যায় এমন টার্গেট স্পষ্টভাবে উল্লেখ করুন।

শ্যাডো রুট জুড়ে ARIA সম্পর্ক

  • বাধ্যতামূলক: aria-labelledby, aria-describedby, aria-controls ইত্যাদির মাধ্যমে রেফার করা id শুধুমাত্র রেফারেন্সিং এলিমেন্টের নিজস্ব ট্রির মধ্যে সমাধান করে। লাইট DOM-এ id-ভিত্তিক অ্যাট্রিবিউট শ্যাডো ট্রির মধ্যে থাকা id-কে পয়েন্ট করতে পারে না এবং এর উল্টোটাও হয় না; রেফারেন্সটি নীরবে উপেক্ষা করা হয়।
  • সীমানা অতিক্রম করতে, প্রতিফলিত ARIA এলিমেন্ট প্রপার্টি (যেমন ariaLabelledByElements, ariaDescribedByElements ইত্যাদি) ব্যবহার করুন, যা আইডির পরিবর্তে সরাসরি JS এলিমেন্ট রেফারেন্স গ্রহণ করে। এগুলি বাইরের দিকে সমাধান করে: শ্যাডো ট্রির মধ্যে থাকা কোনও এলিমেন্ট লাইট DOM বা যেকোনও পূর্বপুরুষ ট্রিতে (স্লট করা কন্টেন্ট সহ) কোনও টার্গেটকে পয়েন্ট করতে পারে, যাতে আপনি লাইট DOM কন্টেন্ট থেকে শ্যাডো-ইন্টার্নাল কন্ট্রোল লেবেল করতে পারেন — এমন কিছু যা id রেফারেন্স প্রকাশ করতে পারে না।
  • সেগুলি ভিতরের দিকে রিজলভ করে না: কোনও এলিমেন্ট ডিসেন্ডেন্ট শ্যাডো ট্রির ভিতরে রেফারেন্স করতে পারে না (যেমন, কোনও হোস্টকে তার নিজস্ব শ্যাডো কন্টেন্ট দ্বারা লেবেল করা যায় না)। সেই উদ্দেশ্যে, নতুন রেফারেন্স টার্গেট মেকানিজম হল স্ট্যান্ডার্ড ডিরেকশন, তবে এটি এখনও ব্যাপকভাবে উপলভ্য নয়।
  • কোনও সম্পর্ককে কোনওভাবেই প্রকাশ করা না গেলে, এটিকে একটি ট্রির মধ্যে রাখুন (একই ট্রিতে লেবেল রেন্ডার করুন) অথবা id রেফারেন্সের পরিবর্তে aria-label টেক্সট ব্যবহার করুন।

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

যেখানে ElementInternals ARIA মিক্সিন উপলভ্য নেই, সেখানে পরিবর্তে হোস্টে অ্যাট্রিবিউট হিসেবে ভূমিকা ও ARIA স্ট্যাটাস সেট করুন (this.setAttribute('role', 'switch'))। এটি সব জায়গায় কাজ করে, তবে DOM-এ অ্যাট্রিবিউট যোগ করতে হয় যা কোনও গ্রাহক ওভাররাইড করতে পারেন।

যেখানে প্রতিফলিত ARIA এলিমেন্ট প্রপার্টি উপলভ্য নেই, সেখানে একই-ট্রি সম্পর্কের জন্য id-ভিত্তিক aria-* অ্যাট্রিবিউট ব্যবহার করুন; ক্রস-বাউন্ডারি লেবেলের কোনও id-ভিত্তিক সমতুল্য নেই, তাই aria-label টেক্সটে ফিরে যান।