Xlera8

आपके अवतार के लिए एक फैंसी होवर प्रभाव

क्या आप उस तरह के प्रभाव के बारे में जानते हैं जहाँ किसी का सिर एक घेरे या छेद से होकर निकल रहा है? प्रसिद्ध पोर्की पिग एनीमेशन जहां वह लाल रिंगों की एक श्रृंखला से बाहर निकलते समय अलविदा कहता है, एक आदर्श उदाहरण है, और Kilian Valkhof ने वास्तव में इसे कुछ समय पहले CSS-Tricks पर फिर से बनाया था.

मेरे पास एक समान विचार है, लेकिन एक अलग तरीके से और एनीमेशन के छिड़काव के साथ। मुझे लगता है कि यह काफी व्यावहारिक है और एक स्वच्छ होवर प्रभाव बनाता है जिसका उपयोग आप अपने अवतार जैसी किसी चीज़ पर कर सकते हैं।

देखना है कि? हम एक स्केलिंग एनीमेशन बनाने जा रहे हैं जहाँ अवतार अपने घेरे से ठीक बाहर निकलता हुआ प्रतीत होता है। ठीक है, है ना? कोड को न देखें और आइए इस एनीमेशन को एक साथ चरण-दर-चरण बनाएं।

HTML: बस एक तत्व

यदि आपने डेमो के कोड की जांच नहीं की है और आप सोच रहे हैं कि कितने divs यह लेगा, फिर वहीं रुक जाएगा, क्योंकि हमारा मार्कअप एक छवि तत्व के अलावा और कुछ नहीं है:

<img src="" alt="">

हाँ, एक तत्व! इस अभ्यास का चुनौतीपूर्ण हिस्सा कोड की सबसे छोटी मात्रा का उपयोग कर रहा है। अगर आप हो चुके हैं मेरा पीछा कुछ समय के लिए, आपको इसकी आदत डाल लेनी चाहिए। मैं सीएसएस समाधान खोजने के लिए कड़ी मेहनत करता हूं जिसे सबसे छोटे, सबसे रखरखाव योग्य कोड के साथ हासिल किया जा सकता है।

मैंने लिखा था लेखों की एक श्रृंखला यहाँ CSS-ट्रिक्स पर जहाँ मैं एक ही तत्व वाले समान HTML मार्कअप का उपयोग करके विभिन्न होवर प्रभावों का पता लगाता हूँ। मैं ग्रेडिएंट्स, मास्किंग, क्लिपिंग, आउटलाइन और यहां तक ​​कि लेआउट तकनीकों के बारे में विस्तार से बताता हूं। मैं उन्हें जांचने की अत्यधिक अनुशंसा करता हूं क्योंकि मैं इस पोस्ट में कई ट्रिक्स का पुन: उपयोग करूंगा।

हम जो कर रहे हैं उसके लिए एक पारदर्शी पृष्ठभूमि वाली वर्गाकार छवि फ़ाइल सबसे अच्छा काम करेगी। यदि आप इसके साथ शुरू करना चाहते हैं तो मैं यहां उपयोग कर रहा हूं।

द्वारा डिज़ाइन किया गया कांगो

मैं वास्तविक छवियों का उपयोग करके इसके बहुत सारे उदाहरण देखने की उम्मीद कर रहा हूं - इसलिए जब आप कर लें तो कृपया अपना अंतिम परिणाम टिप्पणियों में साझा करें ताकि हम एक संग्रह बना सकें!

CSS में कूदने से पहले, आइए पहले प्रभाव का विश्लेषण करें। छवि होवर पर बड़ी हो जाती है, इसलिए हम निश्चित रूप से उपयोग करेंगे transform: scale() वहाँ पर। अवतार के पीछे एक वृत्त है, और एक रेडियल ग्रेडिएंट को चाल चलनी चाहिए। अंत में, हमें सर्कल के नीचे एक बॉर्डर बनाने का एक तरीका चाहिए जो सर्कल के पीछे अवतार की उपस्थिति बनाता है।

चलो काम पर लगें!

पैमाने का प्रभाव

आइए परिवर्तन जोड़कर शुरू करें:

img { width: 280px; aspect-ratio: 1; cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

अभी तक कुछ भी जटिल नहीं है, है ना? पर चलते हैं।

वृत्त

हमने कहा कि पृष्ठभूमि एक रेडियल ढाल होगी। यह बिल्कुल सही है क्योंकि हम रेडियल ग्रेडिएंट के रंगों के बीच सख्त स्टॉप बना सकते हैं, जिससे ऐसा लगता है कि हम ठोस रेखाओं के साथ एक वृत्त बना रहे हैं।

img { --b: 5px; /* border width */ width: 280px; aspect-ratio: 1; background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, #0000 ); cursor: pointer; transition: .5s;
}
img:hover { transform: scale(1.35);
}

CSS चर पर ध्यान दें, --b, मैं वहाँ उपयोग कर रहा हूँ। यह "सीमा" की मोटाई का प्रतिनिधित्व करता है जो वास्तव में रेडियल ग्रेडिएंट के लाल भाग के लिए कठोर रंग स्टॉप को परिभाषित करने के लिए उपयोग किया जा रहा है।

अगला कदम होवर पर ढाल आकार के साथ खेलना है। जैसे-जैसे छवि बढ़ती है, वृत्त को अपना आकार बनाए रखने की आवश्यकता होती है। चूंकि हम आवेदन कर रहे हैं scale() परिवर्तन, हमें वास्तव में चाहिए कमी वृत्त का आकार क्योंकि यह अन्यथा अवतार के साथ बढ़ता है। इसलिए, जबकि इमेज का आकार बढ़ता है, हमें स्केल डाउन करने के लिए ग्रेडिएंट की आवश्यकता होती है।

आइए एक CSS वेरिएबल को परिभाषित करके शुरू करें, --f, जो "स्केल फ़ैक्टर" को परिभाषित करता है, और सर्कल के आकार को सेट करने के लिए इसका उपयोग करता है। मैं उपयोग कर रहा हूं 1 डिफ़ॉल्ट मान के रूप में, जैसा कि छवि के लिए प्रारंभिक पैमाना है और जिस वृत्त से हम रूपांतरित होते हैं।

चाल का वर्णन करने के लिए यहां एक डेमो है। पर्दे के पीछे क्या हो रहा है यह देखने के लिए होवर करें:

मैंने इसमें तीसरा रंग जोड़ा radial-gradient होवर पर ग्रेडिएंट के क्षेत्र की बेहतर पहचान करने के लिए:

radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), #C02942 calc(100% - var(--b)) 99%, lightblue
);

अब हमें अपनी पृष्ठभूमि को वृत्त के केंद्र में रखना है और यह सुनिश्चित करना है कि यह पूरी ऊंचाई ले ले। मैं सीधे सब कुछ घोषित करना पसंद करता हूं background आशुलिपि संपत्ति, इसलिए हम अपनी पृष्ठभूमि की स्थिति जोड़ सकते हैं और यह सुनिश्चित कर सकते हैं कि यह उन मूल्यों पर हमला करके दोहराता नहीं है radial-gradient():

background: radial-gradient() 50% / calc(100% / var(--f)) 100% no-repeat;

पृष्ठभूमि को केंद्र में रखा गया है (50%), के बराबर चौड़ाई है calc(100%/var(--f)), और ऊंचाई के बराबर है 100%.

जब कुछ भी नहीं होता है --f के बराबर है 1 - फिर से, हमारा प्रारंभिक पैमाना। इस बीच, ग्रेडिएंट कंटेनर की पूरी चौड़ाई घेर लेता है। जब हम बढ़ते हैं --f, तत्व का आकार बढ़ता है - धन्यवाद scale() बदलना - और ग्रेडिएंट का आकार घट जाता है।

जब हम यह सब अपने डेमो में लागू करते हैं तो हमें यह मिलता है:

हम करीब आ रहे हैं! हमारे पास शीर्ष पर अतिप्रवाह प्रभाव है, लेकिन हमें अभी भी छवि के निचले हिस्से को छिपाने की जरूरत है, इसलिए ऐसा लगता है कि यह सर्कल के सामने बैठने के बजाय बाहर निकल रहा है। यह इस पूरे मामले का पेचीदा हिस्सा है और हम आगे यही करने जा रहे हैं।

निचली सीमा

मैंने पहली बार इससे निपटने की कोशिश की border-bottom संपत्ति, लेकिन मुझे सीमा के आकार को सर्कल के आकार से मिलान करने का कोई तरीका नहीं मिला। यहाँ सबसे अच्छा है जो मुझे मिल सकता है और आप तुरंत देख सकते हैं कि यह गलत है:

वास्तविक समाधान का उपयोग करना है outline संपत्ति। हाँ, outline, नहीं border. में पिछले लेख, मैं दिखाता हूँ कैसे outline शक्तिशाली है और हमें शांत होवर प्रभाव बनाने की अनुमति देता है। के साथ संयुक्त outline-offset, हमारे पास वही है जो हमें अपने प्रभाव के लिए चाहिए।

विचार एक सेट करना है outline नीचे की सीमा बनाने के लिए छवि पर और इसके ऑफ़सेट को समायोजित करें। ऑफ़सेट स्केलिंग फ़ैक्टर पर उसी तरह निर्भर करेगा जिस तरह से ग्रेडिएंट साइज़ ने किया था।

अब हमारे पास अपनी निचली "सीमा" है (वास्तव में एक outline) एक पूर्ण चक्र बनाने के लिए ढाल द्वारा बनाई गई "सीमा" के साथ संयुक्त। हमें अभी भी इसके कुछ हिस्सों को छिपाने की जरूरत है outline (ऊपर और किनारे से), जिस पर हम एक पल में पहुंचेंगे।

यहाँ हमारा अब तक का कोड है, जिसमें कुछ और CSS वेरिएबल्स शामिल हैं जिनका उपयोग आप छवि आकार को कॉन्फ़िगर करने के लिए कर सकते हैं (--s) और "बॉर्डर" रंग (--c):

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50% / calc(100% / var(--f)) 100% no-repeat; transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

चूँकि हमें एक वृत्ताकार निचली सीमा की आवश्यकता है, हमने a जोड़ा border-radius नीचे की तरफ, अनुमति देता है outline ढाल की वक्रता से मिलान करने के लिए।

गणना पर प्रयोग किया जाता है outline-offset जितना दिखता है उससे कहीं ज्यादा सीधा है। डिफ़ॉल्ट रूप से, outline मुरझाया है बाहर तत्व के बॉक्स का। और हमारे मामले में, हमें इसकी आवश्यकता है ओवरलैप तत्व। अधिक सटीक रूप से, हमें इसकी आवश्यकता है कि ग्रेडिएंट द्वारा बनाए गए सर्कल का पालन करें।

पृष्ठभूमि संक्रमण का आरेख।

जब हम तत्व को स्केल करते हैं, तो हम सर्कल और किनारे के बीच की जगह देखते हैं। आइए यह न भूलें कि विचार यह है कि स्केल ट्रांसफ़ॉर्मेशन के चलने के बाद सर्कल को उसी आकार में रखा जाए, जो हमें उस स्थान के साथ छोड़ देता है जिसका उपयोग हम उपरोक्त आकृति में सचित्र रूपरेखा के ऑफ़सेट को परिभाषित करने के लिए करेंगे।

आइए यह न भूलें कि दूसरा तत्व स्केल किया गया है, इसलिए हमारा परिणाम भी स्केल किया गया है ... जिसका अर्थ है कि हमें परिणाम को विभाजित करने की आवश्यकता है f वास्तविक ऑफ़सेट मान प्राप्त करने के लिए:

Offset = ((f - 1) * S/2) / f = (1 - 1/f) * S/2

हम एक नकारात्मक चिह्न जोड़ते हैं क्योंकि हमें बाहर से अंदर जाने के लिए रूपरेखा की आवश्यकता होती है:

Offset = (1/f - 1) * S/2

यहाँ एक त्वरित डेमो है जो दिखाता है कि कैसे रूपरेखा ग्रेडिएंट का अनुसरण करती है:

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

outline-offset: calc((1 / var(--f) - 1) * var(--s) / 2) - var(--b));

अब हमें यह पता लगाने की जरूरत है कि आउटलाइन से शीर्ष भाग को कैसे हटाया जाए। दूसरे शब्दों में, हम केवल छवि का निचला भाग चाहते हैं outline.

सबसे पहले, शीर्ष पर ओवरलैप से बचने में सहायता के लिए पैडिंग के साथ शीर्ष पर स्थान जोड़ें:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ width: var(--s); aspect-ratio: 1; padding-block-start: calc(var(--s)/5); /* etc. */
}
img:hover { --f: 1.35; /* hover scale */
}

उस शीर्ष गद्दी के लिए कोई विशेष तर्क नहीं है। विचार यह सुनिश्चित करना है कि रूपरेखा अवतार के सिर को न छुए। मैंने उस स्थान को हमेशा समान अनुपात में परिभाषित करने के लिए तत्व के आकार का उपयोग किया।

ध्यान दें कि मैंने जोड़ा है content-box के लिए मूल्य background:

background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000 ) 50%/calc(100%/var(--f)) 100% no-repeat content-box;

हमें इसकी आवश्यकता है क्योंकि हमने पैडिंग जोड़ी है और हम केवल पृष्ठभूमि को सामग्री बॉक्स पर सेट करना चाहते हैं, इसलिए हमें स्पष्ट रूप से पृष्ठभूमि को वहीं रुकने के लिए कहना चाहिए।

मिश्रण में CSS मास्क जोड़ना

हम अंतिम भाग में पहुँचे! हमें बस इतना करना है कि कुछ टुकड़ों को छुपाना है, और हम कर चुके हैं। इसके लिए हम पर भरोसा करेंगे mask संपत्ति और, ज़ाहिर है, ग्रेडियेंट।

यहां एक आंकड़ा है जो बताता है कि हमें क्या छिपाने की जरूरत है या अधिक सटीक होने के लिए हमें क्या दिखाना है

दिखा रहा है कि कैसे मास्क सर्कल के निचले हिस्से पर लागू होता है।

बाईं छवि वह है जो हमारे पास वर्तमान में है, और दाईं ओर वह है जो हम चाहते हैं। हरा भाग उस मास्क को दिखाता है जिसे हमें अंतिम परिणाम प्राप्त करने के लिए मूल छवि पर लागू करना चाहिए।

हम अपने मुखौटे के दो भागों की पहचान कर सकते हैं:

  • तल पर एक गोलाकार भाग जिसका आयाम और वक्रता रेडियल ग्रेडिएंट के समान है जिसका उपयोग हमने अवतार के पीछे वृत्त बनाने के लिए किया था
  • शीर्ष पर एक आयत जो आउटलाइन के अंदर के क्षेत्र को कवर करता है। ध्यान दें कि रूपरेखा शीर्ष पर हरे क्षेत्र के बाहर कैसे है - यह सबसे महत्वपूर्ण हिस्सा है, क्योंकि यह रूपरेखा को काटने की अनुमति देता है ताकि केवल नीचे का भाग दिखाई दे।

यहाँ हमारा अंतिम CSS है:

img { --s: 280px; /* image size */ --b: 5px; /* border thickness */ --c: #C02942; /* border color */ --f: 1; /* initial scale */ --_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; --_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b)); width: var(--s); aspect-ratio: 1; padding-top: calc(var(--s)/5); cursor: pointer; border-radius: 0 0 999px 999px; outline: var(--b) solid var(--c); outline-offset: var(--_o); background: radial-gradient( circle closest-side, #ECD078 calc(99% - var(--b)), var(--c) calc(100% - var(--b)) 99%, #0000) var(--_g); mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g); transform: scale(var(--f)); transition: .5s;
}
img:hover { --f: 1.35; /* hover scale */
}

आइए इसे तोड़ दें mask संपत्ति। शुरुआत के लिए, ध्यान दें कि एक समान radial-gradient() से background संपत्ति वहाँ है। मैंने एक नया चर बनाया, --_g, सामान्य भागों के लिए चीजों को कम अव्यवस्थित बनाने के लिए।

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

अगला, वहाँ एक है linear-gradient() वहाँ भी:

--_g: 50% / calc(100% / var(--f)) 100% no-repeat content-box; mask: linear-gradient(#000 0 0) no-repeat 50% calc(-1 * var(--_o)) / calc(100% / var(--f) - 2 * var(--b)) 50%, radial-gradient( circle closest-side, #000 99%, #0000) var(--_g);

यह मुखौटा का आयत भाग बनाता है। इसकी चौड़ाई रेडियल ग्रेडिएंट की चौड़ाई माइनस दो बार बॉर्डर मोटाई के बराबर है:

calc(100% / var(--f) - 2 * var(--b))

आयत की ऊंचाई आधी के बराबर है, 50%, तत्व के आकार का।

हमें क्षैतिज केंद्र पर स्थित रैखिक ढाल की भी आवश्यकता है (50%) और ऊपर से उसी मान से ऑफ़सेट करें जो आउटलाइन ऑफ़सेट है। मैंने एक और CSS चर बनाया, --_o, ऑफ़सेट के लिए हमने पहले परिभाषित किया था:

--_o: calc((1 / var(--f) - 1) * var(--s) / 2 - var(--b));

यहां भ्रमित करने वाली चीजों में से एक यह है कि हमें एक की जरूरत है नकारात्मक आउटलाइन के लिए ऑफ़सेट (इसे बाहर से अंदर की ओर ले जाने के लिए) लेकिन a सकारात्मक ढाल के लिए ऑफ़सेट (ऊपर से नीचे जाने के लिए)। तो, अगर आप सोच रहे हैं कि हम ऑफ़सेट को क्यों गुणा करते हैं, --_o, द्वारा -1अच्छा, अब आप जानते हैं!

मास्क के ग्रेडिएंट कॉन्फ़िगरेशन को दर्शाने के लिए यहां एक डेमो दिया गया है:

ऊपर होवर करें और देखें कि कैसे सब कुछ एक साथ चलता है। मध्य बॉक्स दो ग्रेडियेंट से बना मुखौटा परत दिखाता है। इसे बाईं छवि के दृश्य भाग के रूप में कल्पना करें, और आपको अंतिम परिणाम दाईं ओर मिलता है!

ऊपर लपेटकर

उफ़, हमारा काम हो गया! और न केवल हम एक चालाक होवर एनीमेशन के साथ समाप्त हुए, बल्कि हमने यह सब एक HTML के साथ किया <img> तत्व। बस इतना ही और CSS प्रवंचना की 20 से कम पंक्तियाँ!

ज़रूर, हम इस तरह के जटिल प्रभाव तक पहुँचने के लिए कुछ छोटी-छोटी ट्रिक्स और गणित के फॉर्मूले पर निर्भर थे। लेकिन हमें पता था कि वास्तव में क्या करना है क्योंकि हमने उन टुकड़ों की पहचान कर ली है जिनकी हमें आवश्यकता थी।

यदि हम स्वयं को अधिक HTML की अनुमति देते हैं तो क्या हम CSS को सरल बना सकते हैं? बिल्कुल। लेकिन हम यहां नई CSS तरकीबें सीखने के लिए हैं! CSS ग्रेडिएंट्स, मास्किंग, the outline संपत्ति का व्यवहार, रूपांतरण, और बहुत कुछ। यदि आप किसी भी समय खोया हुआ महसूस करते हैं, तो निश्चित रूप से देखें मेरी श्रृंखला जो समान सामान्य अवधारणाओं का उपयोग करता है। यह कभी-कभी अधिक उदाहरण देखने और एक बिंदु घर चलाने के लिए मामलों का उपयोग करने में मदद करता है।

मैं आपको एक आखिरी डेमो के साथ छोड़ दूंगा जो लोकप्रिय सीएसएस डेवलपर्स की तस्वीरों का उपयोग करता है। मुझे अपनी छवि के साथ एक डेमो दिखाना न भूलें ताकि मैं इसे संग्रह में जोड़ सकूं!

हमारे साथ चैट करें

नमस्ते! मैं आपकी कैसे मदद कर सकता हूँ?