Круговое меню на HTML, CSS и JavaScript

Круговое меню на HTML, CSS и JavaScript

circle_menu_view

Дизайн веб-сайтов и веб-приложений полон интересных решений. К счастью, современные веб-технологии имеют достаточно ресурсов с помощью которых можно реализовать практически любой элемент. В этой статье хотелось бы рассказать вам, как создать круговое меню на HTML, CSS и JavaScript, которое будет всплывать и исчезать при нажатии на кнопку. С помощью этого меню, можно организовать красивую навигацию по страницам вашего сайта.

И так приступим.


Верстка HTML

Предлагаю создать файл index.html и описать вот такую структуру:

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
    <title>Circular menu</title>
  </head>
  <body>
   
  </body>
</html>

Обратите внимание что, файл со стилями мы подключили в шапке сайта.

Блок меню поместим внутрь блока <body>. Наше меню будет состоять из главного блока <nav> с классом class=’circularMenu’ и кнопок (ссылок) <a> с классом class=circularMenu-item помещенных в этот блок. Последняя кнопка с классом class=circularMenu-btn, будет открывать и закрывать меню, а так же содержать иконку помещенную в <span> с классом class=circularMenu-icon.

    <nav class="circularMenu">
      <a href="#" class="circularMenu-item">News</a>
      <a href="#" class="circularMenu-item">Blog</a>
      <a href="#" class="circularMenu-item">About</a>
      <a href="#" class="circularMenu-item">Products</a>
      <a href="#" class="circularMenu-item">Search</a>
      <a href="#" class="circularMenu-item">Contact</a>
      <a href="" class="circularMenu-btn">
        <span class="circularMenu-icon"></span>
      </a>
    </nav>

Стили CSS

Для выравнивания контента мы будем пользоваться Flexbox-версткой. Почитать подробнее о CSS Flexbox можно тут. Чтоб выровнять контент по центру, для родительского блока задается свойство ‘display: flex;, а для контента ‘align-items: center;’ и ‘justify-content: center;’. Так же мы установим свой шрифт текста, подключив его из Google Fonts.

@import url('https://fonts.googleapis.com/css?family=Roboto&amp;display=swap');
body {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Roboto', sans-serif;
  background-color: #394b64;
}

Зададим размеры для блока меню и относительное позиционирование:

.circularMenu {
  position: relative;
  width: 400px;
  height: 400px;
}

Давайте займемся теперь стилями пунктов меню и кнопки. Каждый пункт у нас будет flex-контейнером и контент (текст) в нём будет позиционироваться по центру. Для того, чтоб наши пункты имели форму окружности зададим свойство border-radius: 50%;. Так как, пункты меню будут исчезать и появляться при клике на кнопку, то зададим плавность появления, прописав свойство transition: 0.5s;

.circularMenu-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90px;
  height: 90px;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  text-decoration: none;
  color: #f7e4e0;
  background-color: #f14f5f;
  -webkit-transition: 0.5s;
  -moz-transition: 0.5s;
  -ms-transition: 0.5s;
  -o-transition: 0.5s;
  transition: 0.5s;
  outline: none;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  -o-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

Теперь зададим стили нашей кнопке. Так как, кнопка на вид такая же как и пункты меню, то стили повторяются.

.circularMenu-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  -o-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  width: 90px;
  height: 90px;
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  background-color: #f14f5f;
  outline: none;
}

С помощью псевдоэлементов .circularMenu-icon::after и .circularMenu-icon::before, изобразим иконку кнопки меню в виде знака «+». Так как наша иконка будет меняться при нажатии, зададим скорость изменения, с помощью всё того же свойства transition: 0.5s;

.circularMenu-icon,
.circularMenu-icon::before,
.circularMenu-icon::after {
  position: absolute;
  width: 45px;
  height: 6px;
  background-color: #f7e4e0;
  -webkit-transition: 0.5s;
  -moz-transition: 0.5s;
  -ms-transition: 0.5s;
  -o-transition: 0.5s;
  transition: 0.5s;
}

.circularMenu-icon {
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  -o-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  background-color: transparent;
}

.circularMenu-icon::before {
  content: '';
}

.circularMenu-icon::after {
  content: '';
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  transform: rotate(90deg);
}

С помощью JavaScript мы будем добавлять дополнительный класс к кнопке, с появлением которого у .circularMenu-icon::after и .circularMenu-icon::before будет меняться угол наклона и наша иконка преобразиться в знак «X».

.circularMenu-btn_active .circularMenu-icon::before {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

.circularMenu-btn_active .circularMenu-icon::after {
  -webkit-transform: rotate(-45deg);
  -moz-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  transform: rotate(-45deg);
}

Скрипт JavaScript

Теперь рассмотрим скрипт, с помощью которого пункты нашего меню будут исчезать и появляться при нажатии на кнопку. Предлагаю вам создать файл script.js и подключить его в конце файла index.html, вот так:

<script type="script/javascript" src="script.js"></script>
</body>
</html>

Давай те же разберём код самого файла.

С помощью JS находим на странице все блоки с классом ‘circularMenu’ и формируем массив из элементов этого блока. Далее, с помощью метода map(), перебираем массив элементов находим элементы с классом ‘circularMenu-item’ и ‘circularMenu-btn’, (это наши пункты меню и кнопка открытия меню).

Далее, определяем количество элементов меню и перебирая рассчитываем для каждого, с помощью методов и функций JS, координаты на которых они окажутся после клика на кнопку. Учитываем что, после активации меню к кнопке добавится класс ‘circularMenu-btn_active’, исходя из наличия которого иконка кнопки будет менять облик.

let menus = [...document.querySelectorAll('.circularMenu')];

menus.map((menu) => {
  let items = menu.querySelectorAll('.circularMenu-item');
  let btn = menu.querySelector('.circularMenu-btn');

  let active = false;

  const count = items.length;
  const arc = 2 * Math.PI * (1 / count);
  const radius = 30;

  btn.addEventListener('click', (e) => {
    e.preventDefault();
    active = !active;

    if (active) {
      btn.classList.add('circularMenu-btn_active');

      for (let i = 0; i < count; i++) {
        const angle = i * arc;
        const x = radius * Math.cos(angle);
        const y = radius * Math.sin(angle);

        items[i].style.left = 50 + x + '%';
        items[i].style.top = 50 + y + '%';
      }
    } else {
      btn.classList.remove('circularMenu-btn_active');

      for (let i = 0; i < count; i++) {
        items[i].removeAttribute('style');
      }
    }
  });
});


Вот так меню выглядит в работе.

Кликните на «+».

Вот и готово наше круговое меню на HTML, CSS и JavaScript

Дополнительно код можно посмотреть по ссылке.

Благодарю за внимание! Пишите мнения, замечания, вопросы в коментарии или с помощью формы обратной связи.