ভিউপোর্ট-অ্যাওয়ার ড্রপডাউন

প্রকাশিত অ্যাকশন প্যানেল বা পপওভার বোতাম গ্রুপ হল ব্যবহারকারীদের জন্য একটি উপযোগী প্যাটার্ন যা ন্যূনতম স্থান গ্রহণ করার সময় অতিরিক্ত কার্যকারিতা অ্যাক্সেস করতে পারে। এই ওভারলে প্যাটার্ন লেআউট জটিলতার সাথে আসে, কারণ ভিউপোর্ট সীমাবদ্ধতার সাথে মানিয়ে নেওয়ার সময় প্যানেলটি অবশ্যই একটি ট্রিগার এলিমেন্টের সাথে যুক্ত থাকতে হবে। সাধারণত, পজিশন গণনা করতে এবং সংঘর্ষ সামলাতে এর জন্য জটিল JavaScript লাইব্রেরি (যেমন Popper.js বা Floating UI) প্রয়োজন হয়।

CSS অ্যাঙ্কর পজিশনিং, CSS-এ সম্পূর্ণভাবে এইসব সম্পর্ক ম্যানেজ করার জন্য একটি ঘোষণামূলক, পারফর্ম্যান্স-অপ্টিমাইজ করা উপায় প্রদান করে, যা ব্রাউজারকে নেটিভভাবে পজিশনিং এবং ওভারফ্লো লজিক ম্যানেজ করার অনুমতি দেয়।

১. বোতাম ও প্যানেলের মধ্যে সম্পর্ক নির্ধারণ করুন

প্রথম ধাপ হল একটি ট্রিগার বোতাম তৈরি করা যা Popover API ব্যবহার করে ওভারলে কন্টেনার খোলে।

বাধ্যতামূলক অ্যাক্সেসিবিলিটি পার্থক্য: এই প্যাটার্নটি স্পষ্টভাবে একটি পপওভারের ভিতরে প্রকাশ করা বোতাম গ্রুপ মডেল করে, যা একটি আসল ARIA মেনু নয়। আপনি সংশ্লিষ্ট কীবোর্ড নেভিগেশন কন্ট্র্যাক্ট (যেমন, আইটেমের মধ্যে স্পেশিয়াল তীরচিহ্ন-কী নেভিগেশন ম্যানেজ করা) সম্পূর্ণভাবে প্রয়োগ না করা পর্যন্ত role="menu" বা role="menuitem" প্রয়োগ করবেন না। একই কারণে, ট্রিগারে aria-haspopup যোগ করবেন না — এর ভ্যালু (menu, listbox, tree, grid বা লিগ্যাসি true) হল একটি প্রতিশ্রুতি যে টার্গেট একটি ম্যাচিং ভূমিকা প্রকাশ করে, যা এই প্যাটার্ন করে না।

<button popovertarget="action-panel">
  Open Actions
</button>
<!-- Use the Popover API (`popover="auto"`) for the overlay to ensure it is placed in the top layer and handled accessibly by the browser. -->
<div id="action-panel" popover="auto" class="panel">
  <button class="action-item" type="button">Edit</button>
</div>

এটি বোতাম এবং প্যানেলের মধ্যে একটি অন্তর্নিহিত অ্যাঙ্কর অ্যাসোসিয়েশন তৈরি করে, যাতে প্যানেলটি বোতামে anchor-name বা প্যানেলে position-anchor ছাড়াই নেটিভভাবে বোতামের সাপেক্ষে অবস্থান করতে পারে।

২. position-area-এর সাথে পজিশনিং

ম্যানুয়াল top/left অফসেটের পরিবর্তে, অ্যাঙ্করের সাপেক্ষে ৩x৩ গ্রিডে টার্গেট প্লেস করতে position-area ব্যবহার করুন।

.panel {
  /* 
     Position the panel below the anchor (block-end), 
     aligned to the start of the anchor and spanning to its end (span-inline-end).
  */
  position-area: block-end span-inline-end;
  
  /* Reset insets to allow the grid to take control */
  inset: auto;
}

RTL এবং বিভিন্ন লেখার মোড অটোমেটিক সাপোর্ট করার জন্য ফিজিক্যাল কীওয়ার্ডের (left, top) পরিবর্তে লজিক্যাল কীওয়ার্ড (span-inline-end, block-start) ব্যবহার করুন।

বাধ্যতামূলক: position-area-এ ফিজিক্যাল ও লজিক্যাল কীওয়ার্ড একসাথে ব্যবহার করবেন না।

৩. এজ-রেজিলিয়েন্স (ফলব্যাক) প্রয়োগ করা

স্ক্রিনের প্রান্তে প্যানেলটি যাতে কেটে না যায়, তার জন্য "ট্রাই ট্যাকটিক্স" নির্ধারণ করুন। ডিফল্ট পজিশন ওভারফ্লো হলে ব্রাউজারকে এটি চেষ্টা করতে হবে।

.panel {
  /* 
     If the panel overflows the bottom, flip it to the top (flip-block).
     If it overflows the inline edges, flip it horizontally (flip-inline).
     If it overflows both (e.g., in a corner), flip on both axes (flip-block flip-inline).
  */
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}

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

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

পপওভারের জন্য ফলব্যাক ও ব্রাউজার সাপোর্ট

পপওভার API মূলত প্রোগ্রেসিভ এনহ্যান্সমেন্ট, তবে এর সংজ্ঞায়িত আচরণ — টপ-লেয়ার প্রোমোশন, লাইট-ডিসমিস এবং popovertarget ইনভোকেশন — শুধুমাত্র CSS-এর সমতুল্য নয়। পুরনো ব্রাউজারের ক্ষেত্রে পলিফিল বা ম্যানুয়াল ফলব্যাক প্রয়োজন হয়, যদি আপনি কোনওটিই শিপ করতে না চান।

Polyfill: পুরনো ব্রাউজারে popover অ্যাট্রিবিউট কাজ করানোর জন্য, শর্তসাপেক্ষে @oddbird/popover-polyfill লোড করুন। বাধ্যতামূলক: HTMLElement.prototype-এ popover প্রপার্টি চেক করে ফিচার শনাক্ত করুন এবং নেটিভ সাপোর্ট না থাকলে শুধুমাত্র তখনই পলিফিল লোড করুন — শর্তহীনভাবে এটি লোড করবেন না।

বান্ডলার বা ইমপোর্ট ম্যাপের মাধ্যমে:

// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
  import("@oddbird/popover-polyfill");
}

বান্ডলার ছাড়া, <script type="module">-এর মধ্যে CDN থেকে ইমপোর্ট করুন:

<script type="module">
  if (!("popover" in HTMLElement.prototype)) {
    import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
  }
</script>

স্টাইলিং সংক্রান্ত সতর্কতা: পলিফিল আসল :popover-open ছদ্ম-ক্লাসকে সংজ্ঞায়িত করতে পারে না, তাই এটি পরিবর্তে .\:popover-open ক্লাস প্রয়োগ করে। বাধ্যতামূলক: :is() বা :where()-এর সাথে দুটিকে একত্রিত করুন, অন্যথায় :popover-open নেই এমন ব্রাউজার সম্পূর্ণ নিয়মটি বাতিল করে দেয়:

[popover]:is(:popover-open, .\:popover-open) {
  display: block;
}

বিকল্প হিসেবে, পলিফিল ছাড়া লিগ্যাসি ফলব্যাকের জন্য, position: fixed ব্যবহার করুন এবং getBoundingClientRect()-এর মাধ্যমে ম্যানুয়ালি কোঅর্ডিনেট হিসেব করুন অথবা ব্যবহারের ক্ষেত্রে গ্রহণযোগ্য হলে inset: auto-এর সাথে ডিফল্ট পজিশনিংয়ের উপর নির্ভর করুন।

অ্যাঙ্কর পজিশনিং ছাড়া ব্রাউজারকে সাপোর্ট করতে, আপনাকে অবশ্যই একটি উপযুক্ত পজিশন সেট করতে হবে। ডিফল্ট হিসেবে, পপওভার স্ক্রিনের মাঝখানে থাকে, যা আপনার ব্যবহারের ক্ষেত্রে কাজ করতে পারে।

কিছু ব্যবহারের ক্ষেত্রে, আপনি @oddbird/css-anchor-positioning পলিফিল ব্যবহার করতে পারবেন, যা কিছু অ্যাঙ্কর পজিশনিং ব্যবহারের ক্ষেত্রে সহায়তা যোগ করে। এটি ইমপ্লিসিট অ্যাঙ্কর সাপোর্ট করে না, তাই আপনাকে ট্রিগারে অ্যাঙ্করের নাম যোগ করতেই হবে। এছাড়াও, পলিফিল দ্বারা পপওভারে position-area কাজ করে না, তাই আপনাকে অবশ্যই পছন্দসই ইনসেটে anchor() ব্যবহার করতে হবে।

<!-- MANDATORY: Conditionally install the anchor positioning polyfill -->
<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    await import("https://unpkg.com/@oddbird/css-anchor-positioning");
  }
</script>
.panel {
  /* Mandatory: use explicit anchor name */
  position-anchor: --kebab-anchor;
  /* Mandatory: use insets rather than position-area for positioning */
  bottom: auto;
  right: auto;
  top: anchor(bottom);
  left: anchor(left);
  margin: 0;
}