Menu Underline effect 2

by davidxmartins

HTML

<header class="menu-big">

  <span class="logo">DAVID MARTINS</span>

  <div class="menu-container">
    <nav class="menu">
      <ul class="menu__list">
        <li><a href="#" class="menu__link">Work</a></li>
        <li><a href="#" class="menu__link">Services</a></li>
        <li><a href="#" class="menu__link">Journal</a></li>
        <li><a href="#" class="menu__link">Info</a></li>
      </ul>
    </nav>
  </div>

</header>

CSS

/* 
  ====================
  Menu Big
  ====================
  */
  
  /* Container */
  
  header.menu-big {
    margin: 0 auto;
    width: 95%;
    max-width: 1200px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: ;
    height: auto;
    box-sizing: border-box;
    padding: 30px 0 10px 0;
    z-index: 9;
    border-bottom: 1px solid #ccc;
}


/* Logo */

.logo {
    font-family: "DMfont_bold", sans-serif;
    font-size: 1.5em;
    padding-left: 1.2vw;
}

/* menu */

.menu-container {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: row;
}

.menu__list {
    --color-underline: black;
    --underline-width: 0;
    --underline-offset-x: 0;
    position: relative;
    display: inline-flex;
    margin: 0;
    padding: 0;
    list-style: none;
}

.menu__list::before {
content: "";
display: block;
position: absolute;
top: calc(100% + 8px); /* Underline effect aligns with the bottom of the header */
height: 3px;
width: var(--underline-width);
transform: translateX(var(--underline-offset-x));
background-color: black;
transition: transform 0.5s, width 0.5s;
border-radius: /* Optional, if you want rounded corners */;
}

.menu__link {
    display: block;
    padding: 0.5rem 1.2vw;
    color: black;
    text-decoration: none;
    font-family: "DMfont_medium", sans-serif;
    font-size: 1em;
    text-transform: uppercase;
    cursor: pointer;
    letter-spacing: .1rem;
}

JavaScript

// Underline effect for menu items

const menu = document.querySelector(".menu__list");
menu.addEventListener("mouseover", (event) => {
    if (event.target.classList.contains("menu__link")) {
        menu.style.setProperty(
            "--underline-width",
            `${event.target.offsetWidth}px`
        );
        menu.style.setProperty(
            "--underline-offset-x",
            `${event.target.offsetLeft}px`
        );
    }
});
menu.addEventListener("mouseleave", () =>
    menu.style.setProperty("--underline-width", "0")
);