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

रंग के हिसाब से काम करने वाला और ऐक्सेस किया जा सकने वाला टूलटिप कस्टम एलिमेंट बनाने के बारे में बुनियादी जानकारी.

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

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

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

खास जानकारी

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

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

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

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

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

सीएसएस की मदद से करीब-करीब हर काम करना चाहते हैं और इसे बनाने का तरीका जानें.

मार्कअप

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

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

यह एक डिव की तरह है, जिसके अंदर कुछ टेक्स्ट है. हम [role="tooltip"] को जोड़कर, सक्षम स्क्रीन रीडर के सुलभता ट्री के साथ जुड़ सकते हैं.

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

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

एचटीएमएल को दिखाने वाले, Chrome DevTools के सुलभता ट्री का स्क्रीनशॉट. यह ऐसा लिंक दिखाता है जिस पर &#39;सबसे ऊपर&#39;; टूलटिप मौजूद है: नमस्ते, एक टूलटिप!&#39;. इस पर फ़ोकस किया जा सकता है. इसके अंदर, &#39;सबसे ऊपर&#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;टूलटिप&#39; लिखा है.

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

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

<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;जीयूआई चैलेंज में खोपड़ी का लोगो&#39; लिखा है.

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

<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;नमस्ते, टूलटिप!&#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;
}

नीचे अपडेट किया गया सुलभता ट्री देखा जा सकता है, जिसमें अब लिंक टेक्स्ट के बाद सेमीकॉलन है और टूलटिप "इसमें टूलटिप है: " का प्रॉम्प्ट दिखता है.

Chrome DevTools सुलभता ट्री के अपडेट किए गए स्क्रीनशॉट में, लिंक टेक्स्ट में &#39;top ; टूलटिप&#39; को बेहतर बनाया गया है: नमस्ते, एक टूलटिप!&#39;.

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

स्टाइल

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

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

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

ब्राउज़र सहायता

  • 105
  • 105
  • 121
  • 15.4

सोर्स

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

ब्राउज़र समर्थन के बारे में ज्यादा चिंता न करें. सबसे पहले, याद रखें कि ये टूलटिप अनुपूरक हैं. अगर वे काम नहीं करते हैं, तो यह अच्छा होना चाहिए. दूसरा, JavaScript सेक्शन में हम एक स्क्रिप्ट डिप्लॉय करेंगे. इसकी मदद से, उन ब्राउज़र के काम करने के तरीके को बेहतर बनाया जा सकेगा जिनकी ज़रूरत :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;block-start&#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);
}

Animation

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

एक सुरक्षित और आसान डिफ़ॉल्ट ट्रांज़िशन

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

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

ध्यान दें, यह "बाहर" की स्थिति सेट कर रहा है, क्योंकि "इन" स्थिति 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 एपीआई का इस्तेमाल किया जा सके. तब तक, मैं टूलटिप बनाऊंगी.

चलिए, इसे अलग-अलग तरीके से समझें और वेब पर सभी के काम करने के तरीके सीखें.

एक डेमो तैयार करें, मुझे ट्वीट करें वाले लिंक, और मैं उसे नीचे दिए गए कम्यूनिटी रीमिक्स सेक्शन में जोड़ दूंगी!

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

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

रिसॉर्स