Mobile-First Menu

Современное меню для сайта. Mobile-first, dropdown, mega menu, sticky header

В прошлом уроке мы создали адаптивное многоуровневое меню, без JS. В этом уроке мы создадим профессиональное адаптивное меню с dropdown, mega menu и sticky header, оптимизированное для мобильных устройств.

Вы изучите:

  • Mobile-First подход — современный метод разработки, рекомендуемый Google;
  • CSS переменные (:root) — как создать гибкую систему цветов;
  • Flexbox — для идеального выравнивания элементов;
  • Position: relative/absolute — правильное позиционирование dropdown меню;
  • Media Queries — адаптация под разные экраны (768px, 1200px);
  • Intersection Observer API — современный способ сделать sticky header;
  • Vanilla JavaScript — без библиотек, чистый код.

Что нужно знать перед началом? Базовые знания HTML, CSS и JS приветствуются, но не обязательны. Объясню каждую строчку кода так, чтобы понял даже ребенок!

Что такое Mobile-First и почему это важно

Mobile-First — это подход к разработке, когда вы сначала создаете версию для мобильных, а потом добавляете улучшения для больших экранов.

Почему Mobile-First лучше?

Параметр Mobile-First Desktop-First
Скорость загрузки (мобила) 2.2 секунды 3.2 секунды (+45%)
Размер CSS 950 строк 1200 строк (+26%)
Media queries Только min-width min и max (сложнее)
Google индексация Оптимально Не оптимально
Конверсия (мобила) 10.2% 8.5% (-17%)

Статистика 2025 года

  • 60%+ трафика приходит с мобильных устройств;
  • Google полностью перешел на mobile-first индексацию;
  • 53% пользователей покидают сайт если он грузится > 3 секунд на мобиле;
  • Для многих людей телефон — единственное устройство для интернета.

Создаем HTML структуру

HTML — это скелет нашего меню. Он определяет, какие элементы будут на странице.

HTML — это как каркас дома (стены, крыша, двери). CSS — это покраска, обои, декор. JavaScript — это электричество, водопровод (всё, что двигается и работает).

Структура меню с семантической разметкой

Правильная семантическая разметка важна для SEO и доступности. Начнем с 1го уровневого меню.

<!-- Top Bar (верхняя полоса с контактами) -->
<div class="top-bar">
  <div class="container-xxl">
    <div class="top-bar-content">
      <div class="contact-info">
        <span>📧 email@example.ru</span>
        <span>📞 +7 (999) 123-45-67</span>
      </div>
      <div class="social-links">
        <a href="#" title="VK">VK</a>
        <a href="#" title="OK">OK</a>
        <a href="#" title="TG">TG</a>
      </div>
    </div>
  </div>
</div>

<!-- Основное меню -->
<header id="header" class="header">
  <div class="container-fluid container-xxl">
    <a href="#hero" class="logo">
      <img src="logo.png" alt="Wr Start Logo">
      <div class="sitename">Wr Start</div>
    </a>
    <nav id="navmenu" class="navmenu">
        <ul>
          <li><a href="#hero" class="active">Главная</a></li>
          <li><a href="#about">О компании</a></li>
          <li><a href="#services">Услуги</a></li>
          <li><a href="#portfolio">Портфолио</a></li>
          <li><a href="#team">Команда</a></li>
          <li><a href="#blog">Блог</a></li>
          <li><a href="#contact">Контакты</a></li>
        </ul>
      </nav>
      <!-- Кнопка призыва к действию -->
      <a class="btn-getstarted" href="#about">Начать</a>
      <!-- Гамбургер для мобилы -->
      <div class="mobile-nav-toggle"></div>
 </div> 
</header>

Разбираем элементы:

  1. <div class="top-bar"> — верхняя полоса. Это необязательный элемент. Здесь обычно размещают контакты, социальные сети или важные объявления.
  2. <header id="header"> — основной контейнер меню. id="header" нужен для JavaScript, чтобы найти этот элемент. class="header" — для стилей CSS.

    Совет: ID vs Class:

    ID — уникальный (как паспорт), используется один раз на странице.
    Class — может повторяться (как имя), используется для стилей.

  3. <div class="container-fluid container-xxl"> — контейнер. Ограничивает ширину содержимого. На больших экранах меню не растянется на весь экран. container-fluid будет иметь position: relative — это ключевой момент для mega menu (его внедрим позже)!
  4. <a href="#" class="logo"> — логотип. Ссылка с картинкой и названием сайта. Обычно ведет на главную страницу.
  5. <nav class="navmenu"> — навигация. <nav> — семантический тег, говорит поисковикам: «Здесь меню навигации!»
  6. <ul> и <li> — список:
    <ul> = unordered list (неупорядоченный список);
    <li> = list item (элемент списка);
    Меню — это по сути список ссылок. Каждая ссылка обернута в <li>.
  7. <a class="btn-getstarted"> — кнопка CTA. CTA = Call To Action (призыв к действию). Это главная кнопка, которая привлекает внимание и ведет к важному действию (регистрация, покупка, связь).
  8. <div class="mobile-nav-toggle"> — гамбургер. Кнопка с тремя полосками (☰), которая открывает меню на мобильных. На десктопе мы её скроем через CSS.

Порядок элементов важен!

На мобиле: Логотип → Кнопка → Бургер
На десктопе: Логотип → Меню → Кнопка

Мы управляем порядком через CSS order, не меняя HTML. Это называется визуальная перестановка без изменения DOM!

Добавляем Dropdown меню

Dropdown — это выпадающее подменю. Добавим его к пункту «Услуги»:

<li class="dropdown">
  <a href="#"><span>Услуги</span></a>
  <ul>
    <li><a href="#">Веб-разработка</a></li>
    <li><a href="#">SEO продвижение</a></li>
    <li><a href="#">Дизайн</a></li>
    <!-- Deep Dropdown (3-й уровень) -->
    <li class="dropdown">
      <a href="#"><span>Маркетинг</span></a>
      <ul>
        <li><a href="#">Контекстная реклама</a></li>
        <li><a href="#">SMM</a></li>
        <li><a href="#">Email рассылки</a></li>
      </ul>
    </li>
    <li><a href="#">Поддержка сайтов</a></li>
  </ul>
</li>

Что здесь происходит?

  1. class="dropdown" — говорит: «У меня есть подменю!»;
  2. Внутри <li> есть <ul> — это и есть подменю;
  3. Deep Dropdown — это dropdown внутри dropdown (3 уровня вложенности).

Добавляем Mega Menu

Mega Menu — широкое меню с несколькими колонками. Идеально для каталогов товаров или большого количества разделов.

<li class="listing-dropdown">
  <a href="#"><span>Каталог</span></a>
  <ul>
    <!-- Колонка 1 -->
    <li>
      <a href="#"><strong>Электроника</strong></a>
      <a href="#">Смартфоны</a>
      <a href="#">Ноутбуки</a>
      <a href="#">Планшеты</a>
    </li>
    <!-- Колонка 2 -->
    <li>
      <a href="#"><strong>Одежда</strong></a>
      <a href="#">Мужская</a>
      <a href="#">Женская</a>
      <a href="#">Детская</a>
    </li>
    <!-- Колонка 3 -->
    <li>
      <a href="#"><strong>Дом и сад</strong></a>
      <a href="#">Мебель</a>
      <a href="#">Инструменты</a>
      <a href="#">Растения</a>
    </li>
  </ul>
</li>

class="listing-dropdown" — специальный класс для mega menu. Отличается от обычного dropdown тем, что:

  • Открывается на всю ширину контейнера;
  • Элементы расположены горизонтально в несколько колонок;
  • Каждая колонка — это отдельный <li>.

Теперь переходим к оформлению (внешнему виду).

CSS переменные в :root

CSS переменные (custom properties) — это переменные для хранения значений, которые можно использовать много раз.

Что такое :root?

:root {
  --primary-color: #4154f1;
  --heading-color: #012970;
  --text-color: #444444;
}

:root — это корень документа, самый верхний элемент (тег <html>). Переменные, заданные здесь, доступны везде на странице.

Зачем нужны переменные?

Без переменных С переменными
.header {
  color: #4154f1;
}
.button {
  background: #4154f1;
}
.link {
  color: #4154f1;
}
:root {
  --primary-color: #4154f1;
}
.header {
  color: var(--primary-color);
}
.button {
  background: var(--primary-color);
}
.link {
  color: var(--primary-color);
}
Чтобы поменять цвет, нужно исправить в 3 местах Меняем только в :root — меняется везде!

Наши переменные для меню

:root {
  /* Шрифты */
  --default-font: system-ui, -apple-system, Arial, sans-serif;
  --heading-font: "Nunito", sans-serif;
  --nav-font: "Poppins", sans-serif;
  
  /* Основные цвета */
  --background-color: #ffffff;
  --default-color: #444444;
  --heading-color: #012970;
  --accent-color: #4154f1;
  --contrast-color: #ffffff;
  
  /* Цвета навигации */
  --nav-color: #012970;
  --nav-hover-color: #4154f1;
  --nav-mobile-background-color: #ffffff;
  --nav-dropdown-background-color: #ffffff;
  --nav-dropdown-color: #212529;
  --nav-dropdown-hover-color: #4154f1;
}

Как использовать переменные?

Функция var() достает значение из переменной:

.header {
  background-color: var(--background-color);
  color: var(--default-color);
}

.navmenu a {
  color: var(--nav-color);
}

.navmenu a:hover {
  color: var(--nav-hover-color);
}

Преимущества CSS переменных

  • Легко менять тему — меняем пару переменных, весь сайт меняет цвета
  • Удобно читатьvar(--primary-color) понятнее, чем #4154f1
  • Меньше ошибок — не нужно копировать одинаковые значения
  • Динамика — можно менять через JavaScript

Правила именования переменных

  • Начинаются с двух дефисов: --my-variable
  • Можно использовать буквы, цифры, дефисы, подчеркивания
  • Регистр важен: --Color и --color — разные переменные
  • Лучше использовать понятные имена: --primary-color вместо --c1

Мобильные стили (базовые)

Золотое правило Mobile-First: базовые стили пишем БЕЗ @media queries. Они применяются по умолчанию ко всем экранам.

Почему сначала мобильные? Мобильные устройства менее мощные, интернет медленнее. Если CSS оптимизирован для мобилы, на десктопе он работает еще быстрее!

Reset и базовые стили

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: var(--default-font);
  color: var(--default-color);
  line-height: 1.6;
}
a {
  text-decoration: none;
  color: inherit;
}
ul {
  list-style: none;
}

Что тут происходит?

  • * { margin: 0; padding: 0; } — убираем отступы у всех элементов. Браузеры ставят свои отступы, мы их сбрасываем;
  • box-sizing: border-box — теперь width включает padding и border. Так проще считать размеры;
  • list-style: none — убираем точки у списков (для меню они не нужны).

Header и контейнер

.header {
  background-color: var(--background-color);
  padding: 15px 0;
  position: relative;
  z-index: 997;
  transition: all 0.3s ease;
}

.header .container-fluid {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;  /* ВАЖНО для mega menu! */
}

Ключевой момент: строка position: relative; на .container-fluid делает его точкой отсчета для всех position: absolute потомков. Без этого mega menu не сможет растянуться на всю ширину контейнера!

Порядок элементов на мобиле

/* Используем flexbox order для управления порядком */
.header .logo {
  order: 1;  /* Первым слева */
}

.header .btn-getstarted {
  order: 2;           /* В центре */
  margin: 0 10px 0 0; /* Отступ до бургера */
  font-size: 14px;
  padding: 8px 16px;
}

.mobile-nav-toggle {
  order: 3;  /* Последним справа */
  width: 1.5em;
  height: 1.5em;
  background-image: url("data:image/svg+xml,..."); /* SVG гамбургера */
}

Как работает flexbox order: по умолчанию все элементы имеют order: 0. Элемент с order: 1 идет первым, order: 2 — вторым, и так далее. Это как номера в очереди!

Мобильное меню (скрыто по умолчанию)

.navmenu ul {
  display: none;  /* Скрыто, откроется по клику */
  list-style: none;
  position: absolute;
  inset: 60px 20px 20px 20px;  /* top right bottom left */
  padding: 10px 0;
  margin: 0;
  border-radius: 10px;
  background-color: var(--nav-mobile-background-color);
  overflow-y: auto;  /* Скролл если пунктов много */
  box-shadow: 0px 10px 40px rgba(0, 0, 0, 0.15);
  z-index: 9998;
}

Что такое inset?

inset: 60px 20px 20px 20px; = краткая запись для:

  • top: 60px; — 60px от верха;
  • right: 20px; — 20px от правого края;
  • bottom: 20px; — 20px от низа;
  • left: 20px; — 20px от левого края.

Открытие меню при клике

/* Когда добавляем класс .mobile-nav-active */
.mobile-nav-active .navmenu > ul {
  display: block;  /* Показываем меню */
}

.mobile-nav-active .navmenu {
  position: fixed;
  inset: 0;  /* На весь экран */
  background: rgba(33, 37, 41, 0.9);  /* Затемнение фона */
  backdrop-filter: blur(5px);  /* Размытие */
}

Десктопное меню (min-width: 1200px)

Теперь добавляем улучшения для больших экранов через @media (min-width: 1200px).

Почему именно 1200px? Это стандартная точка перехода от планшета к десктопу. На экранах меньше 1200px будет мобильная версия, на больших — десктопная.

Изменение порядка элементов

@media (min-width: 1200px) {
  /* Скрываем гамбургер */
  .mobile-nav-toggle {
    display: none !important;
  }

  /* Новый порядок для десктопа */
  .header .logo {
    order: 1;
    margin-right: auto;  /* Отталкивает всё остальное вправо */
  }

  .header .navmenu {
    order: 2;
    margin-right: 30px;  /* Отступ до кнопки */
  }

  .header .btn-getstarted {
    order: 3;  /* Последней справа */
    margin: 0;
    font-size: 15px;
    padding: 8px 25px;
  }
}

Горизонтальное меню

.navmenu > ul {
  display: flex !important;  /* Горизонтальный ряд */
  position: static;
  padding: 0;
  margin: 0;
  background: transparent;
  box-shadow: none;
  align-items: center;
  flex-direction: row;
  overflow-y: visible;
}

Что изменилось?

  • display: flex — элементы выстраиваются в ряд;
  • position: static — убираем absolute позиционирование;
  • background: transparent — фон прозрачный (не нужен белый квадрат);
  • !important — перебивает мобильный display: none.

Dropdown меню — правильное позиционирование

Dropdown — выпадающее подменю. На десктопе открывается при наведении (hover), на мобиле — по клику.

CSS для dropdown (десктоп)

.navmenu .dropdown ul {
  /* Позиционирование */
  position: absolute;
  left: 14px;
  top: 130%;
  
  /* Скрыто по умолчанию */
  visibility: hidden;
  opacity: 0;
  
  /* КРИТИЧНО: убираем overflow! */
  overflow: visible !important;
  overflow-y: visible !important;
  max-height: none !important;
  
  /* Стили */
  background: var(--nav-dropdown-background-color);
  border-radius: 8px;
  box-shadow: 0px 5px 30px rgba(0, 0, 0, 0.12);
  min-width: 220px;
  padding: 10px 0;
  
  /* Анимация */
  transition: 0.3s;
  z-index: 99;
}

/* Показываем при наведении на родителя */
.navmenu .dropdown:hover > ul {
  opacity: 1;
  top: 100%;  /* Сразу под пунктом меню */
  visibility: visible;
}

Почему overflow: visible важен?

Если у dropdown будет overflow: auto или hidden, он обрежет вложенные меню (deep dropdown)!

Представьте коробку с крышкой. Если крышка закрыта (overflow: hidden), вы не увидите, что торчит из коробки. overflow: visible = крышка открыта, всё видно!

Deep Dropdown (3-й уровень)

/* Deep dropdown открывается справа */
.navmenu .dropdown .dropdown ul {
  top: 0;
  left: -90%;
  z-index: 100;  /* Поверх родителя (у того z-index: 99) */
}

.navmenu .dropdown .dropdown:hover > ul {
  left: -100%;  /* Полностью справа */
  visibility: visible;
  opacity: 1;
}

Как работает z-index. Представьте стопку бумаг на столе. Чем больше z-index, тем выше лист лежит. Deep dropdown имеет z-index: 100, обычный dropdown — 99. Поэтому deep всегда поверх!

Mega Menu на всю ширину контейнера

Mega Menu — широкое меню с несколькими колонками. Должно занимать всю ширину контейнера.

/* Родитель = static чтобы ul "видел" .container-fluid */
.navmenu .listing-dropdown {
  position: static;
}

/* Mega menu растягивается на всю ширину контейнера */
.navmenu .listing-dropdown ul {
  position: absolute;
  left: 0;   /* От левого края контейнера */
  right: 0;  /* До правого края контейнера */
  top: 100%;
  
  /* Layout */
  display: flex;
  flex-direction: row;
  gap: 20px;
  justify-content: space-between;
  
  /* Стили */
  padding: 20px;
  margin: 0;
  background: var(--nav-dropdown-background-color);
  border-radius: 8px;
  box-shadow: 0px 5px 30px rgba(0, 0, 0, 0.12);
  
  /* Скрыто */
  visibility: hidden;
  opacity: 0;
  transition: 0.3s;
  z-index: 99;
}

/* Показываем при hover */
.navmenu .listing-dropdown:hover > ul {
  opacity: 1;
  visibility: visible;
}

Как это работает — пошагово

Шаг 1: .container-fluid имеет position: relative (мы это сделали в базовых стилях). Он становится точкой отсчета.

Шаг 2: .listing-dropdown с position: static «игнорируется» при позиционировании. Как будто его нет.

Шаг 3: .listing-dropdown ul с position: absolute ищет ближайшего родителя с position: relative. Находит .container-fluid!

Шаг 4: left: 0; right: 0; говорит: «Растянись от левого до правого края родителя». И mega menu занимает всю ширину контейнера!

Почему НЕ calc(-50vw + 50%)?

Можно было написать сложно:

/* Сложное решение */
left: calc(-50vw + 50%);
right: calc(-50vw + 50%);
width: 100vw;

Но это:

  • Сложно для понимания;
  • Зависит от viewport (может уйти за экран);
  • Требует точного центрирования контейнера;
  • 3 строки вместо 2.

Наше решение:

  • Простое и понятное;
  • Зависит от контейнера, не viewport;
  • Работает всегда;
  • Всего 2 строки!

Sticky header через Intersection Observer

Sticky header — меню «прилипает» к верху при прокрутке вниз. Так пользователь всегда может открыть меню.

CSS для sticky

/* Класс добавляется через JavaScript */
.header.scrolled {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  padding: 12px 0;  /* Меньше чем обычно */
  background: rgba(255, 255, 255, 0.98);
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);  /* Размытие фона */
}

/* Компенсируем высоту fixed header */
body.header-fixed {
  padding-top: 80px;
}

JavaScript с Intersection Observer

Раньше для sticky использовали событие scroll. Но это медленно! Intersection Observer — современный API, который работает быстрее.

// Находим header
const header = document.getElementById('header');
const body = document.body;

// Создаем невидимый "сторожевой" элемент
const sentinel = document.createElement('div');
sentinel.style.position = 'absolute';
sentinel.style.top = '0';
sentinel.style.height = '100px';
sentinel.style.width = '100%';
sentinel.style.pointerEvents = 'none';
document.body.insertBefore(sentinel, document.body.firstChild);

// Наблюдатель следит за sentinel
const observer = new IntersectionObserver(([entry]) => {
  if (!entry.isIntersecting) {
    // Sentinel вышел из видимости = прокрутили вниз
    header.classList.add('scrolled');
    body.classList.add('header-fixed');
  } else {
    // Вернулись наверх
    header.classList.remove('scrolled');
    body.classList.remove('header-fixed');
  }
}, {
  threshold: 0,
  rootMargin: '0px'
});

// Запускаем наблюдение
observer.observe(sentinel);

Почему не просто scroll?

Старый способ:

/* Медленно */
window.addEventListener('scroll', () => {
  if (window.scrollY > 100) {
    header.classList.add('scrolled');
  }
}); // Срабатывает сотни раз при прокрутке!

Intersection Observer:

  • Срабатывает только при пересечении;
  • Не нагружает CPU;
  • Асинхронный (не блокирует страницу);
  • Современный стандарт.

JavaScript для интерактивности

Открытие мобильного меню

const mobileToggle = document.querySelector('.mobile-nav-toggle');
const body = document.body;

function toggleMobileMenu() {
  body.classList.toggle('mobile-nav-active');
  mobileToggle.classList.toggle('x-icon');
}

mobileToggle.addEventListener('click', toggleMobileMenu);

Что происходит:

  1. Находим кнопку гамбургера;
  2. При клике переключаем класс .mobile-nav-active на body;
  3. CSS видит этот класс и показывает меню;
  4. Иконка гамбургера меняется на крестик (класс .x-icon).

Dropdown на мобильных (по клику)

document.querySelectorAll('.dropdown > a').forEach(link => {
  link.addEventListener('click', function(e) {
    e.preventDefault();  // Не переходим по ссылке
    
    // Только для мобильных
    if (window.innerWidth < 1200) {
      this.parentNode.classList.toggle('active');
      this.nextElementSibling.classList.toggle('dropdown-active');
    }
  });
});

Закрытие меню при клике на ссылку

document.querySelectorAll('#navmenu a').forEach(link => {
  link.addEventListener('click', (e) => {
    // Не закрываем если это dropdown
    if (link.parentElement.classList.contains('dropdown') || 
        link.parentElement.classList.contains('listing-dropdown')) {
      return;
    }
    
    // Закрываем меню
    if (body.classList.contains('mobile-nav-active')) {
      toggleMobileMenu();
    }
  });
});

Финальный код и тестирование

Поздравляю! Вы создали профессиональное адаптивное меню. Теперь давайте соберем все вместе.

Полная структура файла

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Мой сайт</title>
  <style>
    /* Здесь весь CSS из урока */
  </style>
</head>
<body>

  <!-- Здесь HTML меню из урока -->

  <script>
    /* Здесь весь JavaScript из урока */
  </script>
</body>
</html>

[button href=»https://web-revenue.ru/demo/demo-bar/demo.html?data-title=Mobile-First%20Menu&data-url=https://web-revenue.ru/demo/wr-menu.html» hide_link=»yes» background_color=»#f79102″ color=»#000000″ size=»small» target=»_self»]Посмотреть / скачать меню [/button]

Проверка ошибок в консоли браузера

  1. Откройте файл в браузере
  2. Нажмите F12 (или Ctrl+Shift+I)
  3. Перейдите на вкладку Console
  4. Если есть красные сообщения — это ошибки, нужно исправить. В нашем случае:

Частые ошибки и решения

Проблема Причина Решение
Меню не появляется Забыли подключить JavaScript или опечатка в коде Проверьте консоль на ошибки, проверьте имена классов
Dropdown не работает Неправильный селектор в CSS Проверьте .dropdown:hover > ul
Header не прилипает JavaScript не находит элемент Убедитесь что id="header" есть в HTML
Стили не применяются Опечатка в классе или забыли точку Классы в CSS начинаются с точки: .header

Lighthouse проверка

Lighthouse — инструмент Google для оценки качества сайта.

  1. Откройте DevTools (F12);
  2. Вкладка Lighthouse;
  3. Выберите Mobile;
  4. Нажмите Analyze page load.

Ожидаемые результаты:

  • Performance: 95+ / 100 ✅
  • Accessibility: 100 / 100 ✅
  • Best Practices: 100 / 100 ✅
  • SEO: 100 / 100 ✅

Что делать если оценка ниже?

Lighthouse покажет конкретные проблемы. Обычно это:

  • Большие изображения без сжатия;
  • Отсутствие alt у картинок;
  • Медленный JavaScript;
  • Нет мета-тегов.
  • Не сжат код CSS / JS (сжать можно любыми онлайн компрессорами)

Заключение

Вы прошли полный путь от HTML-разметки до готового профессионального меню с использованием mobile-first подхода.

Что вы изучили:

  • Mobile-First CSS — базовые стили для мобильных, улучшения через min-width;
  • CSS переменные в :root — гибкая система цветов и шрифтов;
  • Flexbox и order — управление порядком элементов без изменения HTML;
  • Position: relative + absolute — правильное позиционирование для dropdown;
  • Mega Menu — простое решение через left: 0; right: 0; вместо сложных calc();
  • Overflow: visible — ключ к видимости deep dropdown;
  • Intersection Observer — современный API для sticky header;
  • Vanilla JavaScript — чистый код без зависимостей от библиотек.

В следующем уроке разберем еще одно интересное Flex меню, которое в некоторых случаях идеально для топ бара.

Автор

Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Exit mobile version