Умное меню

02 Августа 2021 22:44

Умное меню на JS, которое автоматически по пунктам скрывается в выпадающее меню при изменении размера экрана.

Ссылка на Github.

HTML

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Menu</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&display=swap">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <nav class="nav">
        <ul class="visible-menu">
            <li><a href="#">Главная</a></li>
            <li><a href="#">О Компании</a></li>
            <li><a href="#">Продукция</a></li>
            <li><a href="#">Команда</a></li>
            <li><a href="#">Портфолио</a></li>
            <li><a href="#">Партнеры</a></li>
            <li><a href="#">Оплата</a></li>
            <li><a href="#">Доставка</a></li>
            <li><a href="#">Контакты</a></li>
        </ul>
        <button class="burger hidden">
            <svg width="30" height="40">
                <circle cx="15" cy="10" r="2" fill="#fff"></circle>
                <circle cx="15" cy="20" r="2" fill="#fff"></circle>
                <circle cx="15" cy="30" r="2" fill="#fff"></circle>
            </svg>
            <div class="burger-count"></div>
        </button>
        <ul class="hidden-menu"></ul>
    </nav>
    <script src="script.js"></script>
</body>
</html>

CSS

html {
    --navBg: #d4e7ee;
    --color: #29838c;
    --white: #ffffff;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: "Robot", sans-serif;
}
.nav {
    position: relative;
    display: flex;
    width: 100%;
    background: var(--navBg);
    max-width: 1200px;
    margin: 0 auto;
}
.nav ul {
    list-style: none;
}
.nav a {
    text-decoration: none;
}
.visible-menu {
    display: flex;
}
.visible-menu a {
    display: block;
    padding: 14px 20px;
    font-size: 18px;
    color: var(--color);
}
.visible-menu a:hover {
    background: var(--color);
    color: var(--white);
}
.burger {
    position: absolute;
    width: 60px;
    height: 100%;
    right: 0;
    padding: 0;
    border: 0;
    outline: none;
    background: var(--color);
    color: var(--white);
    cursor: pointer;
}
.burger svg {
    transition: .4s;
}
.burger.active svg {
    transform: rotate(90deg);
}
.burger-count {
    position: absolute;
    width: 26px;
    height: 26px;
    left: 0;
    top: 50%;
    text-align: center;
    background: var(--color);
    color: var(--white);
    font-size: 14px;
    border: 2px solid var(--white);
    line-height: 22px;
    border-radius: 50%;
    font-weight: bold;
    transform: translate(-50%, -50%);
}
.hidden-menu {
    position: fixed;
    right: 0;
    top: 50px;
    min-width: 250px;
    padding: 10px 0;
    background: var(--color);
    transition: .4s;
    transform: translateX(100%);
}
.hidden-menu.active {
    transform: translateX(0);
}
.hidden-menu a {
    display: block;
    padding: 10px 10px 10px 20px;
    color: var(--white);
    font-size: 18px;
}
.hidden-menu a:hover {
    background: var(--white);
    color: var(--color);
}
.nav .hidden {
    display: none;
}

JS

let nav = document.querySelector('.nav'),
vMenu = document.querySelector('.visible-menu'),
hMenu = document.querySelector('.hidden-menu'),
burger = document.querySelector('.burger'),
burgerCount = document.querySelector('.burger-count'),
breaks = [];

function updateNav() {
    //Получаем ширину всего меню
    let navWidth = burger.classList.contains('hidden') ? nav.offsetWidth : nav.offsetWidth - burger.offsetWidth;
    let vMenuWidth = vMenu.offsetWidth; //получили ширину видимого меню

    if(vMenuWidth > navWidth) {
        breaks.push(vMenuWidth);
        hMenu.prepend(vMenu.lastElementChild);
        burger.classList.remove('hidden');
        burgerCount.innerText = breaks.length;
        updateNav();
    }else{
        if(navWidth > breaks[breaks.length - 1]) {
            breaks.pop();
            vMenu.append(hMenu.firstElementChild);
            burgerCount.innerText = breaks.length;
        }
        if(breaks.length < 1) {
            burger.classList.add('hidden');
            hMenu.classList.remove('active');
        }
    }
}

burger.addEventListener('click', function(){
    hMenu.classList.toggle('active');
    burger.classList.toggle('active');
});

window.addEventListener('resize', updateNav);
document.addEventListener('DOMContentLoaded', updateNav);

Результат