रिस्पॉन्सिव स्लाइड आउट साइडनेव बनाने के तरीके के बारे में बुनियादी जानकारी
इस पोस्ट में, मैं आपको बताना चाहता हूं कि मैंने वेब के लिए, साइडनेव कॉम्पोनेंट का प्रोटोटाइप कैसे बनाया. यह कॉम्पोनेंट रिस्पॉन्सिव है, इसमें स्टेटस सेव होता है, यह कीबोर्ड नेविगेशन के साथ काम करता है, JavaScript के साथ और बिना JavaScript के काम करता है, और सभी ब्राउज़र पर काम करता है. डेमो आज़माएं.
अगर आपको वीडियो देखना पसंद है, तो यहां इस पोस्ट का YouTube वर्शन दिया गया है:
खास जानकारी
रिस्पॉन्सिव नेविगेशन सिस्टम बनाना मुश्किल होता है. कुछ उपयोगकर्ता कीबोर्ड का इस्तेमाल करेंगे, कुछ के पास बेहतरीन डेस्कटॉप होंगे, और कुछ छोटे मोबाइल डिवाइस से विज़िट करेंगे. वेबसाइट पर आने वाला हर व्यक्ति, मेन्यू को खोल और बंद कर सकता है.
वेब रणनीतियां
इस कॉम्पोनेंट एक्सप्लोरेशन में, मुझे वेब प्लैटफ़ॉर्म की कुछ अहम सुविधाओं को जोड़ने का मौका मिला:
- सीएसएस
:target
- सीएसएस ग्रिड
- सीएसएस ट्रांसफ़ॉर्म
- व्यूपोर्ट और उपयोगकर्ता की प्राथमिकता के लिए सीएसएस मीडिया क्वेरी
focus
यूएक्स को बेहतर बनाने के लिए JS
मेरे समाधान में एक साइडबार है और यह सिर्फ़ तब टॉगल होता है, जब "मोबाइल" व्यूपोर्ट 540px
या उससे कम हो.
540px
, मोबाइल इंटरैक्टिव लेआउट और स्टैटिक डेस्कटॉप लेआउट के बीच स्विच करने के लिए ब्रेकपॉइंट होगा.
सीएसएस :target
सूडो-क्लास
एक <a>
लिंक, यूआरएल हैश को #sidenav-open
पर सेट करता है और दूसरा लिंक उसे खाली (''
) पर सेट करता है. आखिर में, हैश से मैच करने के लिए एलिमेंट में id
होता है:
<a href="#sidenav-open" id="sidenav-button" title="Open Menu" aria-label="Open Menu">
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>
<aside id="sidenav-open">
…
</aside>
इनमें से किसी भी लिंक पर क्लिक करने से, हमारे पेज के यूआरएल का हैश स्टेटस बदल जाता है. इसके बाद, मैं एक स्यूडो-क्लास की मदद से साइडनेव को दिखाता और छिपा देता हूं:
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
}
#sidenav-open:target {
visibility: visible;
}
}
सीएसएस ग्रिड
पहले, मैंने सिर्फ़ एब्सोलूट या फ़िक्स की गई पोज़िशन वाले साइडनेव लेआउट और कॉम्पोनेंट का इस्तेमाल किया था. हालांकि, ग्रिड के grid-area
सिंटैक्स की मदद से, एक ही पंक्ति या कॉलम में कई एलिमेंट असाइन किए जा सकते हैं.
स्टैक
प्राइमरी लेआउट एलिमेंट #sidenav-container
एक ग्रिड होता है, जो एक लाइन और दो कॉलम बनाता है. इनमें से हर एक का नाम stack
होता है. जब जगह की कमी होती है, तो CSS <main>
एलिमेंट के सभी चाइल्ड को एक ही ग्रिड के नाम पर असाइन करती है. साथ ही, सभी एलिमेंट को एक ही जगह पर रखकर स्टैक बनाती है.
#sidenav-container {
display: grid;
grid: [stack] 1fr / min-content [stack] 1fr;
min-height: 100vh;
}
@media (max-width: 540px) {
#sidenav-container > * {
grid-area: stack;
}
}
मेन्यू का बैकग्राउंड
<aside>
, ऐनिमेशन वाला एलिमेंट है, जिसमें साइड नेविगेशन शामिल होता है. इसमें दो चाइल्ड टैग हैं: [nav]
नाम का नेविगेशन कंटेनर <nav>
और [escape]
नाम का बैकड्रॉप <a>
, जिसका इस्तेमाल मेन्यू को बंद करने के लिए किया जाता है.
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
मेन्यू ओवरले और उसके नेगेटिव स्पेस वाले 'बंद करें' बटन के लिए, अपनी पसंद का अनुपात ढूंढने के लिए 2fr
और 1fr
को अडजस्ट करें.
सीएसएस 3D ट्रांसफ़ॉर्म और ट्रांज़िशन
हमारा लेआउट अब मोबाइल व्यूपोर्ट के साइज़ में स्टैक किया गया है. जब तक मैं कुछ नई स्टाइल नहीं जोड़ता, तब तक यह डिफ़ॉल्ट रूप से हमारे लेख को ओवरले कर रहा है. यहां अगले सेक्शन में इस्तेमाल किए जाने वाले यूज़र एक्सपीरियंस के बारे में बताया गया है:
- ऐनिमेशन के साथ खोलना और बंद करना
- सिर्फ़ तब ऐनिमेशन दिखाएं, जब उपयोगकर्ता को इसकी अनुमति हो
visibility
को ऐनिमेट करें, ताकि कीबोर्ड फ़ोकस, ऑफ़स्क्रीन एलिमेंट में न जाए
मोशन ऐनिमेशन लागू करने के दौरान, मैं सुलभता को सबसे ज़्यादा अहमियत देना चाहता/चाहती हूं.
ऐक्सेस करने लायक मोशन
ऐसा ज़रूरी नहीं है कि सभी को स्लाइड आउट मोशन का अनुभव चाहिए हो. हमारे समाधान में, मीडिया क्वेरी में --duration
सीएसएस वैरिएबल में बदलाव करके, यह प्राथमिकता लागू की जाती है. यह मीडिया क्वेरी वैल्यू, उपयोगकर्ता के ऑपरेटिंग सिस्टम की मोशन (अगर उपलब्ध हो) की प्राथमिकता दिखाती है.
#sidenav-open {
--duration: .6s;
}
@media (prefers-reduced-motion: reduce) {
#sidenav-open {
--duration: 1ms;
}
}
अब जब हमारा साइडनेव स्लाइड करके खुलता और बंद होता है, तो अगर कोई उपयोगकर्ता कम मोशन चाहता है, तो हम एलिमेंट को तुरंत व्यू में ले जाते हैं. ऐसा करने पर, मोशन के बिना एलिमेंट की स्थिति बनी रहती है.
ट्रांज़िशन, ट्रांसफ़ॉर्म, अनुवाद
साइडनेव आउट (डिफ़ॉल्ट)
मोबाइल पर साइडनेव की डिफ़ॉल्ट स्थिति को ऑफ़स्क्रीन पर सेट करने के लिए,
मैं एलिमेंट को transform: translateX(-110vw)
के साथ पोज़िशन करता/करती हूं.
ध्यान दें, मैंने -100vw
के सामान्य ऑफ़स्क्रीन कोड में एक और 10vw
जोड़ा है, ताकि यह पक्का किया जा सके कि साइडनेव के box-shadow
को छिपाने पर, वह मुख्य व्यूपोर्ट में न दिखे.
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
transform: translateX(-110vw);
will-change: transform;
transition:
transform var(--duration) var(--easeOutExpo),
visibility 0s linear var(--duration);
}
}
साइडनेविगेशन में
जब #sidenav
एलिमेंट, :target
के तौर पर मैच होता है, तो translateX()
पोज़िशन को होमबेस 0
पर सेट करें. साथ ही, देखें कि यूआरएल हैश बदलने पर, सीएसएस एलिमेंट को -110vw
की आउट पोज़िशन से, var(--duration)
की "इन" पोज़िशन पर 0
तक स्लाइड करती है.
@media (max-width: 540px) {
#sidenav-open:target {
visibility: visible;
transform: translateX(0);
transition:
transform var(--duration) var(--easeOutExpo);
}
}
ट्रांज़िशन दिखने की सेटिंग
अब हमारा मकसद, स्क्रीन रीडर से मेन्यू को छिपाना है, ताकि सिस्टम किसी ऑफ़स्क्रीन मेन्यू पर फ़ोकस न कर सकें. ऐसा करने के लिए, :target
के बदलने पर, दिखने की स्थिति में बदलाव करने का ट्रांज़िशन सेट किया जाता है.
- अंदर जाते समय, दिखने की स्थिति में बदलाव न करें. तुरंत दिखें, ताकि मैं एलिमेंट को स्लाइड में देख सकूं और फ़ोकस स्वीकार कर सकूं.
- आइटम हटाते समय, उसके दिखने की सेटिंग में बदलाव करें. हालांकि, ऐसा करने में थोड़ी देरी करें, ताकि आइटम हटाने के बाद, उसकी सेटिंग
hidden
पर स्विच हो जाए.
सुलभता से जुड़े यूज़र एक्सपीरियंस को बेहतर बनाना
लिंक
इस तरीके में, स्थिति को मैनेज करने के लिए यूआरएल बदला जाता है.
स्वाभाविक रूप से, यहां <a>
एलिमेंट का इस्तेमाल किया जाना चाहिए. साथ ही, इसमें सुलभता से जुड़ी कुछ बेहतरीन सुविधाएं बिना किसी शुल्क के मिलती हैं. चलिए, अपने इंटरैक्टिव एलिमेंट को ऐसे लेबल से सजाते हैं जो साफ़ तौर पर उनके मकसद के बारे में बताते हों.
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">
<svg>...</svg>
</a>
अब हमारे मुख्य इंटरैक्शन बटन, माउस और कीबोर्ड, दोनों के लिए साफ़ तौर पर अपने इंटेंट के बारे में बताते हैं.
:is(:hover, :focus)
सीएसएस फ़ंक्शनल स्यूडो-सिलेक्टर की मदद से, हम फ़ोकस के साथ-साथ कर्सर घुमाने पर दिखने वाली स्टाइल को भी आसानी से शामिल कर सकते हैं.
.hamburger:is(:hover, :focus) svg > line {
stroke: hsl(var(--brandHSL));
}
Sprinkle on JavaScript
बंद करने के लिए escape
दबाएं
क्या आपके कीबोर्ड पर Escape
बटन से मेन्यू बंद हो जाता है? चलिए, इसे वायर से जोड़ते हैं.
const sidenav = document.querySelector('#sidenav-open');
sidenav.addEventListener('keyup', event => {
if (event.code === 'Escape') document.location.hash = '';
});
ब्राउज़र इतिहास
ब्राउज़र के इतिहास में, खोलने और बंद करने के इंटरैक्शन से कई एंट्री स्टैक होने से रोकने के लिए, बंद करें बटन में यह JavaScript इनलाइन जोड़ें:
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu" onchange="history.go(-1)"></a>
ऐसा करने पर, मेन्यू बंद होने पर यूआरएल के इतिहास की एंट्री हट जाएगी. इससे ऐसा लगेगा कि मेन्यू कभी भी नहीं खोला गया था.
Focus UX
अगले स्निपेट से, हमें यह पता चलता है कि स्क्रीन खुलने या बंद होने के बाद, खोलने और बंद करने वाले बटन पर फ़ोकस कैसे किया जाता है. मुझे टॉगल करने की सुविधा को आसान बनाना है.
sidenav.addEventListener('transitionend', e => {
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? document.querySelector('#sidenav-close').focus()
: document.querySelector('#sidenav-button').focus();
})
साइडनेवि खोलने पर, बंद करने के बटन पर फ़ोकस करें. साइडनेव बंद होने पर,
'खोलें' बटन पर फ़ोकस करें. मैं ऐसा JavaScript में एलिमेंट पर focus()
कॉल करके करता/करती हूं.
नतीजा
अब आपको पता है कि मैंने इसे कैसे किया, तो आप इसे कैसे करेंगे?! इससे कॉम्पोनेंट का आर्किटेक्चर मज़ेदार बन जाता है! स्लॉट वाला पहला वर्शन कौन बनाएगा? 🙂
आइए, अलग-अलग तरीकों का इस्तेमाल करके, वेब पर कॉन्टेंट बनाने के सभी तरीके जानें. गड़बड़ी वाली इमेज बनाएं और मुझे ट्वीट करें. हम इसे यहां दिए गए कम्यूनिटी रीमिक्स सेक्शन में जोड़ देंगे.
कम्यूनिटी रीमिक्स
- कस्टम एलिमेंट के साथ @_developit: डेमो और कोड
- एचटीएमएल/सीएसएस/जेएस के साथ @mayeedwin1: डेमो और कोड
- @a_nurella ने गड़बड़ी वाले वीडियो को रीमिक्स किया है: डेमो और कोड
- एचटीएमएल/सीएसएस/जेएस के साथ @EvroMalarkey: डेमो और कोड