CSS के साथ जादुई, एनिमेटेड Tooltips कैसे बनाएं
Hindi (हिंदी) translation by Ashish Rampal (you can also view the original English article)
टूलटिप्स एक UI को बढ़ाने के लिए एक बढ़िया तरीका है, जब आपके यूज़र्स को उस फैंसी icon के लिए कुछ अतिरिक्त संदर्भ (context) की आवश्यकता होती है, या जब वे एक बटन पर क्लिक करने के लिए कुछ आश्वासन (reassurance) चाहते हैं, या एक image के साथ जाने के लिए Easter Egg कैप्शन (caption) भी. चलो कुछ एनिमेटेड टूलटिप्स (tooltips) बनाते हैं, अभी, HTML और CSS के अलावा कुछ नहीं।
Demo
हम इसके लिए काम कर रहे हैं:
कड़ाही में डूबने से पहले, हम वास्तव में कैसा चल रहे हैं ये झाँक लेते हैं. हमारा मुख्य लक्ष्य टूलटिप को जोड़ने का आसान तरीका पता चलना है, इसलिए हम एक कस्टम tooltip
attribute जोड़कर ऐसा करेंगे:
<span tooltip="message">visible text or icon, etc.</span>
पहुंच और क्षमता के बारे में एक नोट
यदि आप 508-compliant टूलटिप्स की खोज कर रहे हैं, या कंटेनर collision का पता लगाने और/या HTML content बनाम plain text के लिए समर्थन के साथ स्मार्ट टूलटिप्स की आवश्यकता है, तो बहुत सारे समाधान हैं जो आपके लिए उन जरूरतों को हल करने के लिए third-party के स्क्रिप्ट का उपयोग करते हैं.
"JavaScript पूरी तरह से सुलभ इंटरैक्टिव components को बनाने के लिए जरूरी है।" - Sara Soueidan, एक पूरी तरह से सुलभ मदद टूलटिप का निर्माण करना ... मेरी सोच से ज्यादा कठिन है
यह ट्यूटोरियल विशेष रूप से पहुंच (accessibility) का समाधान नहीं करता है आप अपने यूज़र्स को जानते हैं और उनकी क्या जरूरते है, इसलिए इस संबंध में उनकी जरूरतों को भी ध्यान में रखना सुनिश्चित करें।
चलो कुछ उम्मीदें (Expectations) सेट करें
- कोई JavaScript की आवश्यकता नहीं है
- हम एट्रिब्यूट सेलेक्टर्स (classnames नहीं) का उपयोग कर रहे हैं, CSS के बिल्ट-इन (built-in) pattern matching के साथ
- मौजूदा DOM तत्वों में जोड़ें (आपके मार्कअप में कोई नए element की आवश्यक नहीं है *)
- कोड के उदाहरण prefix-free हैं (यदि आवश्यक हो तो अपने लक्षित (target) ब्राउज़रों के लिए vendor prefixes जोड़ें)
- टूलटिप्स ट्रिगर करने के लिए mouseover/hover को मान लीजिये
- केवल प्लेन टेक्स्ट टूलटिप (Plain text tooltips) (HTML, images, आदि का सपोर्ट नहीं हैं)
- टूलटिप्स लगाने में सूक्ष्म एनिमेशन
ठीक है! चलो इस नाव को rock करें!
अरे रुको। हमारे पास पहले एलिमेंट से निपटने के लिए एक asterisk का चिह्न है, "किसी अतिरिक्त मार्कअप की ज़रूरत नहीं". आखिरकार यह एक जादू है. हमारे टूलटिप्स को वास्तव में किसी भी अतिरिक्त DOM एलिमेंट की ज़रूरत नहीं है क्योंकि वे पूरी तरह pseudo-element (::before
और ::after
चीजे) के बने होते हैं, जिसे हम CSS के माध्यम से नियंत्रित कर सकते हैं।
यदि आप किसी एलिमेंट के pseudo-elements का उपयोग पहले से ही styles के किसी अन्य सेट से कर रहे हैं और आप उस एलिमेंट पर टूलटिप चाहते हैं, तो आपको थोड़ा पुनर्रचना (restructure) करने की आवश्यकता हो सकती है।
टूलटिप पार्टी की तरह कोई पार्टी नहीं है!
रुकिए। Gremlins! एक और चेतावनी: CSS positioning. टूलटिप्स को ठीक से कार्य करने के लिए, उनके पैरेंट एलिमेंट (जिस चीज़ को हम टूलटिप से जोड़ रहे हैं) की आवश्यकता है
-
position: relative
, या -
position: absolute
, या position: fixed
असल में, position: static
के अलावा अन्य कुछ भी - यह ब्राउज़र द्वारा सभी एलिमेंट्स के लिए असाइन (assign) किया गया डिफ़ॉल्ट position मोड है। टूलटिप्स की पोजीशन absolutely है और इसलिए उनको सीमाओं को जानने की जरूरत है जिसमें उनकी absolute होने का अर्थ है. डिफ़ॉल्ट position निदेशिका (directive) static अपनी सीमाओं को नहीं घोषित (declare) करता है और हमारे टूलटिप्स को इसके विपरीत धक्का देने के लिए कॉन्टेक्स्ट (context) नहीं देता, इसलिए टूलटिप्स अगले निकटतम parental एलिमेंट का प्रयोग करेंगे जिनकी घोषित सीमा होती है
टूलटिप्स का उपयोग करने के तरीके के साथ आपको यह तय करने की आवश्यकता होगी कि कौन-सा position directive सबसे अच्छा काम करता है. यह टुटोरिअल पैरेंट एलिमेंट के लिए position: relative
को मानता है. यदि आपकी UI absolute पोजीशन एलिमेंट पर निर्भर है, तो उस एलिमेंट पर टूलटिप को तैनात करने के लिए कुछ पुनर्संरचना (restructuring) (अतिरिक्त मार्कअप) भी आवश्यक हो सकते हैं.
चलो कूदते हैं और देखें कि क्या हो रहा है।
Attribute Selectors; A Quick Refresher
अधिकांश CSS नियमों को classnames को दिमाग में रख लिखा जाता है, जैसे कि .this-thing
, लेकिन CSS के पास बहुत सारे सिलेक्टर टाइप्स हैं. हमारा जादुई टूलटिप एट्रिब्यूट सेलेक्टर्स का प्रयोग करने जा रहा है-जो स्क्वायर (square) ब्रैकेट का नोटेशन (notation) है:
[foo] { background: rgba(0, 0, 0, 0.8); color: #fff; }
जब ब्राउज़र कुछ इस स्थिति का सामना करता है:
<span foo>Check it out!</span>
यह पता चलेगा कि उसे [foo]
नियमों को लागू करने की आवश्यकता है क्योंकि <span>
टैग में foo नाम का एक एट्रिब्यूट है इस मामले में, स्पैन में सफेद टेक्स्ट वाला एक translucent-black बैकग्राउंड होगा।
HTML एलिमेंट्स में विभिन्न built-in एट्रिब्यूट हैं, लेकिन हम भी अपना स्वयं का बना सकते हैं foo
या tooltip
की तरह. डिफ़ॉल्ट रूप से, HTML नहीं जानता कि इसका क्या मतलब है, लेकिन CSS के साथ हम HTML को इसका मतलब बता सकते हैं.
एट्रिब्यूट सलैक्टर्स क्यों?
हम मुख्य रूप से चिंताओं को अलग करने के लिए एट्रिब्यूट सिलेक्टर का उपयोग करेंगे. classnames पर एट्रिब्यूट का उपयोग करने से हमें कोई विशेष बोनस अंक नहीं मिलता; क्लासेज (classes) और एट्रिब्यूट की एक ही विशिष्टता है हालांकि, ऐट्रिब्यूट्स का उपयोग करके हम कंटेंट के साथ अपने कंटेंट को रख सकते हैं क्योंकि HTML ऐट्रिब्यूट्स की वैल्यू हो सकती है जबकि classnames की नहीं.
इस उदाहरण कोड में एट्रिब्यूट [tooltip]
बनाम classname .tooltip
पर विचार करें। classname एक एट्रिब्यूट [class]
के लिए वैल्यू में से एक है, जबकि टूलटिप एट्रिब्यूट की एक वैल्यू है, जो टेक्स्ट है जिसे हम प्रदर्शित करना चाहते हैं।
<span class="tooltip another-classname">lorem ipsum</span> <span tooltip="sit dolar amet">lorem ipsum</span>
अब टूलटिप अल्केमी (Alchemy) में प्रवेश करना
हमारे टूलटिप्स दो अलग-अलग ऐट्रिब्यूट्स का उपयोग करेंगे:
-
tooltip
: यह टूलटिप के कंटेंट को (एक सादे टेक्स्ट स्ट्रिंग की तरह) रखता है -
flow
: वैकल्पिक; यह हमें टूलटिप को प्रदर्शित करने के तरीके को नियंत्रित करने की अनुमति देता है। कई ऐसे प्लेसमेंट हैं जो हम समर्थन कर सकते थे लेकिन हम चार सामान्य प्लेसमेंट को कवर करेंगे:
ऊपर, बाएं (left), दाएं (right), नीचे
अब, सभी टूलटिप्स के लिए ग्राउंड वर्क को सेट करें। सभी टूलटिप्स पर 1-5 चरण के नियम लागू होते हैं, चाहे हम उन्हें किसी भी flow को देते हैं चरण 6-7 में विभिन्न flow
वैल्यूज के बीच अंतर है।
1. रिलेटिविटी (Relativity)
यह टूलटिप के पैरेंट एलिमेंट के लिए है. आइए position directive असाइन करें ताकि टूलटिप के हिस्से की absolute positioning (::before
और ::after
pseudo-element) को इस पैरेंट एलिमेंट के संदर्भ में रखा गया हो, न कि page at-large के संदर्भ (context) में या ग्रैंडपैरेंट (grandparent) एलिमेंट या कुछ DOM tree के अन्य बाहरी एलिमेंट.
[tooltip] { position: relative; }
2. Pseudo-element Prime Time
यह pseudo-elements को प्रधान (prime) करने का समय है. यहां हम सामान्य प्रॉपर्टीज को ::before
और ::after
दोनों टुकड़ो के लिए सेट करेंगे। content
प्रॉपर्टी है जो वास्तव में एक pseudo-element का निर्माण करती है, लेकिन हम वहां जल्द ही पहुंचेंगे.
[tooltip]::before, [tooltip]::after { line-height: 1; user-select: none; pointer-events: none; position: absolute; display: none; opacity: 0; /* opinions */ text-transform: none; font-size: .9em; }
3. The Dink
मुझे नहीं पता कि "dink" क्यों समझ में आता है, मैंने हमेशा इसे यही कहा है। यह छोटा त्रिकोण का नुकीला भाग है जो उस चीज़ को इंगित करके अपने speech bubble feel को टूल टिप देता है जिसने इसे लागू किया था। नोटिस हम बॉर्डर के रंग के लिए transparent
उपयोग कर रहे हैं; हम बाद में रंग में जोड़ देंगे, जैसे हम इसे कैसे जोड़ते हैं टूलटिप के flow
पर निर्भर करता है
[tooltip]::before { content: ''; z-index: 1001; border: 5px solid transparent; }
यह कोई टाइपिंग की गलती नहीं है जो content: '';
डिक्लेरेशन (declaration) में एक मान (value) के लिए एक खाली स्ट्रिंग है. हम वहां कुछ भी नहीं चाहते हैं, लेकिन हमें pseudo-element के अस्तित्व के लिए उस प्रॉपर्टी की ज़रूरत है।
त्रिकोण (triangle) बनाने के लिए हम कुछ मोटाई (thickness) के साथ एक खाली बॉक्स में (कोई कंटेंट नहीं) एक सॉलिड बॉर्डर डिफाइन कर रहे हैं जिसकी कोई चौड़ाई (width) और कोई लम्बाई (height) नहीं है, और बॉक्स के केवल एक तरफ बॉर्डर को कलर दे रहे हैं. अधिक जानकारी के लिए निम्नलिखित ट्यूटोरियल की जांच करें:
4. Bubbles!
यह इस समस्या का सबसे महत्वपुर्ण हिस्सा है, ध्यान दें की content: attr(tooltip)
क्या करता है, "इस pseudo-element को अपने कंटेंट के रूप में tooltip
एट्रिब्यूट का मान का उपयोग करना चाहिए।" यही कारण है कि classnames पर एट्रिब्यूट का उपयोग करना बहुत अच्छा है!
[tooltip]::after { content: attr(tooltip); /* magic! */ z-index: 1000; /* most of the rest of this is opinion */ font-family: Helvetica, sans-serif; text-align: center; /* Let the content set the size of the tooltips but this will also keep them from being obnoxious */ min-width: 3em; max-width: 21em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; /* visible design of the tooltip bubbles */ padding: 1ch 1.5ch; border-radius: .3ch; box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35); background: #333; color: #fff; }
dink और bubble दोनों के लिए z-index
की वैल्यूज को ध्यान दें। यह मनमानी (arbitrary) वैल्यू हैं, लेकिन ध्यान रखें कि एक z-index
की वैल्यू relative है। अर्थ: z-index 3 वाले एक एलिमेंट के अंदर 1001 वैल्यू के एक z-index एलिमेंट का अर्थ है की 1001 वाला एलिमेंट z-index: 3 वाले कंटेनर के अंदर सबसे ऊपर (top-most) है.
Bubble के z-index
को dink के z-index
से कम से कम एक कदम नीचे होना चाहिए, यदि यह dink के समान या अधिक है, तो आप dink पर एक असंगत रंग प्रभाव (inconsistent coloring effect) देखेंगे यदि आपकी टूलटिप्स box-shadow
के साथ है.
z-index प्रॉपर्टी को अधिक विस्तृत रूप से देखने के लिए, निम्नलिखित ट्यूटोरियल पर एक नज़र डालें:
5. Interaction Action
टूलटिप के साथ एलिमेंट पर माउस को मँडरा (hover) करके हमारे टूलटिप्स सक्रिय (activated) होते हैं ... लगभग
[tooltip]:hover::before, [tooltip]:hover::after { display: block; }
यदि आप स्टेप 2 में हमारे स्टाइल ब्लॉक पर वापस देखते हैं, तो आपको यह दिखेगा की हमने हमारे टूलटिप के पार्ट्स के लिए opacity: 0;
को display: none;
के साथ प्रयोग किया है. हमने यह किया इसलिए जब टूलटिप्स दिखे (show) या छुपे (hide) तो हम CSS के एनीमेशन इफेक्ट्स का प्रयोग कर सकते हैं.
display
प्रॉपर्टी को एनिमेटेड नहीं किया जा सकता है, लेकिन opacity
को किया जा सकता है! हम एनिमेशन के साथ अंत में डील करेंगे. यदि आप एनिमेटेड टूलटिप्स की परवाह नहीं करते हैं, तो बस स्टेप 2 में से opacity: 0;
को मिटा दें और स्टेप 7 में एनीमेशन पर ध्यान न दें.
जिस अंतिम चीज की आवश्यकता होगी जो की अभी भी सभी टूलटिप्स पर लागू होती है वो है टूलटिप को रोकने का एक तरीका, अगर इसमें कोई कंटेंट नहीं है तो. यदि आप किसी प्रकार की डायनामिक प्रणाली (dynamic system) (Vuy.js, Angular, या React, PHP, आदि) के साथ टूलटिप्स को populate कर रहे हैं तो हमें अजीब से खाली bubbles नहीं चाहिए!
/* don't show empty tooltips */ [tooltip='']::before, [tooltip='']::after { display: none !important; }
6. Flow Control
यह कदम काफी जटिल हो सकता है क्योंकि हम कुछ सामान्य सेलेक्टर्स का उपयोग नहीं करेंगे जिससे कि हमारे टूलटिप्स उनके flow
वैल्यूज (या इसके बिना) के आधार पर उनके प्लेसमेंट से निपट सकें।
"अजीब बातें Circle-K पर चल रहे हैं." - Ted Theodore Logan
स्टाइल्स में कूदने से पहले, हम कुछ सिलेक्टर पैटर्नों (patterns) पर एक नज़र डालेंगे जिनका हम उपयोग करेंगे।
[tooltip]:not([flow])::before, [tooltip][flow^="up"]::before { /* ... properties: values ... */ }
यह ब्राउज़र को बता रहा है: "tooltip
एट्रिब्यूट वाले सभी एलिमेंट्स के लिए जिनका या तो कोई flow
एट्रिब्यूट नहीं है, या 'up' के साथ शुरू होने वाली वैल्यू के साथ flow
होता है: इन स्टाइल्स को इसके ::before
pseudo-element पर लागू करें।"
हम यहां एक पैटर्न का उपयोग कर रहे हैं ताकि इन्हें बहुत अधिक CSS को दोहराने की आवश्यकता के बिना अन्य flow तक बढ़ाया जा सके। यह पैटर्न flow^="up"
, ^=
(प्रारंभ होता है) मैटचर (matcher) का उपयोग कर रहा है. इससे स्टाइल्स को ऊपर-दाएं (up-right) और ऊपर-बाएं (up-left) पर लागू करने की अनुमति मिल सकती है, आप उन flow कंट्रोल्स को जोड़ना चाहते हैं, हम यहां उनको कवर करने नहीं जा रहे हैं, लेकिन आप उन्हें CodePen में अपने वास्तविक टूलटिप डेमो पर उपयोग में देख सकते हैं.
इस ट्यूटोरियल के सभी चार प्रवाहों के लिए CSS ब्लॉक यहां दिए गए हैं।
Up (default):
/* ONLY the ::before */ [tooltip]:not([flow])::before, [tooltip][flow^="up"]::before { bottom: 100%; border-bottom-width: 0; border-top-color: #333; } /* ONLY the ::after */ [tooltip]:not([flow])::after, [tooltip][flow^="up"]::after { bottom: calc(100% + 5px); } /* Both ::before & ::after */ [tooltip]:not([flow])::before, [tooltip]:not([flow])::after, [tooltip][flow^="up"]::before, [tooltip][flow^="up"]::after { left: 50%; transform: translate(-50%, -.5em); }
Down:
[tooltip][flow^="down"]::before { top: 100%; border-top-width: 0; border-bottom-color: #333; } [tooltip][flow^="down"]::after { top: calc(100% + 5px); } [tooltip][flow^="down"]::before, [tooltip][flow^="down"]::after { left: 50%; transform: translate(-50%, .5em); }
Left:
[tooltip][flow^="left"]::before { top: 50%; border-right-width: 0; border-left-color: #333; left: calc(0em - 5px); transform: translate(-.5em, -50%); } [tooltip][flow^="left"]::after { top: 50%; right: calc(100% + 5px); transform: translate(-.5em, -50%); }
Right:
[tooltip][flow^="right"]::before { top: 50%; border-left-width: 0; border-right-color: #333; right: calc(0em - 5px); transform: translate(.5em, -50%); } [tooltip][flow^="right"]::after { top: 50%; left: calc(100% + 5px); transform: translate(.5em, -50%); }
7. सभी चीजों को एनिमेट करें
एनिमेशन अद्भुत हैं. एनिमेशन ये कर सकते हैं:
- यूज़र्स को सहज महसूस करने में मदद
- अपने UI के ख़ास जागरूकता के साथ यूज़र्स की मदद
- उन चीजों पर ध्यान दें जिनको देखा जाना चाहिए
- एक UI के नरम तत्वों को जिनपर अन्यथा binary on/off का झंकार प्रभाव होगा
हमारे टूलटिप्स उस अंतिम विवरण में आते हैं। अस्तित्व (existence) में एक टेक्स्ट bubble pop होने और फ्लैश में pop आउट होने के बजाय, हम उन्हें नरम बनाते हैं।
@keyframes
हमें दो @keyframe
एनिमेशन की आवश्यकता होगी. ऊपर/नीचे (up/down) टूलटिप्स tooltips-vert
कीफ्रेम (keyframe) का उपयोग करेंगे, और बाएं/दाएं (left/right) टूलटिप्स tooltips-horz
कीफ़्रेम का उपयोग करेंगे नोटिस करें की इन दोनों कीफ्रेम में हम केवल टूलटिप्स के desired अंतिम स्थिति को परिभाषित (defining) कर रहे हैं. हमें यह जानने की जरूरत नहीं है कि वे कहां से आते हैं (टूलटिप्स स्वयं उस स्टाइल की जानकारी रखते हैं). हमे सिर्फ इस पर नियंत्रण करना हैं की वे जाते कहाँ हैं।
@keyframes tooltips-vert { to { opacity: .9; transform: translate(-50%, 0); } } @keyframes tooltips-horz { to { opacity: .9; transform: translate(0, -50%); } }
अब, हमें इन keyframes को टूलटिप्स पर लागू करने की आवश्यकता है, जब कोई यूज़र ट्रिगर करने वाले elements के ऊपर आता है (एलिमेंट जो [tooltip]
के साथ होता है)। चूंकि हम नियंत्रित करने के लिए विभिन्न flows को नियोजित कर रहे हैं, टूलटिप्स कैसे दिखाए जाएंगे, इसलिए हमें स्टाइल्स में उन संभावनाओं की पहचान करने की आवश्यकता है.
प्रयोग करें: एनिमेशन के पास नियंत्रण को देने के लिए होवर (hover) करें
[tooltip]:not([flow]):hover::before, [tooltip]:not([flow]):hover::after, [tooltip][flow^="up"]:hover::before, [tooltip][flow^="up"]:hover::after, [tooltip][flow^="down"]:hover::before, [tooltip][flow^="down"]:hover::after { animation: tooltips-vert 300ms ease-out forwards; } [tooltip][flow^="left"]:hover::before, [tooltip][flow^="left"]:hover::after, [tooltip][flow^="right"]:hover::before, [tooltip][flow^="right"]:hover::after { animation: tooltips-horz 300ms ease-out forwards; }
याद रखें कि हम display
प्रॉपर्टी को एनिमेट नहीं कर सकते हैं, लेकिन हम opacity
को जोड़कर टूलटिप्स को fade-in प्रभाव दे सकते हैं. हम ट्रांस्फ़ॉर्म प्रॉपर्टी भी एनिमेटिंग कर रहे हैं जो टूलटिप्स को थोड़ी सी गति देता है जैसे कि वे अपने ट्रिगरिंग एलिमेंट्स के पॉइंट की ओर उड़ रहे हैं।
एनीमेशन डिक्लेरेशन में forwards
कीवर्ड पर ध्यान दें. यह ऐनिमेशन को एक बार पूरा करने के बाद रीसेट नहीं करने के लिए कहता है, लेकिन आगे बढ़ने और अंत में ही रहने के लिए कहता है.
निष्कर्ष
बढ़िया काम! हमने इस ट्यूटोरियल में बहुत कुछ शामिल किया है, और अब हमारे कड़ी मेहनत के लिए दिखाने के लिए tooltips का एक साफ संग्रह (collection) है:
हमने केवल CSS टूलटिप्स के साथ क्या किया जा सकता है की सतह खरोंची है. उनके साथ मज़े करो और प्रयोग करें, और अपने खुद के recipies को बनाते रहें!