Если без гамбургерного меню не обойтись, то начать стоит с выделения меню в отдельный контейнер и добавления кнопки‑тригера. Покажу на примере типового меню «в строку»:

<header class="header">
  <div class="logo">
    <a href="/">
      <img src="logo.svg" width="40" height="40">
    </a>
  </div>
  <nav class="nav">
    <ul>
      <li class="nav__item">
        <a href="/products/">Продукция</a>
      </li>
      <li class="nav__item">
        <a href="/services/">Услуги</a>
      </li>
      <li class="nav__item is__active">
        <a href="/blog/">Блог</a>
      </li>
      <li class="nav__item">
        <a href="/contacts/">Контакты</a>
      </li>
    </ul>
  </nav>
  <!-- aria-label подскажет смысл кнопки программам чтения с экрана -->
  <button class="hamburger" type="button" aria-label="Открыть меню">
   <span class="hamburger-box">
     <span class="hamburger-inner"></span>
   </span>
  </button>
</header>

Стилизуем кнопку. Возьмём уже готовые стили из библиотеки «гамбургерных» иконок на ЦСС:

<link rel="stylesheet" src="styles/hamburgers.css"></link>
<!-- ... -->
<header class="header">
  <div class="logo">
    <!-- ... -->
  </div>
  <nav class="nav">
    <!-- ... -->
  </nav>
  <button class="hamburger hamburger--squeeze" type="button">
   <!-- ... -->
  </button>
</header>
.header .hamburger {
  color: inherit; /* Чтобы иконка унаследовала цвет текста, а не была белой */
  line-height: 0; /* Чтобы иконка не увеличивала высоту меню */
}

Научим кнопку «кликаться». Пускай пока она меняет своё состояние и добавляет или убирает класс у меню:

<script>
  document
    .querySelectorAll('.hamburger')
    .forEach(button => {
     const nav = button
      .closest('.header')
      .querySelector('.nav')
     button.addEventListener('click', () => {
       button
         .classList
         .toggle('is-active')
       nav
        .classList
        .toggle('is-active')
     })
  })
</script>

Скроем кнопку на достаточно широких экранах. А на узких экранах разложим меню вертикально:

@media (width > 500px) {
  .header .hamburger {
    display: none;
  }
}
@media (width <= 500px) {
  .header {
    position: relative; /* Задаём контекст для позиционирования меню */
    grid-template-columns: min-content 1fr;
  }
  .nav {
    position: absolute; /* Меню позиционируем абсолютно, сразу после шапки поверх содержимого */
    top: 0;
    left: 0;
    width: 100%; /* Растягиваем меню на всю ширину экрана */
    padding: 92px 10px 20px; /* Добавляем настолько большой верхний падинг, чтобы меню встало точно под шапкой */
    margin: 0;
  }
  .nav ul {
     grid-auto-flow: row; /* Раскладываем меню рядами */
     grid-auto-rows: max-content;
     row-gap: 5px;
  }
  .nav__item a {
    padding: 0;
  }
}

Подключим меню к кнопке и добавим анимацию. Пусть меню приезжает сверху:

@media (width <= 500px) {
  .nav {
    position: absolute;
    transform: translateY(-100%); /* Прячем меню за верхнюю границу экрана */
    /* ... */
    transition: transform 75ms ease; /* Анимируем изменение позиции меню, синхронизировав с анимацией кнопки */
    transition-delay: 120ms;
    transition-timing-function: cubic-bezier(.215,.61,.355,1);
  }
  .nav.is-active {
    transform: translateY(0); /* Когда меню активно, ставим его под шапку */
  }
}

Появилась проблема с наползанием. Выезжающее меню перекрывает логотип. Поправим это, добавив слой, разделяющий выезжающее меню и логотип с кнопкой:

@media (width <= 500px) {
  .nav {
     /* ... */
     z-index: 1; /* Меню поедет на самом нижнем уровне */
     transform: translateY(calc(82px - 100%)); /* Спрячем меню под слой-разделитель */
  }
  .header::before {
    content: '';
    background: inherit;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 2; /* Слой-разделитель скроет меню, пока оно проезжает под шапкой */
  }
  .header .logo,
  .header .hamburger {
    position: relative;
    z-index: 3; /* Логотип и кнопка встанут на самом верху */
  }
}

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Веб‑разработка
Отправить
Поделиться
Запинить

Рекомендуем другие советы