Реалізація Mega Menu (мега-меню) на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація Mega Menu (мега-меню) на сайті
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація Mega Menu (мега-меню) на сайті

Мега-меню — навігаційний компонент, що розкриває багатоколоночну панель з групуванням посилань, зображеннями, описами й додатковими елементами управління. Застосовується на сайтах з глибокою структурою розділів: інтернет-магазини, портали, корпоративні сайти з кількома продуктовими лініями. Стандартний dropdown-список стає вузьким місцем, коли розділів більше 20 й користувачу потрібен контекст разом з навігацією.

Коли стандартне меню перестає справляться

Звичайний выпадаючий список (<ul> з position: absolute) має жорсткі обмеження:

  • одна колонка — неможливо групувати по категоріях
  • немає місця для допоміжного контенту (зображення, описи, промо-блоки)
  • на touch-пристроях hover-логіка ломається
  • управління з клавіатури або відсутнє, або реалізовано наспіх

Мега-меню вирішує ці проблеми через іншу модель розкриття й розмітку.

Архітектура компонента

Типова структура мега-меню складається з трьох шарів:

Тригери верхнього рівня — горизонтальна навігаційна полоса. Кожен пункт — це або посилання, або кнопка, що розкриває панель. З точки зору семантики: <button aria-expanded="false" aria-controls="menu-catalog">.

Панель<div role="dialog"> або просто <div> з aria-labelledby, абсолютно або фіксовано позиціонована, займаюча всю ширину контейнера (або viewport). Всередину — CSS Grid або Flexbox з кількома колонками.

Контент всередину панелі — групи посилань з заголовками, featured-блоки, зображення, CTA-кнопки. Структуруються через <nav> + <ul> всередину іменованих секцій.

<nav aria-label="Основна навігація">
  <ul class="mega-nav">
    <li>
      <button
        aria-expanded="false"
        aria-controls="panel-catalog"
        class="mega-nav__trigger"
      >
        Каталог
      </button>
      <div id="panel-catalog" class="mega-panel" hidden>
        <div class="mega-panel__grid">
          <section aria-labelledby="group-electronics">
            <h3 id="group-electronics">Електроніка</h3>
            <ul>
              <li><a href="/catalog/phones">Смартфони</a></li>
              <li><a href="/catalog/laptops">Ноутбуки</a></li>
            </ul>
          </section>
          <!-- інші групи -->
        </div>
      </div>
    </li>
  </ul>
</nav>

Реалізація на React

У React-проектах мега-меню зазвичай управляється через контекст або локальний state з useReducer. Анімації відкриття/закриття — через Framer Motion або CSS-трансформації.

const MegaMenu = () => {
  const [activePanel, setActivePanel] = useState<string | null>(null);
  const containerRef = useRef<HTMLElement>(null);

  // Закриття по клику вне меню
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setActivePanel(null);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  // Закриття по Escape
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setActivePanel(null);
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, []);

  return (
    <nav ref={containerRef} aria-label="Основна навігація">
      {navItems.map((item) => (
        <MegaNavItem
          key={item.id}
          item={item}
          isOpen={activePanel === item.id}
          onToggle={() => setActivePanel(activePanel === item.id ? null : item.id)}
        />
      ))}
    </nav>
  );
};

Якщо меню використовується у Next.js з SSR, hidden атрибут панелі повинен обробляться коректно на сервері, щоб уникнути layout shift при гідрації.

Доступність (WCAG 2.1 AA)

Це найчастіше ігнорована частина. Вимоги конкретні:

Паттерн Реалізація
Відкриття по Enter/Space на тригері onKeyDown з перевіркою `key === 'Enter'
Навігація стрілками всередину панелі roving tabindex або aria-activedescendant
Закриття по Escape глобальний обробник або через FocusTrap
Фокус при закритті повернення на тригер через triggerRef.current?.focus()
Приховання від screen reader hidden або aria-hidden="true" на закритій панелі

Бібліотека @radix-ui/react-navigation-menu реалізує більшість цих вимог з коробки й є кращою основою для кастомного мега-меню в React-стеку. Вона використовує паттерн NavigationMenu.Root + NavigationMenu.List + NavigationMenu.Item + NavigationMenu.Trigger + NavigationMenu.Content.

Мобільна версія

Мега-меню на мобільних пристроях трансформується в аккордеон або drawer-панель. Це інший компонент, не просто адаптований десктопний. Breakpoint-логіка у CSS:

@media (max-width: 1024px) {
  .mega-panel {
    position: static;
    display: grid;
    grid-template-rows: 0fr;
    overflow: hidden;
    transition: grid-template-rows 0.3s ease;
  }

  .mega-panel[data-open="true"] {
    grid-template-rows: 1fr;
  }
}

Трюк з grid-template-rows: 0fr → 1fr дозволяє анімувати висоту без фіксованого значення — устаткований паттерн для аккордеонів без JavaScript-вимірювання висоти.

Позиціонування панелі

Два основних підходи:

Full-width — панель розтягується на всю ширину сторінки, прив'язується до нижної границі навігаційної полоси. Використовується в більшості e-commerce сайтів. Реалізується через position: fixed з top: <navbar-height> або через position: absolute на обгортці з overflow: visible.

Flyout — панель позиціонується відносно конкретного тригера. Підходить для меню з невеликою кількістю груп. Вимагає розрахунку позиції через getBoundingClientRect() для коректної поведінки у куті екрана (flip-логіка, як у Floating UI / Popper.js).

Продуктивність

Панелі мега-меню містять багато DOM-вузлів. Якщо контент завантажується з API (наприклад, динамічні категорії каталогу), важливо:

  • рендерити панелі ліниво — лише після першого відкриття (mountedPanels: Set<string>)
  • використовувати content-visibility: auto для скритих секцій
  • обмежити кількість одночасно монтованих панелей
const [mounted, setMounted] = useState(false);

const handleOpen = () => {
  if (!mounted) setMounted(true);
  setIsOpen(true);
};

return (
  <div>
    <button onClick={handleOpen}>Каталог</button>
    {mounted && (
      <div hidden={!isOpen} className="mega-panel">
        <CatalogPanelContent />
      </div>
    )}
  </div>
);

Типові терміни реалізації

  • Статичне мега-меню (фіксовані посилання, без API) з мобільним аккордеоном — 3–5 днів
  • Динамічне меню з завантаженням категорій з CMS/API + full accessibility + анімації — 7–10 днів
  • Інтеграція у існуючий дизайн-системний компонент з unit/a11y тестами — додати 2–3 дні