ویژگی تصویر

ساخت منوی چسبنده با CSS Sticky

  /  CSS   /  ساخت منوی چسبنده با CSS Sticky
بنر تبلیغاتی الف

منوی چسبنده (Sticky) ابزاری ساده و قدرتمند برای بهبود تجربه کاربری است که اجازه می‌دهد یک عنصر زمانی که به نقطه‌ای از صفحه می‌رسد، در موقعیت مشخصی (معمولاً بالا) «بچسبد» و همچنان در جریان اسکرول باقی بماند. تفاوت اصلی بین position: fixed و position: sticky این است که sticky در محدوده کانتینر والد خود عمل می‌کند و با محتوای اطراف تعامل طبیعی دارد.

مبانی position: sticky

خواص اساسی که برای ساخت یک منوی چسبنده نیاز دارید عبارتند از: position: sticky، مقدار top (یا left/right بسته به جهت) و توجه به این‌که والد عنصر نباید overflow: hidden/auto که رفتار را تضعیف می‌کند، داشته باشد.

<nav class="sticky-nav">
  <ul>
    <li><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#contact">Contact</a></li>
  </ul>
</nav>

.sticky-nav {
  position: sticky;
  top: 0;
  background: #fff;
  z-index: 1000;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}

توضیح: این کد یک ناوبری ساده تعریف می‌کند که وقتی بالای صفحه قرار می‌گیرد، با تعیین top: 0 به بالای پنجره می‌چسبد. z-index برای اطمینان از قرارگیری بالاتر از سایر اجزاست و background/box-shadow برای قابل خواندن بودن در هنگام چسبیدن است.

مثال پیشرفته: منوی کناری درون کانتینر

گاهی می‌خواهیم یک سایدبار تنها تا انتهای کانتینر خود بچسبد و بعد از آن با اسکرول همراه نباشد. position: sticky دقیقاً این امکان را می‌دهد.

<div class="container">
  <aside class="sidebar">
    <nav>...links...</nav>
  </aside>
  <main>...long content...</main>
</div>

.container {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 20px;
}

.sidebar nav {
  position: sticky;
  top: 20px; /* فاصله از بالای پنجره */}

توضیح: در این ساختار، سایدبار تا زمانی که ارتفاع کانتینر اجازه دهد از بالای صفحه فاصله top: 20px را حفظ می‌کند و سپس در محدوده والدش می‌ایستد. مهم است که والد (این‌جا .container یا بالاتر) overflow: visible باشد تا رفتار sticky به‌درستی کار کند.

موارد شایع شکست و راه‌حل‌ها

  • وجود overflow: auto|hidden روی والد باعث می‌شود sticky کار نکند. راه‌حل: overflow را تغییر دهید یا sticky را به والد مناسب‌تری منتقل کنید.
  • وجود transform، filter یا perspective روی یک عنصر والد، باعث ایجاد جدیدی کردن کانتکست می‌شود و رفتار sticky را غیرفعال می‌کند. راه‌حل: از transform روی والدهای بالاتر اجتناب کنید یا ساختار DOM را تغییر دهید.
  • برای اجزایی که در لایه‌های پیچیده قرار دارند، z-index نیاز به تنظیم دقیق دارد.
/* مثال اصلاحی: والد نباید overflow یا transform داشته باشد */.wrapper {
  /* اگر قبلاً overflow: auto بود، آن را حذف یا به عنصر دیگر منتقل کنید */  overflow: visible;
  /* از transform: translateZ(0) یا ... روی این لایه اجتناب کنید */}

.sidebar nav {
  position: sticky;
  top: 16px;
  z-index: 10;
}

توضیح: این کد نشان می‌دهد که چگونه باید overflow و transform والد را تغییر دهیم تا sticky کار کند و z-index برای اطمینان از نمایش صحیح در بالای محتوا تنظیم شده است.

سازگاری مرورگرها و fallback

مرورگرپشتیبانی
Chromeاز نسخه‌های اخیر پشتیبانی کامل
Firefoxپشتیبانی کامل
Safari (موبایل/دسکتاپ)پشتیبانی با برخی محدودیت‌ها در نسخه‌های قدیمی
Edgeپشتیبانی کامل (Chromium-based)

در مرورگرهای خیلی قدیمی یا سناریوهای خاص می‌توانید یک fallback ساده با جاوااسکریپت بسازید که موقعیت عنصر را در اسکرول بررسی و کلاس fixed اضافه کند:

// Simple JS fallback (debounced for performance)
let nav = document.querySelector('.sticky-nav');
let navTop = nav.getBoundingClientRect().top + window.pageYOffset;
let ticking = false;

function onScroll() {
  if (!ticking) {
    window.requestAnimationFrame(() => {
      if (window.pageYOffset >= navTop) {
        nav.classList.add('is-fixed');
      } else {
        nav.classList.remove('is-fixed');
      }
      ticking = false;
    });
    ticking = true;
  }
}

window.addEventListener('scroll', onScroll);

توضیح: این اسکریپت موقعیت اولیه نِیو را محاسبه می‌کند و با استفاده از requestAnimationFrame و یک فلگ (ticking) از اضافه‌بار رویداد اسکرول جلوگیری می‌کند. کلاس is-fixed در CSS باید حالت position: fixed را شبیه‌سازی کند. توجه داشته باشید که برای بهبود عملکرد بهتر است debouncing یا throttling مناسب استفاده شود.

نکات دسترسی و طراحی واکنش‌گرا

  • منوی چسبنده نباید محتوای مهم را در صفحهٔ موبایل بپوشاند؛ از top با مقدار مناسب یا media queries استفاده کنید.
  • برای کاربران صفحه‌خوان مطمئن شوید ساختار HTML منطقی و لینک‌ها دسترس‌پذیر هستند.
  • در هنگام تغییر وضعیت منو (مثلاً باز/بسته شدن) فوکوس را مدیریت کنید تا تجربه صفحه‌کلید مناسب باشد.
  • از CSS transitions ساده استفاده کنید اما از انیمیشن‌های سنگین پرهیز کنید تا عملکرد حفظ شود.

بهینه‌سازی عملکرد

  • از heavy repaints جلوگیری کنید: اجزایی که position: sticky دارند را سبک نگه دارید.
  • برای تغییرات بصری ساده از transform و opacity استفاده کنید (اما دقت کنید که transform روی والدها می‌تواند sticky را خراب کند).
  • اگر نیاز به پالیفیل دارید، از نسخه‌های سبک و بهینه‌شده استفاده کنید و از debounce/throttle در اسکریپت‌های اسکرول بهره ببرید.

نتیجه‌گیری

position: sticky یک ابزار ساده اما قوی برای ساخت منوها و سایدبارهای چسبنده است که تجربه کاربری را بسیار بهبود می‌بخشد. شناخت محدودیت‌ها (مثل overflow و transform) و رعایت نکات دسترسی و عملکرد کمک می‌کند تا پیاده‌سازی پایدار و قابل اعتمادی داشته باشید. در بیشتر موارد کافی است چند خط CSS اضافه کنید؛ برای حالات خاص از fallback جاوااسکریپت یا بازطراحی ساده بهره ببرید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: