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

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

<!-- 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 की ज़रूरत होती है या वे अतिरिक्त मार्कअप जोड़ते हैं. सीएसएस ऐंकर पोज़िशनिंग एपीआई का मकसद, टेदरिंग एलिमेंट के लिए सीएसएस एपीआई उपलब्ध कराकर इस समस्या को हल करना है. यह दूसरे एलिमेंट की पोज़िशन और साइज़ के आधार पर, किसी एलिमेंट को पोज़िशन और साइज़ देने का तरीका बताता है.

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

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

"प्रयोग के तौर पर उपलब्ध वेब प्लैटफ़ॉर्म सुविधाएं" के पीछे, Chrome कैनरी में सीएसएस ऐंकर पोज़िशनिंग एपीआई का इस्तेमाल किया जा सकता है फ़्लैग करें. इस फ़्लैग को चालू करने के लिए, Chrome कैनरी खोलें और 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-ऐक्सिस पर नहीं. दस्तावेज़ पढ़ें. इससे आपको समस्या का हल अपने हिसाब से मिल जाएगा.

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

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

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

  • इसके लिए 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 के बराबर होगा.
  • फ़ॉलबैक: यह एक वैकल्पिक फ़ॉलबैक वैल्यू है, जो लंबाई या प्रतिशत स्वीकार करती है.

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

.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);
  }
}


उदाहरण

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

संदर्भ मेन्यू

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

मार्कअप यहां अहम हिस्सा नहीं है. लेकिन, 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 का इस्तेमाल किया जा सकता है और कुछ सीएसएस का इस्तेमाल करके चार्ट को स्टाइल किया जा सकता है. हालांकि, ऐंकर विज्ञापन दिखाने के लिए, लेआउट से जुड़े अपडेट पर ध्यान दिया जाता है.

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

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

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

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

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

एक Selectमेन्यू?

यह आखिरी सवाल उस चीज़ के बारे में थोड़ी सी झलक है, जो आने वाली है. हालांकि, फ़ोकस करने लायक पॉपओवर बनाया जा सकता है और अब ऐंकर विज्ञापन दिखाया जा सकता है. किसी स्टाइल वाले <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);
}

पॉपओवर एपीआई की सुविधाओं को सीएसएस ऐंकर पोज़िशन के साथ जोड़ें और सेट अप पूरा करें.

देखें

जब आप :has() जैसी चीज़ों को पेश करते हैं, तो यह खुशखबरी है. खुला होने पर मार्कर को घुमाया जा सकता है:

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

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


बस इतना ही!

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

Unस्प्लैश पर CHUTTERSNAP की फ़ोटो