सीएसएस ऐंकर पोज़िशनिंग की मदद से, एलिमेंट को एक-दूसरे के साथ टेदर करना

फ़िलहाल, एक एलिमेंट को दूसरे से कैसे जोड़ा जाता है? उनकी पोज़िशन ट्रैक की जा सकती है या किसी तरह के रैपर एलिमेंट का इस्तेमाल किया जा सकता है.

<!-- index.html -->
<div class="container">
  <a href="/link" class="anchor">I’m the anchor</a>
  <div class="anchored">I’m the anchored thing</div>
</div>
/* styles.css */
.container {
  position: relative;
}
.anchored {
  position: absolute;
}

ये समाधान अक्सर सही नहीं होते. उन्हें JavaScript की ज़रूरत होती है या अतिरिक्त मार्कअप जोड़ना पड़ता है. CSS ऐंकर पोज़िशनिंग एपीआई का मकसद, टैदरिंग एलिमेंट के लिए CSS API उपलब्ध कराकर इस समस्या को हल करना है. यह अन्य एलिमेंट की पोज़िशन और साइज़ के आधार पर, किसी एक एलिमेंट की पोज़िशन और साइज़ तय करने का तरीका उपलब्ध कराता है.

इस इमेज में, ब्राउज़र की एक मॉकअप विंडो दिखाई गई है. इसमें टूलटिप के बारे में जानकारी दी गई है.

ब्राउज़र समर्थन

Chrome Canary में, "वेब प्लैटफ़ॉर्म की नई सुविधाएं" फ़्लैग के पीछे, सीएसएस ऐंकर पोज़िशनिंग एपीआई को आज़माया जा सकता है. उस फ़्लैग को चालू करने के लिए, Chrome Canary खोलें और chrome://flags पर जाएं. इसके बाद, "वेब प्लैटफ़ॉर्म की एक्सपेरिमेंटल सुविधाएं" फ़्लैग चालू करें.

Oddbird की टीम ने डेवलपमेंट में एक पॉलीफ़िल भी बनाया है. github.com/oddbird/css-anchor-positioning पर जाकर, रीपो ज़रूर देखें.

ऐंकर करने की सुविधा के साथ काम करने वाले प्रॉडक्ट देखने के लिए:

@supports(anchor-name: --foo) {
  /* Styles... */
}

ध्यान दें कि यह एपीआई अभी एक्सपेरिमेंटल स्टेज में है और इसमें बदलाव हो सकता है. इस लेख में, अहम बातों के बारे में खास तौर पर बताया गया है. फ़िलहाल, यह सुविधा सीएसएस वर्किंग ग्रुप के स्पेसिफ़िकेशन के मुताबिक पूरी तरह से काम नहीं करती.

समस्या

आपको ऐसा करने की ज़रूरत क्यों पड़ेगी? टूलटिप या टूलटिप जैसे अनुभव बनाने के लिए, इस सुविधा का इस्तेमाल किया जा सकता है. ऐसे में, अक्सर टूलटिप को उस कॉन्टेंट से जोड़ना होता है जिसका वह रेफ़रंस देता है. अक्सर, किसी एलिमेंट को दूसरे से जोड़ने के लिए किसी तरीके की ज़रूरत होती है. आपको यह भी उम्मीद होती है कि पेज के साथ इंटरैक्ट करने से, वह टैग नहीं हटेगा. उदाहरण के लिए, अगर कोई उपयोगकर्ता यूज़र इंटरफ़ेस (यूआई) को स्क्रोल करता है या उसका साइज़ बदलता है.

समस्या का एक और हिस्सा यह है कि अगर आपको यह पक्का करना है कि टैग किया गया एलिमेंट दिखता रहे, तो क्या करना होगा. उदाहरण के लिए, अगर कोई टूलटिप खोला जाता है और वह व्यूपोर्ट के बॉर्डर से काट जाता है, तो क्या करना होगा. ऐसा हो सकता है कि उपयोगकर्ताओं को यह अनुभव अच्छा न लगे. आपको टूलटिप में बदलाव करना है.

मौजूदा सलूशन

फ़िलहाल, इस समस्या को हल करने के कुछ अलग तरीके हैं.

सबसे पहले, "ऐंकर को रैप करें" वाला बुनियादी तरीका. दोनों एलिमेंट को एक कंटेनर में लपेटा जाता है. इसके बाद, position का इस्तेमाल करके टूलटिप को ऐंकर के हिसाब से पोज़िशन किया जा सकता है.

<div class="containing-block">
  <div class="tooltip">Anchor me!</div>
  <a class="anchor">The anchor</a>
</div>
.containing-block {
  position: relative;
}

.tooltip {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
}
देखें

कंटेनर को एक जगह से दूसरी जगह ले जाया जा सकता है. ऐसा करने पर, ज़्यादातर चीज़ें उसी जगह पर ही रहेंगी.

अगर आपको अपने ऐंकर की पोज़िशन पता है या उसे किसी तरह से ट्रैक किया जा सकता है, तो एक और तरीका अपनाया जा सकता है. इसे कस्टम प्रॉपर्टी के साथ अपने टूलटिप में पास किया जा सकता है.

<div class="tooltip">Anchor me!</div>
<a class="anchor">The anchor</a>
:root {
  --anchor-width: 120px;
  --anchor-top: 40vh;
  --anchor-left: 20vmin;
}

.anchor {
  position: absolute;
  top: var(--anchor-top);
  left: var(--anchor-left);
  width: var(--anchor-width);
}

.tooltip {
  position: absolute;
  top: calc(var(--anchor-top));
  left: calc((var(--anchor-width) * 0.5) + var(--anchor-left));
  transform: translate(-50%, calc(-100% - 10px));
}
देखें

लेकिन, अगर आपको अपने ऐंकर की पोज़िशन नहीं पता है, तो क्या होगा? आपको JavaScript का इस्तेमाल करके, इस समस्या को ठीक करना पड़ सकता है. नीचे दिए गए कोड की तरह कुछ किया जा सकता है, लेकिन इसका मतलब है कि आपकी स्टाइल, सीएसएस से बाहर निकलकर JavaScript में लीक होने लगी हैं.

const setAnchorPosition = (anchored, anchor) => {
  const bounds = anchor.getBoundingClientRect().toJSON();
  for (const [key, value] of Object.entries(bounds)) {
    anchored.style.setProperty(`--${key}`, value);
  }
};

const update = () => {
  setAnchorPosition(
    document.querySelector('.tooltip'),
    document.querySelector('.anchor')
  );
};

window.addEventListener('resize', update);
document.addEventListener('DOMContentLoaded', update);
देखें

इससे कुछ सवाल उठते हैं:

  • स्टाइल का हिसाब कब लगाया जाता है?
  • स्टाइल का हिसाब कैसे लगाया जाता है?
  • स्टाइल का हिसाब कितनी बार लगाया जाता है?

क्या इससे समस्या हल हो गई? ऐसा हो सकता है कि यह आपके इस्तेमाल के उदाहरण के लिए सही हो, लेकिन इसमें एक समस्या है: हमारा समाधान, आपके हिसाब से नहीं बदलता. यह काम नहीं कर रहा है. अगर मेरा ऐंकर किया गया एलिमेंट, व्यूपोर्ट में दिखने से बाहर हो जाता है, तो क्या होगा?

अब आपको यह तय करना होगा कि इस पर प्रतिक्रिया देनी है या नहीं और अगर देनी है, तो कैसे. आपको ज़्यादा सवालों के जवाब देने और ज़्यादा फ़ैसले लेने पड़ रहे हैं. आपको सिर्फ़ एक एलिमेंट को दूसरे से ऐंकर करना है. अगर सब कुछ सही से हो, तो आपका समाधान अपने आस-पास के माहौल के हिसाब से अडजस्ट होगा और उस पर प्रतिक्रिया देगा.

इस समस्या को हल करने के लिए, JavaScript का इस्तेमाल किया जा सकता है. इसके लिए, आपको अपने प्रोजेक्ट में डिपेंडेंसी जोड़नी होगी. साथ ही, इनका इस्तेमाल करने के तरीके के आधार पर, परफ़ॉर्मेंस से जुड़ी समस्याएं भी आ सकती हैं. उदाहरण के लिए, कुछ पैकेज सही पोज़िशन बनाए रखने के लिए requestAnimationFrame का इस्तेमाल करते हैं. इसका मतलब है कि आपको और आपकी टीम को पैकेज और उसके कॉन्फ़िगरेशन के विकल्पों के बारे में जानकारी होनी चाहिए. इस वजह से, हो सकता है कि आपके सवाल और फ़ैसले कम न हों, बल्कि उनमें बदलाव हो. यह सीएसएस ऐंकर पोज़िशनिंग के लिए "क्यों" का हिस्सा है. इससे, रैंक का हिसाब लगाते समय परफ़ॉर्मेंस से जुड़ी समस्याओं के बारे में सोचने की ज़रूरत नहीं पड़ेगी.

इस समस्या के लिए, "floating-ui", एक लोकप्रिय पैकेज है. इसका इस्तेमाल करने के लिए, कोड कुछ ऐसा दिख सकता है:

import {computePosition, flip, offset, autoUpdate} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.2.1/+esm';

const anchor = document.querySelector('.anchor')
const tooltip = document.querySelector('.tooltip')

const updatePosition = () => {  
  computePosition(anchor, tooltip, {
    placement: 'top',
    middleware: [offset(10), flip()]
  })
    .then(({x, y}) => {
      Object.assign(tooltip.style, {
        left: `${x}px`,
        top: `${y}px`
      })
  })
};

const clean = autoUpdate(anchor, tooltip, updatePosition);

इस डेमो में, उस कोड का इस्तेमाल करके ऐंकर की जगह बदलकर देखें.

देखें

ऐसा हो सकता है कि "टूलटिप" आपकी उम्मीद के मुताबिक काम न करे. यह Y-ऐक्सिस पर व्यूपोर्ट के बाहर जाने पर प्रतिक्रिया करता है, लेकिन X-ऐक्सिस पर नहीं. दस्तावेज़ देखें. इससे आपको अपनी समस्या का समाधान मिल सकता है.

हालांकि, अपने प्रोजेक्ट के लिए सही पैकेज ढूंढने में काफ़ी समय लग सकता है. इसमें आपको कई फ़ैसले लेने पड़ते हैं. अगर आपके हिसाब से यह सुविधा काम नहीं करती है, तो आपको परेशानी हो सकती है.

ऐंकर पोज़िशनिंग का इस्तेमाल करना

CSS ऐंकर पोज़िशनिंग एपीआई डालें. इसका मकसद, अपनी स्टाइल को सीएसएस में रखना और आपको ज़्यादा से ज़्यादा फ़ैसले लेने से बचाना है. आपको वही नतीजा चाहिए, लेकिन डेवलपर के अनुभव को बेहतर बनाना है.

  • JavaScript की ज़रूरत नहीं है.
  • ब्राउज़र को अपने निर्देशों के हिसाब से सबसे सही पोज़िशन तय करने दें.
  • तीसरे पक्ष की कोई डिपेंडेंसी नहीं
  • कोई भी रैपर एलिमेंट नहीं है.
  • यह टॉप लेयर में मौजूद एलिमेंट के साथ काम करता है.

आइए, ऊपर बताई गई समस्या को फिर से बनाएं और उसका हल निकालें. इसके बजाय, ऐंकर वाली नाव के उदाहरण का इस्तेमाल करें. ये ऐंकर किए गए एलिमेंट और ऐंकर को दिखाते हैं. पानी, उस ब्लॉक को दिखाता है जिसमें डेटा मौजूद है.

सबसे पहले, आपको यह चुनना होगा कि ऐंकर को कैसे तय किया जाए. ऐसा करने के लिए, अपनी सीएसएस में ऐंकर एलिमेंट पर anchor-name प्रॉपर्टी सेट करें. यह डैश-आइडेंटिफ़ायर वैल्यू स्वीकार करता है.

.anchor {
  anchor-name: --my-anchor;
}

इसके अलावा, anchor एट्रिब्यूट की मदद से, एचटीएमएल में ऐंकर तय किया जा सकता है. एट्रिब्यूट की वैल्यू, ऐंकर एलिमेंट का आईडी होता है. इससे एक इंप्लिसिट ऐंकर बनता है.

<a id="my-anchor" class="anchor"></a>
<div anchor="my-anchor" class="boat">I’m a boat!</div>

ऐंकर तय करने के बाद, anchor फ़ंक्शन का इस्तेमाल किया जा सकता है. anchor फ़ंक्शन तीन आर्ग्युमेंट लेता है:

  • ऐंकर एलिमेंट: इस्तेमाल किए जाने वाले ऐंकर का anchor-name—या implicit ऐंकर का इस्तेमाल करने के लिए, वैल्यू को छोड़ा जा सकता है. इसे एचटीएमएल रिलेशनशिप या anchor-name वैल्यू वाली anchor-default प्रॉपर्टी की मदद से तय किया जा सकता है.
  • ऐंकर साइड: उस पोज़िशन का कीवर्ड जिसका आपको इस्तेमाल करना है. यह top, right, bottom, left, center वगैरह हो सकता है. इसके अलावा, आपके पास प्रतिशत पास करने का विकल्प भी होता है. उदाहरण के लिए, 50% का मतलब center होगा.
  • फ़ॉलबैक: यह एक वैकल्पिक फ़ॉलबैक वैल्यू है, जो लंबाई या प्रतिशत को स्वीकार करती है.

ऐंकर किए गए एलिमेंट की इनसेट प्रॉपर्टी (top, right, bottom, left या उनके लॉजिकल एग्ज़िम्पल) की वैल्यू के तौर पर, anchor फ़ंक्शन का इस्तेमाल किया जाता है. calc में anchor फ़ंक्शन का इस्तेमाल भी किया जा सकता है:

.boat {
  bottom: anchor(--my-anchor top);
  left: calc(anchor(--my-anchor center) - (var(--boat-size) * 0.5));
}

 /* alternative with anchor-default */
.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: calc(anchor(center) - (var(--boat-size) * 0.5));
}

center इनसेट प्रॉपर्टी मौजूद नहीं है. इसलिए, अगर आपको अपने ऐंकर किए गए एलिमेंट का साइज़ पता है, तो calc का इस्तेमाल करें. translate का इस्तेमाल क्यों नहीं करना चाहिए? इसका इस्तेमाल किया जा सकता है:

.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: anchor(center);
  translate: -50% 0;
}

हालांकि, ब्राउज़र ऐंकर किए गए एलिमेंट के लिए, बदली गई पोज़िशन को ध्यान में नहीं रखता. इससे यह साफ़ तौर पर पता चलेगा कि पोज़िशन फ़ॉलबैक और ऑटो पोज़िशनिंग को ध्यान में रखते समय, यह जानकारी क्यों ज़रूरी है.

देखें

आपने ऊपर कस्टम प्रॉपर्टी --boat-size का इस्तेमाल देखा होगा. हालांकि, अगर आपको ऐंकर किए गए एलिमेंट का साइज़, ऐंकर के साइज़ के हिसाब से तय करना है, तो उस साइज़ को भी ऐक्सेस किया जा सकता है. इसका हिसाब खुद लगाने के बजाय, anchor-size फ़ंक्शन का इस्तेमाल किया जा सकता है. उदाहरण के लिए, अपनी नाव को ऐंकर की चौड़ाई से चार गुना बड़ा बनाने के लिए:

.boat {
  width: calc(4 * anchor-size(--my-anchor width));
}

anchor-size(--my-anchor height) की मदद से, ऊंचाई की जानकारी भी देखी जा सकती है. इसका इस्तेमाल, किसी एक या दोनों ऐक्सिस का साइज़ सेट करने के लिए किया जा सकता है.

अगर आपको absolute पोज़िशनिंग वाले किसी एलिमेंट को ऐंकर करना है, तो क्या करें? नियम यह है कि एलिमेंट, एक-दूसरे के भाई-बहन नहीं हो सकते. ऐसे में, ऐंकर को ऐसे कंटेनर में लपेटा जा सकता है जिसमें relative पोज़िशनिंग हो. इसके बाद, उस पर ऐंकर किया जा सकता है.

<div class="anchor-wrapper">
  <a id="my-anchor" class="anchor"></a>
</div>
<div class="boat">I’m a boat!</div>

यह डेमो देखें. इसमें ऐंकर को खींचकर कहीं भी छोड़ा जा सकता है और नाव उसी दिशा में चलेगी.

देखें

स्क्रोल की स्थिति ट्रैक करना

कुछ मामलों में, आपका ऐंकर एलिमेंट स्क्रोल किए जा सकने वाले कंटेनर में हो सकता है. साथ ही, हो सकता है कि आपका ऐंकर किया गया एलिमेंट उस कंटेनर से बाहर हो. स्क्रोलिंग, लेआउट से अलग थ्रेड पर होती है. इसलिए, आपको इसे ट्रैक करने का तरीका चाहिए. anchor-scroll प्रॉपर्टी ऐसा कर सकती है. इसे ऐंकर किए गए एलिमेंट पर सेट किया जाता है और उस ऐंकर की वैल्यू दी जाती है जिसे ट्रैक करना है.

.boat { anchor-scroll: --my-anchor; }

इस डेमो को आज़माएं. इसमें कोने में मौजूद चेकबॉक्स की मदद से, anchor-scroll को चालू और बंद किया जा सकता है.

देखें

हालांकि, यह उदाहरण यहां थोड़ा कम काम का है, क्योंकि आदर्श दुनिया में, आपकी नाव और ऐंकर, दोनों पानी में होते हैं. साथ ही, पॉपओवर एपीआई जैसी सुविधाओं से, मिलते-जुलते एलिमेंट को एक साथ रखने में मदद मिलती है. हालांकि, ऐंकर पोज़िशनिंग उन एलिमेंट के साथ काम करेगी जो सबसे ऊपर वाली लेयर में हैं. एपीआई का यह एक मुख्य फ़ायदा है: अलग-अलग फ़्लो में एलिमेंट को जोड़ना.

इस डेमो में, टूलटिप वाले ऐंकर के साथ स्क्रोलिंग कंटेनर दिखाया गया है. ऐसा हो सकता है कि पॉपओवर टूलटिप एलिमेंट, ऐंकर के साथ एक ही जगह पर न हों:

देखें

हालांकि, आपको यह पता चलेगा कि पॉपओवर अपने ऐंकर लिंक को कैसे ट्रैक करते हैं. स्क्रोल किए जा सकने वाले उस कंटेनर का साइज़ बदला जा सकता है. ऐसा करने पर, पोज़िशन अपने-आप अपडेट हो जाएंगी.

पोज़िशन फ़ॉलबैक और ऑटो पोज़िशनिंग

यहां ऐंकर पोज़िशनिंग की सुविधा का फ़ायदा एक लेवल ज़्यादा मिलता है. position-fallback, आपके दिए गए फ़ॉलबैक के सेट के आधार पर, आपके ऐंकर किए गए एलिमेंट की पोज़िशन तय कर सकता है. अपनी स्टाइल की मदद से, ब्राउज़र को निर्देश दें और उसे अपने लिए पोज़िशन तय करने दें.

आम तौर पर, टूलटिप को ऐंकर के ऊपर या नीचे दिखाया जाता है. यह व्यवहार इस बात पर निर्भर करता है कि टूलटिप को उसके कंटेनर से क्लिप किया जाएगा या नहीं. आम तौर पर, वह कंटेनर व्यूपोर्ट होता है.

अगर आपने पिछले डेमो के कोड को ध्यान से देखा होता, तो आपको पता चल जाता कि position-fallback प्रॉपर्टी का इस्तेमाल किया जा रहा था. अगर आपने कंटेनर को स्क्रोल किया है, तो आपको उन ऐंकर किए गए पॉपओवर के कूदने की जानकारी दिख सकती है. ऐसा तब हुआ, जब उनके ऐंकर व्यूपोर्ट की सीमा के करीब पहुंच गए. उस समय, पॉपओवर व्यूपोर्ट में बने रहने के लिए अडजस्ट हो रहे होते हैं.

साफ़ तौर पर position-fallback बनाने से पहले, ऐंकर पोज़िशनिंग की सुविधा अपने-आप पोज़िशनिंग की सुविधा भी देगी. ऐंकर फ़ंक्शन और दूसरी इनसेट प्रॉपर्टी, दोनों में auto की वैल्यू का इस्तेमाल करके, फ़्लिप को बिना किसी शुल्क के पाया जा सकता है. उदाहरण के लिए, अगर bottom के लिए anchor का इस्तेमाल किया जाता है, तो top को auto पर सेट करें.

.tooltip {
  position: absolute;
  bottom: anchor(--my-anchor auto);
  top: auto;
}

अपने-आप पोज़िशन तय होने की सुविधा के बजाय, साफ़ तौर पर position-fallback का इस्तेमाल किया जा सकता है. इसके लिए, आपको पोज़िशन फ़ॉलबैक सेट तय करना होगा. ब्राउज़र इनमें से तब तक खोजता रहेगा, जब तक उसे कोई ऐसी पोज़िशनिंग नहीं मिल जाती जिसका इस्तेमाल किया जा सकता हो. इसके बाद, वह पोज़िशनिंग लागू कर देता है. अगर उसे कोई काम करने वाला विकल्प नहीं मिलता है, तो वह डिफ़ॉल्ट रूप से पहले विकल्प का इस्तेमाल करता है.

ऐसा position-fallback जो टूलटिप को ऊपर और फिर नीचे दिखाने की कोशिश करता है, ऐसा दिख सकता है:

@position-fallback --top-to-bottom {
  @try {
    bottom: anchor(top);
    left: anchor(center);
  }

  @try {
    top: anchor(bottom);
    left: anchor(center);
  }
}

टूलटिप पर लागू करने पर, यह ऐसा दिखता है:

.tooltip {
  anchor-default: --my-anchor;
  position-fallback: --top-to-bottom;
}

anchor-default का इस्तेमाल करने का मतलब है कि position-fallback को अन्य एलिमेंट के लिए फिर से इस्तेमाल किया जा सकता है. anchor-default सेट करने के लिए, स्कोप वाली कस्टम प्रॉपर्टी का भी इस्तेमाल किया जा सकता है.

देखें

नाव का इस्तेमाल करके, इस डेमो को फिर से देखें. position-fallback सेट है. ऐंकर की जगह बदलने पर, नाव कंटेनर में ही बनी रहेगी. बॉडी पैडिंग को अडजस्ट करने वाली पैडिंग वैल्यू भी बदलकर देखें. देखें कि ब्राउज़र, पोज़िशनिंग को कैसे ठीक करता है. कंटेनर के ग्रिड अलाइनमेंट को बदलकर, पोज़िशन बदली जा रही हैं.

देखें

इस बार position-fallback, घड़ी की सुई की दिशा में पोज़िशन आज़माते हुए ज़्यादा शब्दों का इस्तेमाल करता है.

.boat {
  anchor-default: --my-anchor;
  position-fallback: --compass;
}

@position-fallback --compass {
  @try {
    bottom: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    right: anchor(left);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }
}


उदाहरण

अब आपको ऐंकर पोज़िशनिंग की मुख्य सुविधाओं के बारे में पता है. आइए, टूलटिप के अलावा कुछ दिलचस्प उदाहरणों पर नज़र डालते हैं. इन उदाहरणों का मकसद, आपको ऐंकर पोज़िशनिंग का इस्तेमाल करने के तरीकों के बारे में आइडिया देना है. स्पेसिफ़िकेशन को बेहतर बनाने का सबसे अच्छा तरीका, आप जैसे असल उपयोगकर्ताओं से इनपुट लेना है.

कॉन्टेक्स्ट मेन्यू

चलिए, Popover API का इस्तेमाल करके कॉन्टेक्स्ट मेन्यू से शुरू करते हैं. इसका मतलब है कि शेवरॉन वाले बटन पर क्लिक करने से, कॉन्टेक्स्ट मेन्यू दिखेगा. साथ ही, उस मेन्यू में एक और मेन्यू होगा, जिसे बड़ा किया जा सकता है.

यहां मार्कअप अहम नहीं है. हालांकि, आपके पास popovertarget का इस्तेमाल करने वाले तीन बटन हैं. इसका मतलब है कि आपके पास popover एट्रिब्यूट का इस्तेमाल करने वाले तीन एलिमेंट हैं. इससे, आपको बिना किसी JavaScript के संदर्भ मेन्यू खोलने की सुविधा मिलती है. यह इस तरह दिख सकता है:

<button popovertarget="context">
  Toggle Menu
</button>        
<div popover="auto" id="context">
  <ul>
    <li><button>Save to your Liked Songs</button></li>
    <li>
      <button popovertarget="playlist">
        Add to Playlist
      </button>
    </li>
    <li>
      <button popovertarget="share">
        Share
      </button>
    </li>
  </ul>
</div>
<div popover="auto" id="share">...</div>
<div popover="auto" id="playlist">...</div>

अब, position-fallback तय किया जा सकता है और उसे संदर्भ मेन्यू के बीच शेयर किया जा सकता है. हम पॉपओवर के लिए भी, inset स्टाइल को अनसेट करना न भूलें.

[popovertarget="share"] {
  anchor-name: --share;
}

[popovertarget="playlist"] {
  anchor-name: --playlist;
}

[popovertarget="context"] {
  anchor-name: --context;
}

#share {
  anchor-default: --share;
  position-fallback: --aligned;
}

#playlist {
  anchor-default: --playlist;
  position-fallback: --aligned;
}

#context {
  anchor-default: --context;
  position-fallback: --flip;
}

@position-fallback --aligned {
  @try {
    top: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }

  @try {
    top: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(bottom);
    left: anchor(right);
  }

  @try {
    right: anchor(left);
    bottom: anchor(bottom);
  }
}

@position-fallback --flip {
  @try {
    bottom: anchor(top);
    left: anchor(left);
  }

  @try {
    right: anchor(right);
    bottom: anchor(top);
  }

  @try {
    top: anchor(bottom);
    left: anchor(left);
  }

  @try {
    top: anchor(bottom);
    right: anchor(right);
  }
}

इससे आपको अडैप्टिव नेस्ट किए गए कॉन्टेक्स्ट मेन्यू का यूज़र इंटरफ़ेस (यूआई) मिलता है. चुनें टूल का इस्तेमाल करके, कॉन्टेंट की पोज़िशन बदलें. आपका चुना गया विकल्प, ग्रिड के अलाइनमेंट को अपडेट करता है. इससे, ऐंकर पोज़िशनिंग के ज़रिए पॉपओवर को पोज़िशन करने के तरीके पर असर पड़ता है.

देखें

फ़ोकस और फ़ॉलो करना

इस डेमो में :has() का इस्तेमाल करके, सीएसएस प्राइमिटिव को जोड़ा गया है. इसका मकसद, फ़ोकस में मौजूद input के लिए विज़ुअल इंडिकेटर को ट्रांज़िशन करना है.

ऐसा करने के लिए, रनटाइम पर नया ऐंकर सेट करें. इस डेमो के लिए, इनपुट फ़ोकस होने पर स्कोप वाली कस्टम प्रॉपर्टी अपडेट हो जाती है.

#email {
    anchor-name: --email;
  }
  #name {
    anchor-name: --name;
  }
  #password {
    anchor-name: --password;
  }
:root:has(#email:focus) {
    --active-anchor: --email;
  }
  :root:has(#name:focus) {
    --active-anchor: --name;
  }
  :root:has(#password:focus) {
    --active-anchor: --password;
  }

:root {
    --active-anchor: --name;
    --active-left: anchor(var(--active-anchor) right);
    --active-top: calc(
      anchor(var(--active-anchor) top) +
        (
          (
              anchor(var(--active-anchor) bottom) -
                anchor(var(--active-anchor) top)
            ) * 0.5
        )
    );
  }
.form-indicator {
    left: var(--active-left);
    top: var(--active-top);
    transition: all 0.2s;
}

लेकिन, इसे आगे कैसे बढ़ाया जा सकता है? इसका इस्तेमाल, निर्देशों वाले ओवरले के लिए किया जा सकता है. टूलटिप, दिलचस्प जगहों के बीच जा सकता है और अपना कॉन्टेंट अपडेट कर सकता है. कॉन्टेंट को क्रॉसफ़ेड किया जा सकता है. अलग-अलग ऐनिमेशन की मदद से, display को ऐनिमेट या ट्रांज़िशन देखें.

देखें

बार चार्ट कैलकुलेट करना

ऐंकर पोज़िशनिंग के साथ एक और मज़ेदार काम किया जा सकता है. इसे calc के साथ जोड़ा जा सकता है. मान लीजिए कि आपके पास एक चार्ट है, जिसमें कुछ पॉपओवर हैं जो चार्ट पर एनोटेट करते हैं.

सीएसएस min और max का इस्तेमाल करके, सबसे बड़ी और सबसे छोटी वैल्यू को ट्रैक किया जा सकता है. इसके लिए, सीएसएस कुछ इस तरह दिख सकती है:

.chart__tooltip--max {
    left: anchor(--chart right);
    bottom: max(
      anchor(--anchor-1 top),
      anchor(--anchor-2 top),
      anchor(--anchor-3 top)
    );
    translate: 0 50%;
  }

चार्ट की वैल्यू अपडेट करने के लिए, कुछ JavaScript और चार्ट को स्टाइल करने के लिए, कुछ CSS का इस्तेमाल किया गया है. हालांकि, ऐंकर पोज़िशनिंग की सुविधा, लेआउट के अपडेट को मैनेज करती है.

देखें

हैंडल का साइज़ बदलना

आपको सिर्फ़ एक एलिमेंट को ऐंकर करने की ज़रूरत नहीं है. किसी एलिमेंट के लिए कई ऐंकर का इस्तेमाल किया जा सकता है. आपको बार चार्ट के उदाहरण में यह दिख सकता है. टूलटिप को चार्ट और फिर सही बार पर ऐंकर किया गया था. इस कॉन्सेप्ट को थोड़ा आगे बढ़ाकर, एलिमेंट का साइज़ बदला जा सकता है.

ऐंकर पॉइंट को, साइज़ बदलने के लिए कस्टम हैंडल की तरह इस्तेमाल किया जा सकता है. साथ ही, inset वैल्यू का इस्तेमाल किया जा सकता है.

.container {
   position: absolute;
   inset:
     anchor(--handle-1 top)
     anchor(--handle-2 right)
     anchor(--handle-2 bottom)
     anchor(--handle-1 left);
 }

इस डेमो में, GreenSock Draggable की मदद से हैंडल को खींचा और छोड़ा जा सकता है. हालांकि, <img> एलिमेंट का साइज़ बदलकर, कंटेनर को भरता है. यह हैंडल के बीच के अंतर को भरने के लिए अडजस्ट होता है.

देखें

SelectMenu?

आखिरी अपडेट में, हमने आपको आने वाले समय में मिलने वाली सुविधाओं की झलक दिखाई है. हालांकि, फ़ोकस किया जा सकने वाला पॉपओवर बनाया जा सकता है. इससे, आपको ऐंकर पोज़िशनिंग की सुविधा मिलती है. स्टाइल किए जा सकने वाले <select> एलिमेंट की बुनियाद बनाई जा सकती है.

<div class="select-menu">
<button popovertarget="listbox">
 Select option
 <svg>...</svg>
</button>
<div popover="auto" id="listbox">
   <option>A</option>
   <option>Styled</option>
   <option>Select</option>
</div>
</div>

anchor का इस्तेमाल करने से, यह काम आसान हो जाएगा. हालांकि, शुरुआती सीएसएस कुछ इस तरह दिख सकती है:

[popovertarget] {
 anchor-name: --select-button;
}
[popover] {
  anchor-default: --select-button;
  top: anchor(bottom);
  width: anchor-size(width);
  left: anchor(left);
}

Popover API की सुविधाओं को सीएसएस ऐंकर पोज़िशनिंग के साथ जोड़ें.

देखें

:has() जैसी चीज़ों को शामिल करना अच्छा लगता है. मार्कर को खोलकर घुमाया जा सकता है:

.select-menu:has(:open) svg {
  rotate: 180deg;
}

इसे आगे कहां ले जाया जा सकता है? इसे काम करने वाले select में बदलने के लिए, हमें और क्या करना होगा? हम इस बारे में अगले लेख में बताएंगे. हालांकि, चिंता न करें. स्टाइल किए जा सकने वाले चुनने की सुविधा देने वाले एलिमेंट जल्द ही उपलब्ध होंगे. हमारे साथ बने रहें!


बस इतना ही!

वेब प्लैटफ़ॉर्म लगातार बेहतर हो रहा है. यूज़र इंटरफ़ेस (यूआई) कंट्रोल को बेहतर बनाने के लिए, सीएसएस ऐंकर की पोज़िशनिंग एक अहम हिस्सा है. इससे आपको कुछ मुश्किल फ़ैसले लेने से बचने में मदद मिलेगी. हालांकि, इससे आपको ऐसे काम करने में भी मदद मिलेगी जो पहले कभी नहीं किए जा सके थे. जैसे, <select> एलिमेंट का स्टाइल तय करना! अपने विचारों से हमें अवगत कराएं.

Unsplash पर मौजूद, CHUTTERSNAP की फ़ोटो