pointer-events प्रॉपर्टी का उपयोग करके विशिष्ट HTML एलिमेंट्स पर माउसओवर/होवर (:hover) इवेंट को हटाना/अनदेखा करना सीखें।
मैं हाल ही में अपने एक क्लाइंट के लिए एक टीम गैलरी पेज बनाया। प्रत्येक गैलरी आइटम एक UI कार्ड द्वारा दर्शाया गया है जो एक ओवरले का उपयोग करता है जो आपके माउस को इसके ऊपर ले जाने पर रंग बदलता है। लेकिन मुझे एक समस्या का सामना करना पड़ा, जिसने इस ट्यूटोरियल को प्रेरित किया।
UI कार्ड कंटेंट और संरचना
प्रत्येक गैलरी कार्ड आइटम में ये एलिमेंट्स होते हैं:
- कर्मचारी फोटो - ब्लैक/व्हाइट
- कर्मचारी नाम - सफेद
- कर्मचारी भूमिका - सफेद
- एक सूक्ष्म डार्क बैकग्राउंड ओवरले
जब यूज़र्स प्रत्येक कार्ड पर अपना माउस ले जाते हैं तो बैकग्राउंड ओवरले हल्के सेमी-ट्रांसपेरेंट पीले (ब्रांड कलर) में ट्रांज़िशन करता है।
UI कार्ड उदाहरण
चूंकि मैं इस ट्यूटोरियल को एक विशिष्ट समस्या को हल करने पर केंद्रित रखना चाहता हूं, यहां UI कार्ड कैसा दिखता था इसका एक सरलीकृत (डिज़ाइन-वार) संस्करण है। अपना माउस इसके ऊपर ले जाने का प्रयास करें और बैकग्राउंड कलर को हल्के पीले में ट्रांज़िशन होते देखें:
Employee Name Employee Role
लेकिन एक समस्या है। आपने शायद इसे पहले ही देख लिया है। टेक्स्ट क्षेत्र पर अपना माउस ले जाने का प्रयास करें, क्या आप समस्या देखते हैं?
जैसे ही आपका माउस टेक्स्ट एलिमेंट क्षेत्र पर जाता है, होवर इवेंट रद्द हो जाता है — और तुरंत डिफ़ॉल्ट निष्क्रिय अवस्था में वापस ग्रे रंग के साथ आ जाता है। स्वीकार्य नहीं!
यहां HTML कोड है:
<div class="card"> <div class="card-overlay"></div> <img class="card-image" src="https://in.wsxdn.com/UploadFiles_4959/202203/2022033109324298.jpg" /> <div class="card-info"> <div class="card-name">Employee Name</div> <div class="card-role">Employee Role</div> </div> </div>
और CSS:
.card { max-width: 350px; position: relative; } .card-overlay { background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5)); height: 100%; width: 100%; position: absolute; top: 0; left: 0; transition: background-color 0.6s; } .card-overlay:hover { background-color: rgba(255, 204, 7, 0.5); } .card-image { max-width: 100%; display: block; } .card-info { position: absolute; bottom: 2rem; left: 2rem; } .card-name, .card-role { color: white; font-size: 1.5rem; line-height: 1.25; padding: 0.25rem; } .card-name { font-weight: bold; }
तो जब आप टेक्स्ट क्षेत्र पर अपना माउस ले जाते हैं तो होवर इवेंट क्यों रद्द हो जाता है?
HTML के स्टैकिंग ऑर्डर के कारण। स्टैकिंग ऑर्डर आमतौर पर CSS z-index प्रॉपर्टी द्वारा नियंत्रित होता है। हालांकि, एक डिफ़ॉल्ट स्टैकिंग ऑर्डर होता है जो होता है, यदि आप इसे सीधे CSS के साथ पहले संबोधित नहीं करते हैं।
z-indexएक स्टैक ऑर्डर CSS प्रॉपर्टी है। जिस एलिमेंट काz-indexमान (संख्या) सबसे अधिक होता है, उसे अन्य एलिमेंट्स के सामने रखा जाता है — यह मानते हुए कि उनकाpositionमान समान है। सभी एलिमेंट्स का डिफ़ॉल्टz-indexमानautoहोता है, जो शून्य0के समान है।
तो चूंकि हमारे पास दो एलिमेंट्स हैं जो दोनों एब्सोल्यूट पोजिशन्ड हैं और उन दोनों का डिफ़ॉल्ट z-index auto (0) है, उनमें से कौन सा स्टैकिंग ऑर्डर में दूसरे के सामने है (एक को जीतना होगा)?
आपके HTML में जो अंत में आता है वह जीतता है।
इस मामले में, <div class="card-info"> कंटेनर जिसमें नाम और भूमिका टेक्स्ट एलिमेंट्स होते हैं, card-overlay एलिमेंट के बाद आता है:
<div class="card"> <div class="card-overlay"></div> <img class="card-image" src="https://in.wsxdn.com/UploadFiles_4959/202203/2022033109324298.jpg" /> <div class="card-info"> <div class="card-name">Employee Name</div> <div class="card-role">Employee Role</div> </div> </div>
UI कार्ड उदाहरण पर, जैसे ही आप टेक्स्ट एलिमेंट्स पर अपना माउस ले जाते हैं, आप अब ओवरले एलिमेंट पर होवर नहीं कर रहे हैं, बल्कि <class="card-info"> एलिमेंट पर, जिसमें :hover (स्यूडो क्लास) अटैच नहीं है। केवल .card के पास वह है (CSS कोड देखें)।
आप क्या कर सकते हैं?
यदि आप भौतिक रूप से <div class="card-overlay"></div> एलिमेंट को <div class="card-info>...</div> एलिमेंट के नीचे ले जाते हैं जैसे:
<div class="card"> <img class="card-image" src="https://in.wsxdn.com/UploadFiles_4959/202203/2022033109324298.jpg" /> <div class="card-info"> <div class="card-name">Employee Name</div> <div class="card-role">Employee Role</div> </div> <div class="card-overlay"></div> </div>
तब स्टैकिंग ऑर्डर स्वैप हो जाएगा, और यह होता है:
Employee Name Employee Role
बढ़िया, अब टेक्स्ट क्षेत्र पर अपना माउस ले जाने पर ओवरले ट्रांज़िशन बाधित नहीं होता (इसे आज़माएं)।
लेकिन रुकिए... अब जब स्टैकिंग ऑर्डर को घुमा दिया गया है, तो टेक्स्ट एलिमेंट्स ओवरले द्वारा ग्रे आउट हो जाते हैं, जो अब इसके सामने/ऊपर है।
हमने एक समस्या हल करते हुए दूसरी बना दी।
आइए उस दृष्टिकोण का उपयोग न करें, और <div class="card-overlay"> एलिमेंट को उसकी मूल स्थिति में वापस ले जाएं।
क्या होगा यदि हम इसके बजाय .card-overlay क्लास को z-index मान 1 देते हैं?
अब card-overlay को card-info के सामने रखा जाएगा (जिसमें अभी भी z-index: 0 है) क्योंकि इसका स्टैक ऑर्डर अधिक है (z-index: 1) और अब होवर पर कलर चेंज इवेंट फिर से निर्बाध रूप से काम करेगा — जो बहुत अच्छा है, लेकिन...
दुर्भाग्य से, ऐसा करने से वही सटीक चीज़ होगी जो पहले हुई थी जब हमने भौतिक रूप से <div class="card-overlay"> एलिमेंट को <div class="card-info"> एलिमेंट के नीचे ले जाया था। इस बार हमने केवल CSS के साथ सीधे स्टैकिंग ऑर्डर बदल दिया। टेक्स्ट एलिमेंट्स अभी भी ओवरले द्वारा ग्रे आउट हैं।
यह अस्वीकार्य है!
पॉइंटर इवेंट्स बचाव के लिए!
मुझे अचानक याद आया कि CSS में pointer-events नामक एक प्रॉपर्टी है जो आपको यह तय करने की अनुमति देती है कि कोई एलिमेंट पॉइंटर इवेंट्स पर प्रतिक्रिया देगा या नहीं।
पॉइंटर इवेंट्स वे सब कुछ हैं जो आपके माउस से संबंधित हैं, जैसे क्लिक करना, स्क्रॉल करना, या किसी एलिमेंट पर अपना माउस ले जाना (होवर)।
तो मैंने बस अपने .card-info क्लास में pointer-events: none; जोड़ दिया, जैसे:
.card-info { position: absolute; bottom: 2rem; left: 2rem; pointer-events: none; /* the fix! */ }
और अब आप टेक्स्ट सहित पूरे UI कार्ड पर होवर कर सकते हैं, बिना होवर इवेंट को रद्द किए — और टेक्स्ट एलिमेंट्स अपने 100% सफेद रंग को बरकरार रखते हैं:
Employee Name Employee Role
कोड कोडपेन देखें।