दिखने वाला ऐक्शन पैनल या पॉपओवर बटन ग्रुप, उपयोगकर्ताओं के लिए एक काम का पैटर्न है. इससे वे कम से कम जगह का इस्तेमाल करके, अतिरिक्त सुविधाएं ऐक्सेस कर सकते हैं. इस ओवरले पैटर्न का लेआउट जटिल होता है. इसकी वजह यह है कि पैनल को ट्रिगर एलिमेंट से जुड़ा रहना चाहिए. साथ ही, इसे व्यूपोर्ट की सीमाओं के हिसाब से अडजस्ट होना चाहिए. पहले, एलिमेंट की पोज़िशन का हिसाब लगाने और ओवरलैप होने से बचाने के लिए, Popper.js या Floating UI जैसी मुश्किल JavaScript लाइब्रेरी की ज़रूरत पड़ती थी.
सीएसएस ऐंकर पोज़िशनिंग, इन रिलेशनशिप को पूरी तरह से सीएसएस में मैनेज करने का एक डिक्लेरेटिव और परफ़ॉर्मेंस के हिसाब से ऑप्टिमाइज़ किया गया तरीका उपलब्ध कराती है. इससे ब्राउज़र, पोज़िशनिंग और ओवरफ़्लो लॉजिक को नेटिव तौर पर मैनेज कर पाते हैं.
1. बटन और पैनल के बीच संबंध तय करना
सबसे पहले, एक ट्रिगर बटन बनाएं जो 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 की ज़रूरत नहीं होती.
2. position-area के साथ पोज़िशनिंग
मैन्युअल तरीके से top/left ऑफ़सेट का इस्तेमाल करने के बजाय, position-area का इस्तेमाल करें. इससे टारगेट को ऐंकर के हिसाब से 3x3 ग्रिड पर रखा जा सकता है.
.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;
}
आरटीएल और लिखने के अलग-अलग मोड अपने-आप काम करें, इसके लिए फ़िज़िकल कीवर्ड (left, top) के बजाय लॉजिकल कीवर्ड (span-inline-end, block-start) को प्राथमिकता दें.
ज़रूरी: position-area में फ़िज़िकल और लॉजिकल कीवर्ड को मिक्स न करें.
3. एज-रेज़िलियंस (फ़ॉलबैक) लागू करना
पैनल को स्क्रीन के किनारे पर कटने से रोकने के लिए, "तरीके आज़माएं" को तय करें. अगर डिफ़ॉल्ट पोज़िशन ओवरफ़्लो होती है, तो ब्राउज़र को इन तरीकों को आज़माना चाहिए.
.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;
}
अगर आपके ड्रॉपडाउन या फ़्लायआउट में कोई ऐरो या बॉर्डर शामिल है, जिसकी स्टाइल को फ़ॉलबैक पोज़िशन के हिसाब से बदलना ज़रूरी है, तो पोज़िशन अवेयर टूलटिप देखें. JavaScript के बिना डायलॉग और पॉपओवर को डिक्लेरेटिव तरीके से शुरू करने के लिए, डिक्लेरेटिव डायलॉग और पॉपओवर कंट्रोल देखें.
फ़ॉलबैक रणनीतियां
पॉपओवर के लिए फ़ॉलबैक और ब्राउज़र की सुविधा
Popover API ज़्यादातर प्रोग्रेसिव एन्हांसमेंट है. हालांकि, इसके मुख्य व्यवहार — टॉप-लेयर प्रमोशन, लाइट-डिसमिस, और popovertarget को शुरू करना — सिर्फ़ सीएसएस के बराबर नहीं हैं. पुराने ब्राउज़र के लिए, polyfill की ज़रूरत होती है. अगर आपको 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"> में सीडीएन से इंपोर्ट करें:
<script type="module">
if (!("popover" in HTMLElement.prototype)) {
import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
}
</script>
स्टाइलिंग से जुड़ी चेतावनी: polyfill, असल :popover-open स्यूडो-क्लास को तय नहीं कर सकता. इसलिए, यह इसके बजाय .\:popover-open क्लास लागू करता है. ज़रूरी: दोनों को :is() या :where() के साथ जोड़ें. ऐसा न करने पर, जिन ब्राउज़र में :popover-open नहीं है वे पूरे नियम को खारिज कर देते हैं:
[popover]:is(:popover-open, .\:popover-open) {
display: block;
}
इसके अलावा, बिना polyfill के लेगसी फ़ॉलबैक के लिए, position: fixed का इस्तेमाल करें और getBoundingClientRect() की मदद से मैन्युअल तरीके से निर्देशांकों का हिसाब लगाएं. इसके अलावा, अगर इस्तेमाल के उदाहरण के लिए यह स्वीकार्य है, तो inset: auto के साथ डिफ़ॉल्ट पोज़िशनिंग का इस्तेमाल करें.
ऐंकर पोज़िशनिंग की सुविधा के बिना काम करने वाले ब्राउज़र के लिए, आपको सही पोज़िशन सेट करनी होगी. डिफ़ॉल्ट रूप से, पॉपओवर स्क्रीन के बीच में होते हैं. यह आपके इस्तेमाल के उदाहरण के लिए काम कर सकता है.
इस्तेमाल के कुछ मामलों में, @oddbird/css-anchor-positioning पॉलीफ़िल का इस्तेमाल किया जा सकता है. इससे ऐंकर पोज़िशनिंग के इस्तेमाल के कुछ मामलों के लिए सहायता मिलती है. यह इंप्लिसिट ऐंकर के साथ काम नहीं करता. इसलिए, आपको ट्रिगर में ऐंकर के नाम जोड़ने होंगे. इसके अलावा, position-area को पॉपओवर पर polyfill के साथ इस्तेमाल नहीं किया जा सकता. इसलिए, आपको अपनी पसंद के इनसेट पर 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;
}