रिस्पॉन्सिव स्लाइड बनाने के तरीके के बारे में खास जानकारी
मैं आपको इस पोस्ट में बताना चाहती हूँ कि मैंने वेब के लिए Sidenav कॉम्पोनेंट को कैसे प्रोटोटाइप किया था रिस्पॉन्सिव है, स्टेटफ़ुल है, कीबोर्ड नेविगेशन के साथ काम करता है, JavaScript के साथ और उसके बिना काम करता है, और सभी ब्राउज़र पर काम करता है. डेमो आज़माएं.
अगर आपको वीडियो देखना है, तो इस पोस्ट का YouTube वर्शन यहां देखें:
खास जानकारी
रिस्पॉन्सिव नेविगेशन सिस्टम बनाना मुश्किल है. कुछ उपयोगकर्ताओं को कीबोर्ड से, कुछ के पास शक्तिशाली डेस्कटॉप होंगे और कुछ का इस्तेमाल किसी छोटे मोबाइल डिवाइस से होगा. वेबसाइट पर आने वाले सभी लोग मेन्यू को खोल और बंद कर सकेंगे.
वेब रणनीति
इस कॉम्पोनेंट एक्सप्लोरेशन में, मुझे वेब प्लैटफ़ॉर्म की कुछ ज़रूरी सुविधाओं को एक साथ इस्तेमाल करने में खुशी हो रही है:
- सीएसएस
:target
- सीएसएस ग्रिड
- सीएसएस के बदलाव
- व्यूपोर्ट और उपयोगकर्ता की पसंद के लिए सीएसएस मीडिया क्वेरी
focus
के लिए JS UX को बेहतर बनाने की सुविधा
मेरे समाधान में एक साइडबार है और सिर्फ़ "मोबाइल" पर टॉगल होता है 540px
या इससे कम का व्यूपोर्ट.
मोबाइल इंटरैक्टिव लेआउट और स्टैटिक डेस्कटॉप लेआउट के बीच स्विच करने के लिए, 540px
हमारा ब्रेकपॉइंट होगा.
सीएसएस :target
pseudo-class
एक <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>
इनमें से हर लिंक पर क्लिक करने से, पेज के यूआरएल की हैश स्थिति बदल जाती है, फिर एक pseudo-class के साथ मैं साइडनेव दिखाता और छिपाता हूं:
@media (max-width: 540px) {
#sidenav-open {
visibility: hidden;
}
#sidenav-open:target {
visibility: visible;
}
}
सीएसएस ग्रिड
पहले, मैं सिर्फ़ ऐब्सलूट या तय पोज़िशन का इस्तेमाल करता था
साइडनेव लेआउट और कॉम्पोनेंट. हालांकि, अपने grid-area
सिंटैक्स के साथ ग्रिड
एक ही पंक्ति या कॉलम के लिए एक से ज़्यादा एलिमेंट असाइन करें.
स्टैक
प्राइमरी लेआउट एलिमेंट #sidenav-container
एक ग्रिड है, जो एक पंक्ति और दो कॉलम बनाता है.
हर एक का नाम stack
है. जगह की कमी होने पर, सीएसएस, <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>
ऐनिमेशन वाला ऐसा एलिमेंट है जिसमें साइड नेविगेशन मौजूद होता है. इसमें हैं
2 बच्चे: नेविगेशन कंटेनर <nav>
का नाम [nav]
है और बैकड्रॉप <a>
है
इसका इस्तेमाल मेन्यू बंद करने के लिए किया जाता है. इसका इस्तेमाल [escape]
किया जाता है.
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
2fr
और को अडजस्ट करें मेन्यू ओवरले और इसके नेगेटिव स्पेस को बंद करने वाले बटन के लिए पसंदीदा अनुपात का पता लगाने के लिए, 1fr
.
CSS 3D में पूरी तरह बदलाव करना और ट्रांज़िशन
हमारा लेआउट अब मोबाइल व्यूपोर्ट साइज़ के हिसाब से स्टैक किया गया है. जब तक मैं कुछ नई स्टाइल न जोड़ लूं, वह डिफ़ॉल्ट रूप से हमारे लेख को ओवरले कर रहा हो. अगले सेक्शन में, यहां कुछ UX के बारे में बताया गया है, जिसकी जानकारी मुझे चाहिए:
- खुला और बंद ऐनिमेट करें
- मोशन के साथ ऐनिमेशन को सिर्फ़ तब ही ऐनिमेट करें, जब उपयोगकर्ता इससे सहमत हो
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
पर फ़्लिप हो जाएगा.
सुलभता के लिए UX को बेहतर बनाया गया
लिंक
इस समाधान के लिए, यूआरएल में बदलाव किया जाता है, ताकि राज्य को मैनेज किया जा सके.
स्वाभाविक रूप से, यहां <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)
सीएसएस का इस्तेमाल करने वाले pseudo-selector से, हम तेज़ी से समाज में बदलाव कर सकते हैं फ़ोकस के साथ शेयर करके उन्हें हमारी होवर स्टाइल के साथ शेयर करें.
.hamburger:is(:hover, :focus) svg > line {
stroke: hsl(var(--brandHSL));
}
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>
ऐसा करने से यूआरएल इतिहास की एंट्री बंद हो जाएगी, जिससे यह ऐसा हो जाएगा जैसे कि मेन्यू कभी खोला नहीं.
उपयोगकर्ता अनुभव पर फ़ोकस करें
अगला स्निपेट इस बात पर फ़ोकस करने में हमारी सहायता करता है कि वह तो वे खुलते या बंद होते हैं. मैं टॉगल करना आसान बनाना चाहता हूँ.
sidenav.addEventListener('transitionend', e => {
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? document.querySelector('#sidenav-close').focus()
: document.querySelector('#sidenav-button').focus();
})
साइडनेव खुलने पर, 'बंद करें' बटन पर फ़ोकस करें. जब साइडनेव बंद हो जाता है,
'खोलें' बटन पर फ़ोकस करते हैं. मैं JavaScript में एलिमेंट पर focus()
को कॉल करके ऐसा करता/करती हूं.
नतीजा
अब जब आपको पता है कि मैंने इसे कैसे किया, तो कैसे करेंगे?! यह कुछ मज़ेदार कॉम्पोनेंट आर्किटेक्चर बनाता है! स्लॉट के साथ पहला वर्शन कौन बनाएगा? 🙂
चलिए, अलग-अलग तरह के वेब पर काम करने के सभी तरीक़े सीख रहे हैं. कोई Glitch बनाएं, अपना वर्शन मुझे ट्वीट करें और मैं इसे कम्यूनिटी रीमिक्स सेक्शन नीचे दिया गया है.
कम्यूनिटी रीमिक्स
- कस्टम एलिमेंट के साथ @_developit: डेमो और कोड
- एचटीएमएल/सीएसएस/जेएस के साथ @maineedwin1: डेमो और कोड
- Glitch रीमिक्स के साथ @a_nurella: डेमो और कोड
- एचटीएमएल/सीएसएस/जेएस के साथ @EvroMalarkey: डेमो और कोड