В этой статье я покажу, как сделать несложное бургер-меню для сайта, которое в дальнейшем вы сможете стилизовать и улучшать по своему усмотрению. Наше меню адаптируется под мобильные устройства. При нажатии на иконку-бургер, слева направо выпадает меню. Анимируется сама иконка, из бургера она превращается в крестик. Также наша навигация всегда прижата к верхней стороне браузера, что удобно для пользователей.

Это изображение имеет пустой атрибут alt; его имя файла - bandicam_2022-03-15_15-36-22-217-1.gif

Скачать актуальный код бургер-меню для сайта можно здесь.

HTML-разметка бургер-меню

Теперь давайте разберем по порядку как это сделать. Начнем с разметки HTML.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="stylesheet" href="reset.css" />
    <link rel="stylesheet" href="style.css" />
    <title>Adaptive header for site</title>
  </head>
  <body>
    <nav class="navbar">
      <div class="container">
        <div class="navbar__wrap">
          <div class="hamb">
            <div class="hamb__field" id="hamb">
              <span class="bar"></span> <span class="bar"></span>
              <span class="bar"></span>
            </div>
          </div>
          <a href="#" class="logo" id="logo">Logo</a>
          <ul class="menu" id="menu">
            <li><a href="#">Home</a></li>
            <li><a href="#">Benefits</a></li>
            <li><a href="#">Prices</a></li>
            <li><a href="#">Blog</a></li>
            <li><a href="#">About us</a></li>
            <li><a href="#">Contact</a></li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="popup" id="popup"></div>
    <!-- Продолжение вашего кода .. -->
  </body>
</html>

Вся основная разметка меню содержится в элементе с классом navbar. Внутри мы располагаем контейнер с классом container для того, чтобы ограничить нашу навигацию по ширине 1000px и выровнять по центру.

Элемент navbar__wrap также является контейнером, но в нем мы уже выравниваем элементы внутри самого меню. Внутри меню содержится:

  • Сама кнопка бургер меню — div с классом hamb
  • Логотип — ссылка с классом logo
  • Элементы меню — список с классом menu

Последний div с классом popup — это всплывающее окно, которое будет появляться при нажатии на иконку бургер.

Как видите разметка довольна простая, теперь приходим к стилизации.

Стилизация бургер-меню

В начале стилизуем десктопное меню:

@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");

html {
  box-sizing: border-box;
  height: 100%;
}

*,
*::after,
*::before {
  box-sizing: inherit;
}

body {
  display: flex;
  flex-direction: column;
  font-family: "Roboto", sans-serif;
  font-size: 16px;
  line-height: 1.2;
  height: 100%;
}

.container {
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  height: 100%;
  padding: 0 15px;
}

.navbar {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 75px;
  background: #7a52b3;
}

.navbar__wrap {
  display: flex;
  justify-content: space-between;
  height: 100%;
}

.hamb {
  display: none;
}

.popup {
  display: none;
}

.logo {
  text-decoration: none;
  color: #fff;
  font-size: 20px;
  font-weight: bold;
  text-transform: uppercase;
  display: flex;
  align-items: center;
}

.menu > li > a {
  text-decoration: none;
}

.navbar__wrap .menu {
  display: flex;
}

.navbar__wrap .menu > li {
  display: flex;
  align-items: stretch;
}

.navbar__wrap .menu > li > a {
  display: flex;
  align-items: center;
  padding: 0 20px;
  color: rgba(255, 255, 255, 0.7);
}

.navbar__wrap .menu > li > a:hover {
  color: rgba(255, 255, 255, 1);
}

За ширину бургер меню отвечает элемент container, а конкретно его CSS-свойство max-width: 1000px. В элементе navbar мы задаем высоту height: 75px, а также делаем наше меню фиксированным благодаря свойству position: fixed.

В контейнере navbar__wrap мы распределяем все элементы меню (иконка, логотип, ссылки) равномерно, используя flexbox и его свойство justify-content: space-between.

По умолчанию элементы hamb и popup скрыты display: none. Свойство display мы будем менять в JavaScript.

Остальная часть CSS-кода не требует объяснения: там мы начиная с элемента logo стилизуем элементы нашего меню.

Делаем адаптацию под мобильную версию

Наше меню преобразуется в мобильную версию, когда ширина экрана становится меньше 1000px. В CSS это делается так:

@media (max-width: 1000px) {
  .navbar__wrap .menu {
    display: none;
  }

  .hamb {
    display: flex;
    align-items: center;
  }

  .hamb__field {
    padding: 10px 20px;
    cursor: pointer;
  }

  .bar {
    display: block;
    width: 30px;
    height: 3px;
    margin: 6px auto;
    background-color: #fff;
    transition: 0.2s;
  }

  .popup {
    position: fixed;
    top: 75px;
    left: -100%;
    width: 100%;
    height: 100%;
    background-color: #fff;
    z-index: 100;
    display: flex;
    transition: 0.3s;
  }

  .popup.open {
    left: 0;
  }

  .popup .menu {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: start;
    padding: 50px 0;
    overflow: auto;
  }

  .popup .menu > li {
    width: 100%;
  }

  .popup .menu > li > a {
    width: 100%;
    display: flex;
    justify-content: center;
    padding: 20px 0;
    font-size: 20px;
    font-weight: bold;
    color: #3f3f3f;
  }

  .popup .menu > li > a:hover {
    background-color: rgba(122, 82, 179, 0.1);
  }

  .hamb__field.active .bar:nth-child(2) {
    opacity: 0;
  }

  .hamb__field.active .bar:nth-child(1) {
    transform: translateY(8px) rotate(45deg);
  }

  .hamb__field.active .bar:nth-child(3) {
    transform: translateY(-8px) rotate(-45deg);
  }

  body.noscroll {
    overflow: hidden;
  }
}

Медиазапрос @media (max-width: 1000px) меняет стили элементов при ширине экрана меньше 1000px. Кстати, чтобы он срабатывал необходимо в HTML-разметку тега head добавить:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Для всплывающего окна popup мы задаем свойство left: -100%, чтобы скрыть его в левой части. При нажатии на иконку бургер к попапу добавится класс active и свойство left будет равным 0. То есть наш попап открывается слева направо. А чтобы он делал это плавно мы добавили к popup свойство transition: 0.3s.

Также при вызове popup мы блокируем прокрутку экрана у глобального тега body. Для этого добавляем ему класс body.noscroll со значением overflow: hidden.

Пишем скрипт для бургер-меню

Все подготовительные работы выполнены, осталось только «оживить» наше меню. Воспользуемся следующим кодом на JS:

const hamb = document.querySelector("#hamb");
const popup = document.querySelector("#popup");
const body = document.body;

// Клонируем меню, чтобы задать свои стили для мобильной версии
const menu = document.querySelector("#menu").cloneNode(1);

// При клике на иконку hamb вызываем ф-ию hambHandler
hamb.addEventListener("click", hambHandler);

// Выполняем действия при клике ..
function hambHandler(e) {
  e.preventDefault();
  // Переключаем стили элементов при клике
  popup.classList.toggle("open");
  hamb.classList.toggle("active");
  body.classList.toggle("noscroll");
  renderPopup();
}

// Здесь мы рендерим элементы в наш попап
function renderPopup() {
  popup.appendChild(menu);
}

// Код для закрытия меню при нажатии на ссылку
const links = Array.from(menu.children);

// Для каждого элемента меню при клике вызываем ф-ию
links.forEach((link) => {
  link.addEventListener("click", closeOnClick);
});

// Закрытие попапа при клике на меню
function closeOnClick() {
  popup.classList.remove("open");
  hamb.classList.remove("active");
  body.classList.remove("noscroll");
}

В начале мы поочередно считываем наши элементы, обращаясь к id каждого из них. Единственная особенность — в третьей строке мы клонируем menu, причем вместе со всеми его дочерними элементами. Для этого пользуемся методом cloneNode(1). Это делается для того, чтобы меню в десктопной и мобильной версии имели каждый свои стили.

Далее на иконку hamb навешиваем обработчик события на клик. При клике будем вызывать функцию hambHandler. В данной функции мы будем переключать стили у соответствующих элементов. Например: при первом нажатии на иконку для popup зададим класс active, таким образом наше всплывающее окно откроется плавно слева направо. В конце функции hambHandler мы вызовем другую функцию renderPopup, которая займется заполнением попапа.

После того, как пользователь нажмет на элемент меню, необходимо, чтобы всплывающее окно закрылось. Для этого, начиная с 27 строчки мы считаем все дочерние элементы меню. Для каждого из них навешиваем обработчик события при клике. После чего при клике выполним функцию closeOnClick, которая закроет всплывающее окно.


Warning: Undefined variable $aff_bottom_mark in /sites/codelab.pro/wp-content/themes/myTheme/dist/partials/post/post_base.php on line 81

Warning: Undefined variable $aff_bottom_info in /sites/codelab.pro/wp-content/themes/myTheme/dist/partials/post/post_base.php on line 85