कोडलैब: साइडनेव कॉम्पोनेंट बनाना

इस कोडलैब में, वेब पर रिस्पॉन्सिव स्लाइड आउट साइड नेविगेशन लेआउट कॉम्पोनेंट बनाने का तरीका बताया गया है. हम एचटीएमएल से शुरू करके, सीएसएस और फिर JavaScript के साथ कॉम्पोनेंट बनाएंगे.

इस कॉम्पोनेंट को बनाने के लिए, सीएसएस वेब प्लैटफ़ॉर्म की चुनी गई सुविधाओं के बारे में जानने के लिए, मेरी ब्लॉग पोस्ट साइडनेव कॉम्पोनेंट बनाना देखें.

सेटअप

  1. प्रोजेक्ट में बदलाव करने के लिए, बदलाव करने के लिए रीमिक्स करें पर क्लिक करें.
  2. app/index.html खोलें.

एचटीएमएल

सबसे पहले, एचटीएमएल सेटअप की ज़रूरी चीज़ें जान लें, ताकि काम करने के लिए उसमें कॉन्टेंट और कुछ बॉक्स मौजूद रहें.

इस एचटीएमएल को <body> टैग में डालें.

<aside></aside>
<main></main>

<aside>, <main> के साथ नेविगेशन मेन्यू को एक कॉम्प्लीमेंटरी एलिमेंट के तौर पर रखता है. <main> में मुख्य पेज का कॉन्टेंट होता है.

इसके बाद, हम पेज के बाकी कॉन्टेंट से इन सिमैंटिक एलिमेंट को भर देंगे.

<aside> एलिमेंट में नेविगेशन एलिमेंट, कुछ नेविगेशन लिंक, और 'बंद करें' लिंक जोड़ें.

<aside>
  <nav>
    <h4>My</h4>
    <a href="#">Dashboard</a>
    <a href="#">Profile</a>
    <a href="#">Preferences</a>
    <a href="#">Archive</a>

    <h4>Settings</h4>
    <a href="#">Accessibility</a>
    <a href="#">Theme</a>
    <a href="#">Admin</a>
  </nav>

  <a href="#"></a>
</aside>

लिंक, <nav> एलिमेंट में अच्छे से चले जाते हैं और <nav> एलिमेंट, <aside> साइडबार में बहुत अच्छे होते हैं. हालांकि, हम इस सुविधा को और बेहतर बना सकते हैं.

मुख्य कॉन्टेंट एलिमेंट में, लेआउट कॉन्टेंट को सेमेटिक तरीके से रखने के लिए, एक हेडर और एक लेख जोड़ें.

<main>
  <header>
    <a href="#sidenav-open" class="hamburger">
      <svg viewBox="0 0 50 40">
        <line x1="0" x2="100%" y1="10%" y2="10%" />
        <line x1="0" x2="100%" y1="50%" y2="50%" />
        <line x1="0" x2="100%" y1="90%" y2="90%" />
      </svg>
    </a>
    <h1>Site Title</h1>
  </header>

  <article>
    {put some placeholder content here}
  </article>
</main>

हेडर में, मेन्यू खोलने का लिंक होता है. साइडबार में, 'बंद करें' बटन होता है. हम जल्द ही, व्यूपोर्ट के साइज़ के हिसाब से एलिमेंट दिखाएंगे और छिपाएंगे.

हमने <article> एलिमेंट में, प्लेसहोल्डर वाक्य चिपकाया है. `` को अपने कॉन्टेंट से बदलें या यहां दिया गया लोरम पेस्ट करें:

<h2>Totam Header</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum consectetur, necessitatibus velit officia ut impedit veritatis temporibus soluta? Totam odit cupiditate facilis nisi sunt hic necessitatibus voluptatem nihil doloribus! Enim.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead Totam Odit</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

<h3>Subhead</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>

इस कॉन्टेंट और इसकी लंबाई की वजह से, पेज को स्क्रोल किया जा सकता है. ऐसा तब होता है, जब पेज की ऊंचाई आपके व्यूपोर्ट की ऊंचाई से ज़्यादा हो जाती है.

अब तक, आपने नेविगेशन, लिंक, और साइडनेवि को बंद करने का तरीका जोड़कर, साइड एलिमेंट जोड़ा है. आपने मुख्य एलिमेंट में एक हेडर, साइडनेव खोलने का तरीका, और एक लेख भी जोड़ा है. यह पहले से ही साफ़, सेमैंटिक, और समय के साथ बदलने वाला है. हालांकि, हम इसे सभी के लिए ज़्यादा साफ़ और आसान बना सकते हैं. साइडनेव में मौजूद खुले लिंक को ज़्यादा साफ़ तौर पर मार्क किया जा सकता है.

हेडर के ओपन लिंक एलिमेंट में title और aria-label एट्रिब्यूट जोड़ें:

<a href="#sidenav-open" class="hamburger">
<a href="#sidenav-open" title="Open Menu" aria-label="Open Menu" class="hamburger">

ओपन एसवीजी आइकॉन को भी ज़्यादा साफ़ तौर पर मार्क किया जा सकता है. ओपन लिंक एलिमेंट में मौजूद SVG में ये एट्रिब्यूट जोड़ें:

<svg viewBox="0 0 50 40">
<svg viewBox="0 0 50 40" role="presentation" focusable="false" aria-label="trigram for heaven symbol">

साइडनेव में मौजूद 'बंद करें' लिंक को ज़्यादा साफ़ तौर पर मार्क किया जा सकता है. साइडनेव लिंक एलिमेंट में title और aria-label एट्रिब्यूट जोड़ें:

<a href="#"></a>
<a href="#" title="Close Menu" aria-label="Close Menu"></a>

सीएसएस

अब एलिमेंट को लेआउट करने का समय आ गया है. मुख्य कॉन्टेंट और साइडनेव, <body> टैग के डायरेक्ट चाइल्ड हैं. इसलिए, इनसे शुरुआत करना अच्छा रहेगा.

इस सीएसएस को css/sidenav.css में जोड़ें, ताकि <body> एलिमेंट बच्चों को अलग-अलग लेआउट में बताए.

body {
  display: grid;
  grid: [stack] 1fr / min-content [stack] 1fr;

  @media (max-width: 540px) {
    & > :matches(aside, main) {
      grid-area: stack;
    }
  }
}

इस लेआउट का मतलब है: एक पंक्ति stack बनाएं और उसमें सभी चीज़ें डालें. साथ ही, उस पंक्ति में दो कॉलम बनाएं. इनमें से दूसरे कॉलम का नाम भी stack है. पहले कॉलम का साइज़, कॉन्टेंट की ज़रूरत के हिसाब से होना चाहिए. बाकी कॉन्टेंट दूसरे कॉलम में डाला जा सकता है. इसके बाद, अगर व्यूपोर्ट का साइज़ 540px या उससे कम है, तो साइडनेव और मुख्य कॉन्टेंट एलिमेंट को एक ही पंक्ति और कॉलम में डालें. इससे, वे 1x1 ग्रिड में एक-दूसरे के ऊपर दिखेंगे.

रिस्पॉन्सिव स्टैकिंग की इस सुविधा को आधार के तौर पर इस्तेमाल करके, अब हम साइडनेव के दिखने और ट्रांज़िशन स्टाइल को टॉगल करने के लिए, यूआरएल बार की स्थिति का फ़ायदा ले सकते हैं.

<aside> एलिमेंट को app/index.html में वापस अपडेट करें:

<aside>
<aside id="sidenav-open">

इससे सीएसएस, एलिमेंट और यूआरएल हैश को एक साथ मैच कर पाता है. :target का इस्तेमाल करने के लिए यह ज़रूरी है. अब एलिमेंट का आईडी, उस यूआरएल हैश से मैच कर सकता है जिसे हम <a> टैग के साथ सेट करेंगे.

इसके अलावा, JavaScript टारगेटिंग को आसान बनाने के लिए, साइडनेव को कंट्रोल करने वाले मुख्य एलिमेंट के लिए आईडी जोड़ें. सबसे पहले, साइडनेवि में मौजूद ओपन लिंक में कोई आईडी जोड़ें:

<a href="#sidenav-open" class="hamburger" title="Open Menu" aria-label="Open Menu">
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">

इसके बाद, साइडनेव बंद करने के लिंक में एक आईडी जोड़ें:

<a href="#" title="Close Menu" aria-label="Close Menu"></a>
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>

इससे, मैक्रो <body> के रिस्पॉन्सिव स्टैकिंग लेआउट के साथ-साथ, यूआरएल बार से जुड़ने में भी मदद मिलती है. चलिए, आगे बढ़ना शुरू करें!

<aside> का लेआउट भी साफ़ है. इसमें दो चाइल्ड एलिमेंट हैं. पहला <nav>, जो पेपर जैसा दिखने वाला स्लाइड आउट कॉम्पोनेंट है. दूसरा, क्लोज़िंग <a> लिंक एलिमेंट, जो यूआरएल को # पर सेट करता है. यह लिंक, पेपर स्लाइड आउट नेविगेशन के दाईं ओर दिखाई नहीं देता है; ऐसा इसलिए है, ताकि लोग विज़ुअल कॉम्पोनेंट को खारिज करने के लिए उसे "क्लिक" कर सकें.

css/sidenav.css में यह सीएसएस जोड़ें:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;
}

मुझे लगता है कि रेशियो और नामों को यहां बहुत अच्छे तरीके से शामिल किया गया है. यहां ग्रिड की मदद से डिज़ाइनर को बहुत कंट्रोल मिलता है.

इसके बाद, मुझे मुख्य कॉन्टेंट को शर्त के हिसाब से ओवरले करना होगा और दस्तावेज़ को स्क्रोल करने पर भी अपनी जगह बनाए रखनी होगी. यह position: sticky और कुछ overscroll-behavior लोगों के लिए बढ़िया काम है.

साइडनेव के लिए ये स्टाइल जोड़ें:

#sidenav-open {
  display: grid;
  grid-template-columns: [nav] 2fr [escape] 1fr;

  @media (max-width: 540px) {
    position: sticky;
    top: 0;
    max-height: 100vh;
    overflow: hidden auto;
    overscroll-behavior: contain;

    visibility: hidden; /* not keyboard accessible when closed */
  }
}

इन स्टाइल से यह पक्का होता है कि साइडनेव, व्यूपोर्ट की ऊंचाई के बराबर हो. साथ ही, यह वर्टिकल तौर पर स्क्रोल करता हो और इसमें स्क्रोल होता हो. सबसे अहम बात यह है कि यह एलिमेंट को छिपा देता है. डिफ़ॉल्ट रूप से, जब व्यूपोर्ट 540px या उससे छोटा हो, तो साइडनेव को छिपाएं. जब तक!

#sidenav-open एलिमेंट में :target स्यूडो-सिलेक्टर जोड़ें:

#sidenav-open {

  @media (max-width: 540px) {

    &:target {
      visibility: visible;
    }
  }
}

अगर उस एलिमेंट और यूआरएल बार का आईडी एक ही है, तो visibility को visible पर सेट करें. पेज स्क्रोल करने के बाद साइड मेन्यू खोलें या साइडनेव के खुले होने पर पेज को स्क्रोल करके देखें. आपकी क्या राय है?

app/sidenav.css के सबसे नीचे यह सीएसएस जोड़ें:

#sidenav-button,
#sidenav-close {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  touch-action: manipulation;

  @media (min-width: 540px) {
    display: none;
  }
}

ये स्टाइल, हमारे 'खोलें' और 'बंद करें' बटन को टारगेट करते हैं. साथ ही, उनके टैप और टच स्टाइल तय करते हैं. इसके अलावा, वे व्यूपोर्ट के 540px या उससे बड़े होने पर, उन्हें छिपा भी देते हैं.

आइए, थोड़ा शानदार बनाने के लिए, सुलभता के साथ सीएसएस ट्रांसफ़ॉर्म जोड़ते हैं. css/sidenav.css में यह सीएसएस जोड़ें:

#sidenav-open {
  --easeOutExpo: cubic-bezier(0.16, 1, 0.3, 1);
  --duration: .6s;

  ...

  @media (max-width: 540px) {
    ...

    transform: translateX(-110vw);
    will-change: transform;
    transition:
      transform var(--duration) var(--easeOutExpo),
      visibility 0s linear var(--duration);

    &:target {
      visibility: visible;
      transform: translateX(0);
      transition: transform var(--duration) var(--easeOutExpo);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    --duration: 1ms;
  }
}
`prefers-reduced-motion` मीडिया क्वेरी के आधार पर, इंटरैक्शन के साथ और बिना अवधि के लागू किए गए इंटरैक्शन का डेमो.

कुछ JavaScript जोड़ें

Escape बटन से मेन्यू बंद हो जाना चाहिए. js/index.js में यह JS जोड़ें:

const sidenav = document.querySelector('#sidenav-open');

sidenav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    document.location.hash = '';
  }
});

यह साइडनेव एलिमेंट पर किसी मुख्य इवेंट के लिए सुनता है. अगर यह Escape है, तो यह यूआरएल हैश को खाली पर सेट करता है, जिससे साइडनेव ट्रांज़िशन बंद हो जाता है.

UX JS का यह अगला हिस्सा फ़ोकस मैनेजमेंट है. मुझे साइडनेव को खोलने और बंद करने की प्रोसेस को आसान बनाना है. इसलिए, मैं तब तक इंतज़ार करता हूं, जब तक साइडनेव किसी तरह का ट्रांज़िशन पूरा नहीं कर लेता. इसके बाद, यूआरएल हैश के साथ क्रॉस-चेक करके यह तय करता हूं कि साइडनेव चालू है या बंद. इसके बाद, मैं JavaScript का इस्तेमाल करके, उस बटन पर फ़ोकस सेट करता हूं जो उपयोगकर्ता ने अभी दबाया है.

js/index.js में यह JavaScript जोड़ें:

const closenav = document.querySelector('#sidenav-close');
const opennav = document.querySelector('#sidenav-button');

sidenav.addEventListener('transitionend', e => {
  if (e.propertyName !== 'transform') {
    return;
  }

  const isOpen = document.location.hash === '#sidenav-open';

  isOpen
    ? closenav.focus()
    : opennav.focus();
});

इसे आज़माएं

  • साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीनफ़ुलस्क्रीन दबाएं.

नतीजा

कॉम्पोनेंट से जुड़ी मेरी ज़रूरतें पूरी हो गई हैं. इस पर आधारित अपनी सुविधा बनाएं. यूआरएल के बजाय, JavaScript स्टेटस का इस्तेमाल करें. साथ ही, इसे अपनी पसंद के मुताबिक बनाएं! इसमें हमेशा कुछ न कुछ जोड़ने या इस्तेमाल के और उदाहरण शामिल करने के लिए कुछ न कुछ होता है.

इस कॉम्पोनेंट पर लागू किए गए नॉन-लेआउट से जुड़ी स्टाइल देखने के लिए, css/brandnav.css खोलें. मुझे नहीं लगता कि यह उस सुविधा सेट के लिए ज़रूरी है जिस पर मेरा फ़ोकस था. साथ ही, मुझे उम्मीद थी कि स्टाइल को लेआउट से अलग करने से, कॉपी और चिपकाने की सुविधा को बढ़ावा मिलेगा. इस जानकारी की मदद से, आपको ज़्यादा जानकारी मिल सकती है!

रिस्पॉन्सिव साइडनेव कॉम्पोनेंट को स्लाइड आउट कैसे बनाएं? क्या कभी आपके पास एक से ज़्यादा, जैसे कि दोनों तरफ़ एक-एक टैब खुला होता है? हमें YouTube वीडियो में, समस्या को हल करने का आपका तरीका दिखाने में खुशी होगी. इसके लिए, हमें ट्वीट करें या YouTube पर अपने कोड के साथ टिप्पणी करें. इससे सभी को मदद मिलेगी!