टूलटिप कॉम्पोनेंट बनाना

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

इस पोस्ट में, मुझे रंग के हिसाब से अडजस्ट होने वाले और ऐक्सेस किए जा सकने वाले <tool-tip> कस्टम एलिमेंट को बनाने के बारे में अपने विचार शेयर करने हैं. डेमो आज़माएं और सोर्स देखें!

टूलटिप को अलग-अलग उदाहरणों और कलर स्कीम में काम करते हुए दिखाया गया है

अगर आपको वीडियो देखना ज़्यादा पसंद है, तो इस पोस्ट का YouTube वर्शन यहां दिया गया है:

खास जानकारी

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

यह करें: हमेशा अपने इनपुट को लेबल करें.
ऐसा न करें: लेबल के बजाय टूलटिप पर भरोसा करना

टॉगलटिप बनाम टूलटिप

कई कॉम्पोनेंट की तरह, टूलटिप के बारे में अलग-अलग जानकारी दी गई है. उदाहरण के लिए, MDN, WAI ARIA, Sarah Higley, और Inclusive Components में टूलटिप के बारे में जानकारी दी गई है. मुझे टूलटिप और टॉगलटिप के बीच का अंतर पसंद है. टूलटिप में, ऐसी अतिरिक्त जानकारी होनी चाहिए जिसके साथ इंटरैक्ट नहीं किया जा सकता. वहीं, टॉगलटिप में इंटरैक्टिविटी और ज़रूरी जानकारी शामिल हो सकती है. पॉप-अप को दो हिस्सों में बांटने की मुख्य वजह, ऐक्सेसिबिलिटी है. उपयोगकर्ताओं को पॉप-अप पर कैसे नेविगेट करना चाहिए और इसके अंदर मौजूद जानकारी और बटन को कैसे ऐक्सेस करना चाहिए. टॉगलटिप में जानकारी बहुत जल्दी बढ़ जाती है.

यहां Designcember साइट के टॉगलटिप का वीडियो दिया गया है. यह इंटरैक्टिव ओवरले है. उपयोगकर्ता इसे पिन करके खोल सकता है और एक्सप्लोर कर सकता है. इसके बाद, इसे हल्के से खारिज करके या एस्केप बटन दबाकर बंद कर सकता है:

इस GUI चैलेंज में टूलटिप का इस्तेमाल किया गया है. इसमें सीएसएस की मदद से लगभग सभी काम किए गए हैं. इसे बनाने का तरीका यहां बताया गया है.

मार्कअप

मैंने कस्टम एलिमेंट <tool-tip> का इस्तेमाल करने का विकल्प चुना है. अगर लेखकों को कस्टम एलिमेंट को वेब कॉम्पोनेंट में नहीं बदलना है, तो ऐसा करना ज़रूरी नहीं है. ब्राउज़र, <foo-bar> को <div> की तरह ही ट्रीट करेगा. कस्टम एलिमेंट को ऐसे क्लासनेम के तौर पर देखा जा सकता है जो कम खास हो. इसमें JavaScript का इस्तेमाल नहीं किया जाता.

<tool-tip>A tooltip</tool-tip>

यह एक div की तरह होता है, जिसमें कुछ टेक्स्ट होता है. [role="tooltip"] जोड़ने पर, हम स्क्रीन रीडर के ऐक्सेसिबिलिटी ट्री से जुड़ सकते हैं.

<tool-tip role="tooltip">A tooltip</tool-tip>

अब स्क्रीन रीडर इसे टूलटिप के तौर पर पहचानते हैं. यहां दिए गए उदाहरण में देखें कि पहले लिंक एलिमेंट के टूलटिप एलिमेंट को उसके ट्री में कैसे पहचाना जाता है और दूसरे लिंक एलिमेंट के टूलटिप एलिमेंट को कैसे नहीं पहचाना जाता? दूसरे व्यक्ति के पास भूमिका नहीं है. स्टाइल सेक्शन में, हम इस ट्री व्यू को बेहतर बनाएंगे.

Chrome DevTools के सुलभता ट्री का स्क्रीनशॉट, जिसमें एचटीएमएल दिखाया गया है. यह फ़ोकस किए जा सकने वाले &#39;top ; Has tooltip: Hey, a tooltip!&#39; टेक्स्ट वाला लिंक दिखाता है. इसके अंदर, &#39;top&#39; का स्टैटिक टेक्स्ट और टूलटिप एलिमेंट मौजूद है.

इसके बाद, हमें टूलटिप को फ़ोकस करने लायक नहीं बनाना है. अगर स्क्रीन रीडर को टूलटिप की भूमिका समझ में नहीं आती है, तो वह उपयोगकर्ताओं को कॉन्टेंट पढ़ने के लिए <tool-tip> पर फ़ोकस करने की अनुमति देगा. हालांकि, उपयोगकर्ता अनुभव के लिए इसकी ज़रूरत नहीं है. स्क्रीन रीडर, कॉन्टेंट को पैरंट एलिमेंट में जोड़ देंगे. इसलिए, इसे ऐक्सेस करने के लिए फ़ोकस करने की ज़रूरत नहीं है. यहां हम inert का इस्तेमाल कर सकते हैं, ताकि यह पक्का किया जा सके कि कोई भी उपयोगकर्ता अपने टैब फ़्लो में गलती से इस टूलटिप कॉन्टेंट को न ढूंढ पाए:

<tool-tip inert role="tooltip">A tooltip</tool-tip>

Chrome DevTools के सुलभता ट्री का दूसरा स्क्रीनशॉट. इस बार, टूलटिप एलिमेंट मौजूद नहीं है.

इसके बाद, मैंने टूलटिप की पोज़िशन तय करने के लिए, एट्रिब्यूट को इंटरफ़ेस के तौर पर इस्तेमाल करने का विकल्प चुना. डिफ़ॉल्ट रूप से, सभी <tool-tip> "टॉप" पोज़िशन पर सेट होते हैं. हालांकि, tip-position जोड़कर किसी एलिमेंट की पोज़िशन को पसंद के मुताबिक़ बनाया जा सकता है:

<tool-tip role="tooltip" tip-position="right ">A tooltip</tool-tip>

इस इमेज में, एक लिंक का स्क्रीनशॉट दिखाया गया है. इसके दाईं ओर टूलटिप है, जिसमें &#39;A tooltip&#39; लिखा है.

इस तरह की चीज़ों के लिए, मैं क्लास के बजाय एट्रिब्यूट का इस्तेमाल करता/करती हूं, ताकि <tool-tip> को एक ही समय में एक से ज़्यादा पोज़िशन असाइन न की जा सकें. यह सिर्फ़ एक या कोई भी नहीं हो सकता.

आखिर में, <tool-tip> एलिमेंट को उस एलिमेंट के अंदर रखें जिसके लिए आपको टूलटिप देनी है. यहां मैंने alt टेक्स्ट को देखने वाले उपयोगकर्ताओं के साथ शेयर किया है. इसके लिए, मैंने <picture> एलिमेंट में एक इमेज और alt को रखा है:<tool-tip>

<picture>
  <img alt="The GUI Challenges skull logo" width="100" src="...">
  <tool-tip role="tooltip" tip-position="bottom">
    The <b>GUI Challenges</b> skull logo
  </tool-tip>
</picture>

इस इमेज में, एक इमेज का स्क्रीनशॉट दिखाया गया है. इसमें टूलटिप में &#39;GUI Challenges skull logo&#39; लिखा है.

यहां मैंने <abbr> एलिमेंट के अंदर <tool-tip> एलिमेंट रखा है:

<p>
  The <abbr>HTML <tool-tip role="tooltip" tip-position="top">Hyper Text Markup Language</tool-tip></abbr> abbr element.
</p>

इस इमेज में, एक पैराग्राफ़ का स्क्रीनशॉट दिखाया गया है. इसमें एचटीएमएल शब्द को अंडरलाइन किया गया है और इसके ऊपर एक टूलटिप है. इसमें &#39;हाइपर टेक्स्ट मार्कअप लैंग्वेज&#39; लिखा है.

सुलभता

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

  1. कम जगह वाले या अव्यवस्थित इंटरफ़ेस में, पूरक मैसेज छिपाएं.
  2. जब कोई उपयोगकर्ता किसी एलिमेंट पर माउस घुमाता है, फ़ोकस करता है या उसे छूकर इंटरैक्ट करता है, तब मैसेज दिखाएं.
  3. कर्सर घुमाने, फ़ोकस करने या टच करने की सुविधा बंद होने पर, मैसेज को फिर से छिपाएं.
  4. आखिर में, अगर किसी उपयोगकर्ता ने मोशन कम करने की सेटिंग को चुना है, तो पक्का करें कि मोशन कम हो.

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

MacOS VoiceOver की मदद से, टूलटिप वाले लिंक को पढ़ने का स्क्रीनशॉट

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

Chrome DevTools के ऐक्सेसिबिलिटी ट्री का स्क्रीनशॉट. इसमें लिंक टेक्स्ट में &#39;top Hey, a tooltip!&#39; लिखा है.

<tool-tip> में सिर्फ़ स्क्रीन रीडर के लिए छद्म-तत्व जोड़ें. इससे, हम दृष्टिबाधित लोगों के लिए अपना प्रॉम्प्ट टेक्स्ट जोड़ सकते हैं.

&::before {
  content: "; Has tooltip: ";
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

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

Chrome DevTools के ऐक्सेसिबिलिटी ट्री का अपडेट किया गया स्क्रीनशॉट. इसमें लिंक टेक्स्ट को बेहतर तरीके से लिखा गया है, &#39;top ; Has tooltip: Hey, a tooltip!&#39;.

अब, जब स्क्रीन रीडर का इस्तेमाल करने वाला कोई व्यक्ति लिंक पर फ़ोकस करता है, तो स्क्रीन रीडर "टॉप" कहता है और कुछ देर रुकता है. इसके बाद, "में टूलटिप है: देखो, टूलटिप" बोलता है. इससे स्क्रीन रीडर का इस्तेमाल करने वाले व्यक्ति को, UX से जुड़े कुछ अच्छे सुझाव मिलते हैं. इस वजह से, लिंक के टेक्स्ट और टूलटिप के बीच में थोड़ा अंतर आ जाता है. इसके अलावा, जब "has tooltip" की सूचना दी जाती है, तो स्क्रीन रीडर का इस्तेमाल करने वाला व्यक्ति इसे आसानी से रद्द कर सकता है. ऐसा तब किया जा सकता है, जब उसने इसे पहले ही सुन लिया हो. यह सुविधा, कर्सर को तेज़ी से घुमाने और हटाने की सुविधा से मिलती-जुलती है. ऐसा इसलिए, क्योंकि आपने पहले ही पूरक मैसेज देख लिया है. इससे UX में समानता बनी रही.

स्टाइल

<tool-tip> एलिमेंट, उस एलिमेंट का चाइल्ड होगा जिसके लिए यह पूरक मैसेजिंग दिखा रहा है. इसलिए, आइए सबसे पहले ओवरले इफ़ेक्ट के लिए ज़रूरी चीज़ों के बारे में जानते हैं. position absolute की मदद से, इसे दस्तावेज़ के फ़्लो से बाहर निकालें:

tool-tip {
  position: absolute;
  z-index: 1;
}

अगर पैरंट एलिमेंट स्टैकिंग कॉन्टेक्स्ट नहीं है, तो टूलटिप खुद को सबसे नज़दीकी स्टैकिंग कॉन्टेक्स्ट के हिसाब से सेट कर लेगा. हालांकि, हमें ऐसा नहीं करना है. ब्लॉक पर एक नया सिलेक्टर है, जो आपकी मदद कर सकता है, :has():

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

:has(> tool-tip) {
  position: relative;
}

ब्राउज़र के साथ काम करने की सुविधा के बारे में ज़्यादा चिंता न करें. सबसे पहले, याद रखें कि ये टूलटिप सिर्फ़ अतिरिक्त जानकारी देती हैं. अगर वे काम नहीं करते हैं, तो कोई समस्या नहीं होनी चाहिए. दूसरे चरण में, JavaScript सेक्शन में हम एक स्क्रिप्ट डिप्लॉय करेंगे. इससे हमें उन ब्राउज़र के लिए ज़रूरी फ़ंक्शन को polyfill करने में मदद मिलेगी जिनमें :has() काम नहीं करता.

इसके बाद, टूलटिप को नॉन-इंटरैक्टिव बनाते हैं, ताकि वे अपने पैरंट एलिमेंट से पॉइंटर इवेंट न चुराएं:

tool-tip {
  
  pointer-events: none;
  user-select: none;
}

इसके बाद, ओपैसिटी की मदद से टूलटिप को छिपाएं, ताकि हम क्रॉसफ़ेड की मदद से टूलटिप को ट्रांज़िशन कर सकें:

tool-tip {
  opacity: 0;
}

:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
}

:is() और :has() यहां अहम भूमिका निभाते हैं. ये tool-tip में मौजूद पैरंट एलिमेंट को उपयोगकर्ता की इंटरैक्टिविटी के बारे में बताते हैं, ताकि चाइल्ड टूलटिप की दृश्यता को टॉगल किया जा सके. माउस का इस्तेमाल करने वाले लोग, बटन पर कर्सर घुमा सकते हैं. कीबोर्ड और स्क्रीन रीडर का इस्तेमाल करने वाले लोग, बटन पर फ़ोकस कर सकते हैं. वहीं, टचस्क्रीन का इस्तेमाल करने वाले लोग, बटन पर टैप कर सकते हैं.

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

डार्क मोड में टूलटिप का स्क्रीनशॉट. यह &#39;ब्लॉक-स्टार्ट&#39; लिंक के ऊपर दिख रहा है.

tool-tip {
  --_p-inline: 1.5ch;
  --_p-block: .75ch;
  --_triangle-size: 7px;
  --_bg: hsl(0 0% 20%);
  --_shadow-alpha: 50%;

  --_bottom-tip: conic-gradient(from -30deg at bottom, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) bottom / 100% 50% no-repeat;
  --_top-tip: conic-gradient(from 150deg at top, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) top / 100% 50% no-repeat;
  --_right-tip: conic-gradient(from -120deg at right, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) right / 50% 100% no-repeat;
  --_left-tip: conic-gradient(from 60deg at left, rgba(0,0,0,0), #000 1deg 60deg, rgba(0,0,0,0) 61deg) left / 50% 100% no-repeat;

  pointer-events: none;
  user-select: none;

  opacity: 0;
  transform: translateX(var(--_x, 0)) translateY(var(--_y, 0));
  transition: opacity .2s ease, transform .2s ease;

  position: absolute;
  z-index: 1;
  inline-size: max-content;
  max-inline-size: 25ch;
  text-align: start;
  font-size: 1rem;
  font-weight: normal;
  line-height: normal;
  line-height: initial;
  padding: var(--_p-block) var(--_p-inline);
  margin: 0;
  border-radius: 5px;
  background: var(--_bg);
  color: CanvasText;
  will-change: filter;
  filter:
    drop-shadow(0 3px 3px hsl(0 0% 0% / var(--_shadow-alpha)))
    drop-shadow(0 12px 12px hsl(0 0% 0% / var(--_shadow-alpha)));
}

/* create a stacking context for elements with > tool-tips */
:has(> tool-tip) {
  position: relative;
}

/* when those parent elements have focus, hover, etc */
:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
  transition-delay: 200ms;
}

/* prepend some prose for screen readers only */
tool-tip::before {
  content: "; Has tooltip: ";
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

/* tooltip shape is a pseudo element so we can cast a shadow */
tool-tip::after {
  content: "";
  background: var(--_bg);
  position: absolute;
  z-index: -1;
  inset: 0;
  mask: var(--_tip);
}

/* top tooltip styles */
tool-tip:is(
  [tip-position="top"],
  [tip-position="block-start"],
  :not([tip-position]),
  [tip-position="bottom"],
  [tip-position="block-end"]
) {
  text-align: center;
}

थीम में बदलाव करना

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

@media (prefers-color-scheme: light) {
  tool-tip {
    --_bg: white;
    --_shadow-alpha: 15%;
  }
}

टूलटिप के हल्के और गहरे रंग वाले वर्शन का साइड-बाय-साइड स्क्रीनशॉट.

लाइट थीम के लिए, हम बैकग्राउंड को सफ़ेद रंग में बदलते हैं. साथ ही, ओपैसिटी को अडजस्ट करके, शैडो को ज़्यादा हल्का कर देते हैं.

दाएं से बाएं

दाईं से बाईं ओर पढ़ने के मोड के साथ काम करने के लिए, कस्टम प्रॉपर्टी, दस्तावेज़ की दिशा की वैल्यू को -1 या 1 की वैल्यू में सेव करेगी.

tool-tip {
  --isRTL: -1;
}

tool-tip:dir(rtl) {
  --isRTL: 1;
}

इसका इस्तेमाल, टूलटिप को सही जगह पर रखने के लिए किया जा सकता है:

tool-tip[tip-position="top"]) {
  --_x: calc(50% * var(--isRTL));
}

साथ ही, यह भी पता लगाने में मदद करता है कि त्रिकोण कहां है:

tool-tip[tip-position="right"]::after {
  --_tip: var(--_left-tip);
}

tool-tip[tip-position="right"]:dir(rtl)::after {
  --_tip: var(--_right-tip);
}

आखिर में, इसका इस्तेमाल translateX() पर लॉजिकल ट्रांसफ़ॉर्म के लिए भी किया जा सकता है:

--_x: calc(var(--isRTL) * -3px * -1);

टूलटिप की पोज़िशनिंग

टूलटिप की पोज़िशन को लॉजिकल तरीके से सेट करने के लिए, inset-block या inset-inline प्रॉपर्टी का इस्तेमाल करें. इससे टूलटिप की फ़िज़िकल और लॉजिकल, दोनों पोज़िशन को मैनेज किया जा सकता है. यहां दिए गए कोड में दिखाया गया है कि बाईं से दाईं और दाईं से बाईं ओर, दोनों दिशाओं के लिए चारों पोज़िशन को कैसे स्टाइल किया जाता है.

टॉप और ब्लॉक-स्टार्ट अलाइनमेंट

इस स्क्रीनशॉट में, बाएं से दाएं और दाएं से बाएं की ओर टेक्स्ट लिखने की सुविधा के लिए, सबसे ऊपर मौजूद बटन की जगह में अंतर दिखाया गया है.

tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position])) {
  inset-inline-start: 50%;
  inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-size));
  --_x: calc(50% * var(--isRTL));
}

tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position]))::after {
  --_tip: var(--_bottom-tip);
  inset-block-end: calc(var(--_triangle-size) * -1);
  border-block-end: var(--_triangle-size) solid transparent;
}

दाईं ओर और लाइन के आखिर में अलाइन करना

इस स्क्रीनशॉट में, बाएं से दाएं की ओर टेक्स्ट की दाईं ओर मौजूद जगह और दाएं से बाएं की ओर टेक्स्ट के आखिर में मौजूद जगह के बीच का अंतर दिखाया गया है.

tool-tip:is([tip-position="right"], [tip-position="inline-end"]) {
  inset-inline-start: calc(100% + var(--_p-inline) + var(--_triangle-size));
  inset-block-end: 50%;
  --_y: 50%;
}

tool-tip:is([tip-position="right"], [tip-position="inline-end"])::after {
  --_tip: var(--_left-tip);
  inset-inline-start: calc(var(--_triangle-size) * -1);
  border-inline-start: var(--_triangle-size) solid transparent;
}

tool-tip:is([tip-position="right"], [tip-position="inline-end"]):dir(rtl)::after {
  --_tip: var(--_right-tip);
}

बॉटम और ब्लॉक-एंड अलाइनमेंट

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

tool-tip:is([tip-position="bottom"], [tip-position="block-end"]) {
  inset-inline-start: 50%;
  inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-size));
  --_x: calc(50% * var(--isRTL));
}

tool-tip:is([tip-position="bottom"], [tip-position="block-end"])::after {
  --_tip: var(--_top-tip);
  inset-block-start: calc(var(--_triangle-size) * -1);
  border-block-start: var(--_triangle-size) solid transparent;
}

बाईं ओर और लाइन की शुरुआत में अलाइन करना

इस स्क्रीनशॉट में, बाएं से दाएं (लेफ़्ट) और दाएं से बाएं (इनलाइन-स्टार्ट) अलाइनमेंट के बीच का अंतर दिखाया गया है.

tool-tip:is([tip-position="left"], [tip-position="inline-start"]) {
  inset-inline-end: calc(100% + var(--_p-inline) + var(--_triangle-size));
  inset-block-end: 50%;
  --_y: 50%;
}

tool-tip:is([tip-position="left"], [tip-position="inline-start"])::after {
  --_tip: var(--_right-tip);
  inset-inline-end: calc(var(--_triangle-size) * -1);
  border-inline-end: var(--_triangle-size) solid transparent;
}

tool-tip:is([tip-position="left"], [tip-position="inline-start"]):dir(rtl)::after {
  --_tip: var(--_left-tip);
}

ऐनिमेशन

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

डिफ़ॉल्ट रूप से सुरक्षित और काम का ट्रांज़िशन

ओपैसिटी और ट्रांसफ़ॉर्म को ट्रांज़िशन करने के लिए, टूलटिप एलिमेंट को इस तरह स्टाइल करें:

tool-tip {
  opacity: 0;
  transform: translateX(var(--_x, 0)) translateY(var(--_y, 0));
  transition: opacity .2s ease, transform .2s ease;
}

:has(> tool-tip):is(:hover, :focus-visible, :active) > tool-tip {
  opacity: 1;
  transition-delay: 200ms;
}

ट्रांज़िशन में मोशन जोड़ना

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

@media (prefers-reduced-motion: no-preference) {
  :has(> tool-tip:is([tip-position="top"], [tip-position="block-start"], :not([tip-position]))):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_y: 3px;
  }

  :has(> tool-tip:is([tip-position="right"], [tip-position="inline-end"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_x: -3px;
  }

  :has(> tool-tip:is([tip-position="bottom"], [tip-position="block-end"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_y: -3px;
  }

  :has(> tool-tip:is([tip-position="left"], [tip-position="inline-start"])):not(:hover):not(:focus-visible):not(:active) tool-tip {
    --_x: 3px;
  }
}

ध्यान दें कि "out" स्थिति सेट की जा रही है, क्योंकि "in" स्थिति translateX(0) पर है.

JavaScript

मेरी राय में, JavaScript का इस्तेमाल करना ज़रूरी नहीं है. ऐसा इसलिए है, क्योंकि आपके यूज़र इंटरफ़ेस (यूआई) में किसी टास्क को पूरा करने के लिए, इनमें से किसी भी टूलटिप को पढ़ना ज़रूरी नहीं होना चाहिए. इसलिए, अगर टूलटिप पूरी तरह से काम नहीं करती हैं, तो इससे कोई खास फ़र्क़ नहीं पड़ना चाहिए. इसका यह भी मतलब है कि हम टूलटिप को बेहतर बनाने के लिए लगातार काम कर सकते हैं. आखिरकार, सभी ब्राउज़र :has() के साथ काम करेंगे. इसके बाद, इस स्क्रिप्ट को पूरी तरह से हटाया जा सकता है.

पॉलीफ़िल स्क्रिप्ट दो काम करती है. ऐसा सिर्फ़ तब होता है, जब ब्राउज़र :has() के साथ काम नहीं करता. सबसे पहले, देखें कि :has() के साथ काम करने वाले:

if (!CSS.supports('selector(:has(*))')) {
  // do work
}

इसके बाद, <tool-tip> के पैरंट एलिमेंट ढूंढें और उन्हें क्लासनेम दें, ताकि वे काम कर सकें:

if (!CSS.supports('selector(:has(*))')) {
  document.querySelectorAll('tool-tip').forEach(tooltip =>
    tooltip.parentNode.classList.add('has_tool-tip'))
}

इसके बाद, उस क्लासनेम का इस्तेमाल करने वाली स्टाइल का एक सेट डालें. इससे, :has() सेलेक्टर के जैसा ही व्यवहार दिखेगा:

if (!CSS.supports('selector(:has(*))')) {
  document.querySelectorAll('tool-tip').forEach(tooltip =>
    tooltip.parentNode.classList.add('has_tool-tip'))

  let styles = document.createElement('style')
  styles.textContent = `
    .has_tool-tip {
      position: relative;
    }
    .has_tool-tip:is(:hover, :focus-visible, :active) > tool-tip {
      opacity: 1;
      transition-delay: 200ms;
    }
  `
  document.head.appendChild(styles)
}

बस इतना ही करना है. अब सभी ब्राउज़र में टूलटिप दिखेंगी, अगर :has() काम नहीं करता है.

नतीजा

अब आपको पता चल गया है कि मैंने यह कैसे किया. अब आप कैसे करेंगे‽ 🙂 मुझे इन एपीआई का इंतज़ार है: टॉगलटिप को आसान बनाने के लिए popup एपीआई, z-इंडेक्स की समस्याओं से बचने के लिए टॉप लेयर, और विंडो में चीज़ों को बेहतर तरीके से रखने के लिए anchor एपीआई. तब तक, मैं टूलटिप बनाऊँगा.

आइए, हम अपने तरीकों में विविधता लाएं और वेब पर काॅन्टेंट पोस्ट करने के सभी तरीके जानें.

डेमो बनाएं और मुझे ट्वीट करें. इसके बाद, मैं इसे यहां कम्यूनिटी रीमिक्स सेक्शन में जोड़ दूंगा!

कम्यूनिटी रीमिक्स

फ़िलहाल, यहां देखने के लिए कुछ भी नहीं है.

संसाधन