CSS, HTML, JavaScript, سورس کد

سورس کد منو ریسپانسیو موبایل با HTML، CSS و JavaScript (رایگان)

منو ریسپانسیو موبایل - طاووس وب
زمان مطالعه: ۷ دقیقهسطح: مبتدیسورس کد رایگان
خلاصه در یک نگاه
  • این منو در موبایل بالای صفحه پنهان است و با زدن آیکون، با انیمیشن نرم پایین می‌آید.
  • کل منطق فقط یک کلاس است: show-menu که top منو را از منفی به صفر می‌برد.
  • در دسکتاپ با یک media query، همان منو به منوی افقی معمولی تبدیل می‌شود.
  • نسخهٔ این مقاله دسترس‌پذیر است: دکمهٔ واقعی، aria-expanded و بستن با کلید Escape.

بیش از نیمی از بازدید سایت‌ها از موبایل است و منو اولین جایی است که کاربر موبایل با آن کار می‌کند. در این آموزش سورس کد یک منو ریسپانسیو موبایل را با HTML، CSS و کمی JavaScript می‌سازیم: منویی که روی گوشی از بالای صفحه باز می‌شود و روی دسکتاپ به یک منوی افقی ساده تبدیل می‌شود. کد کامل را می‌توانید کپی کنید یا پیش‌نمایش نسخهٔ اولیه را ببینید.

دموی زنده منو ریسپانسیو

روی آیکون منو بزنید

منو با کلیک روی لینک‌ها، دکمهٔ ضربدر یا کلید Escape بسته می‌شود.

منطق کار منو ریسپانسیو در یک نگاه

پنج قدم ساخت منو ریسپانسیو موبایل با HTML و CSS و JavaScript
کل منطق منو: پنهان کردن با top منفی و نمایش با اضافه شدن کلاس show-menu

ایدهٔ اصلی خیلی ساده است: منو همیشه در صفحه وجود دارد، اما در موبایل با position: fixed و top: -100% بالای صفحه و بیرون از دید قرار می‌گیرد. وقتی کاربر روی آیکون می‌زند، جاوااسکریپت کلاس show-menu را اضافه می‌کند، top صفر می‌شود و چون روی منو transition گذاشته‌ایم، منو نرم پایین می‌آید. پس جاوااسکریپت فقط یک کلاس را اضافه و حذف می‌کند و همهٔ انیمیشن با CSS انجام می‌شود که سریع‌تر و روان‌تر است.

قدم ۱: کد HTML منو

ساختار شامل لوگو، لیست لینک‌ها و دو دکمه (باز و بستن) است. به‌جای div از button استفاده کرده‌ایم تا منو با کیبورد و صفحه‌خوان هم کار کند. آیکون‌ها از کتابخانهٔ رایگان Boxicons هستند:

<!-- آیکون‌ها: Boxicons -->
<link href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">

<header class="header">
  <nav class="nav container">
    <a href="/" class="nav__logo">TavoosWeb</a>

    <div class="nav__menu" id="nav-menu">
      <ul class="nav__list">
        <li><a href="#" class="nav__link">خانه</a></li>
        <li><a href="#" class="nav__link">مقالات</a></li>
        <li><a href="#" class="nav__link">خدمات</a></li>
        <li><a href="#" class="nav__link">تماس با ما</a></li>
      </ul>

      <button class="nav__close" id="nav-close" aria-label="بستن منو">
        <i class="bx bx-x"></i>
      </button>
    </div>

    <button class="nav__toggle" id="nav-toggle" aria-label="باز کردن منو"
            aria-controls="nav-menu" aria-expanded="false">
      <i class="bx bx-grid-alt"></i>
    </button>
  </nav>
</header>

قدم ۲: کد CSS منو ریسپانسیو

این CSS به روش «اول موبایل» نوشته شده؛ یعنی استایل پایه برای موبایل است و در انتها با media query حالت دسکتاپ را اضافه کرده‌ایم:

:root {
  --header-height: 3.5rem;
  --first-color: #5f01af;
  --text-color: #1b1b1b;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
ul { list-style: none; }
a { text-decoration: none; }
button { background: none; border: 0; font: inherit; color: inherit; cursor: pointer; }

.header {
  position: fixed; top: 0; left: 0; width: 100%;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, .06);
  z-index: 100;
}
.nav {
  height: var(--header-height);
  max-width: 1024px; margin-inline: auto; padding-inline: 1.5rem;
  display: flex; justify-content: space-between; align-items: center;
}
.nav__logo { font-weight: 700; color: var(--text-color); }
.nav__toggle, .nav__close { font-size: 1.5rem; display: inline-flex; }

/* موبایل: منو بالای صفحه و بیرون از دید است */
.nav__menu {
  position: fixed; left: 0; top: -100%; width: 100%;
  padding: 5rem 0 3rem;
  background: var(--first-color);
  border-radius: 0 0 1.5rem 1.5rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .15);
  transition: top .4s ease;
}
.nav__list { display: flex; flex-direction: column; align-items: center; row-gap: 2rem; }
.nav__link { color: #fff; font-weight: 500; }
.nav__close { position: absolute; top: 1rem; right: 1.5rem; color: #fff; }

/* کلاسی که جاوااسکریپت اضافه می‌کند */
.show-menu { top: 0; }

/* دسکتاپ: منوی افقی معمولی */
@media (min-width: 1024px) {
  .nav__toggle, .nav__close { display: none; }
  .nav__menu { position: static; padding: 0; background: none; box-shadow: none; border-radius: 0; }
  .nav__list { flex-direction: row; column-gap: 2.5rem; }
  .nav__link { color: var(--text-color); }
  .nav__link:hover { color: var(--first-color); }
}

/* احترام به کاربرانی که انیمیشن کمتر می‌خواهند */
@media (prefers-reduced-motion: reduce) {
  .nav__menu { transition: none; }
}

نکته: اگر هدر شما ثابت (fixed) است، به بدنهٔ صفحه به اندازهٔ ارتفاع هدر فاصلهٔ بالا بدهید (مثلاً padding-top: var(--header-height)) تا اولین بخش محتوا زیر هدر پنهان نشود.

قدم ۳: کد JavaScript

جاوااسکریپت فقط کلاس را مدیریت می‌کند. دو قابلیت مهم هم اضافه کرده‌ایم که در بیشتر منوهای آماده فراموش می‌شوند: بستن منو بعد از کلیک روی لینک (برای صفحات تک‌صفحه‌ای ضروری است) و بستن با کلید Escape:

const navMenu   = document.getElementById('nav-menu'),
      navToggle = document.getElementById('nav-toggle'),
      navClose  = document.getElementById('nav-close');

function openMenu() {
  navMenu.classList.add('show-menu');
  navToggle.setAttribute('aria-expanded', 'true');
}
function closeMenu() {
  navMenu.classList.remove('show-menu');
  navToggle.setAttribute('aria-expanded', 'false');
}

navToggle?.addEventListener('click', openMenu);
navClose?.addEventListener('click', closeMenu);

// بستن منو بعد از کلیک روی هر لینک
document.querySelectorAll('.nav__link').forEach(link =>
  link.addEventListener('click', closeMenu)
);

// بستن منو با کلید Escape
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') closeMenu();
});

شخصی‌سازی منو

تغییر رنگ

فقط مقدار --first-color را عوض کنید تا رنگ پس‌زمینهٔ منو تغییر کند.

باز شدن از کنار

به‌جای top، از right: -100% و در کلاس show-menu از right: 0 استفاده کنید.

نقطهٔ شکست

عدد 1024px را به 768px تغییر دهید تا منوی افقی روی تبلت هم نمایش داده شود.

انیمیشن نرم‌تر

به‌جای ease از cubic-bezier(.22,1,.36,1) استفاده کنید؛ همان حسی که در دمو می‌بینید.

اگر منوی جذاب‌تری با انیمیشن نشانگر می‌خواهید، سورس کد نوبار انیمیشنی را هم ببینید. برای اصول کلی طراحی موبایل هم نکات ساخت سایت موبایل‌فرندلی را بخوانید. سورس‌های بیشتر در دسته‌بندی سورس کد CSS و سورس کد HTML هستند. ویدیوی این سورس را هم می‌توانید در اینستاگرام طاووس وب ببینید.

استفاده از این منو در وردپرس

قالب‌های وردپرسی معمولاً منوی موبایل خودشان را دارند و بهتر است همان را از تنظیمات قالب یا سربرگ‌ساز شخصی‌سازی کنید. این سورس برای سایت‌های HTML، لندینگ پیج‌های اختصاصی و قالب‌هایی که خودتان کدنویسی می‌کنید مناسب است. در وردپرس می‌توانید HTML را در یک ویجت HTML، CSS را در «سفارشی‌سازی ← CSS اضافی» و JavaScript را با یک افزونهٔ درج کد در فوتر قرار دهید.

سایتی می‌خواهید که روی موبایل عالی کار کند؟طاووس وب لندینگ پیج و سایت شرکتی را با طراحی موبایل‌محور، سرعت بالا و منوهای کاربرپسند می‌سازد.

طراحی لندینگ پیج

سؤالات متداول منو ریسپانسیو

منو ریسپانسیو چیست؟

منویی است که بسته به اندازهٔ صفحه تغییر شکل می‌دهد؛ در موبایل پشت یک آیکون پنهان می‌شود و با لمس باز می‌شود و در دسکتاپ به‌صورت افقی و کامل نمایش داده می‌شود.

آیا برای ساخت منو ریسپانسیو حتماً به جاوااسکریپت نیاز است؟

می‌شود با ترفندهای CSS خالص (مثل checkbox پنهان) هم منو ساخت، اما استفاده از چند خط جاوااسکریپت و دکمهٔ واقعی دسترس‌پذیرتر است و کنترل بهتری روی باز و بسته شدن می‌دهد.

چرا به‌جای div از button استفاده کردیم؟

دکمهٔ واقعی با کیبورد قابل فوکوس است، با Enter و Space کار می‌کند و صفحه‌خوان‌ها آن را به‌عنوان دکمه معرفی می‌کنند؛ ویژگی aria-expanded هم باز یا بسته بودن منو را اعلام می‌کند.

چطور منو را از سمت راست باز کنم؟

در CSS به‌جای top از right استفاده کنید: در حالت عادی right را منفی ۱۰۰ درصد بگذارید و در کلاس show-menu مقدار صفر بدهید. عرض منو را هم مثلاً ۷۵ درصد قرار دهید.

دانلود از گیت هاب ناشر سورس کد

دانلود فایل

پسورد فایل : ندارد

author-avatar

درباره مهدی حبیبی

مهدی حبیبی، بنیان‌گذار طاووس وب و برنامه‌نویس فرانت‌اند با بیش از ۵ سال تجربه در طراحی سایت و بیش از ۵۰ پروژهٔ انجام‌شده. تخصصش وردپرس، المنتور، ووکامرس، سئو و بهینه‌سازی سرعت است و تجربهٔ پروژه‌های واقعی را در طاووس وب به زبان ساده آموزش می‌دهد. و البته مجنون قهوه!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *