javascripthtmlcssmobile-website

How to fix underline text hover going to far in responsive navbar


I am trying to make a responsive navbar that allows the navbar to collapse and open on mobile view, however when I try to open the navbar in mobile view and hover over the different links, my animation that puts a line under the text when hovering seems to be too long and doesn't stick the same length as the text. However works fine on normal desktop view.

image of the issue

const menuIcon = document.querySelector("#menu-icon");
const navbar = document.querySelector(".navbar");

menuIcon.addEventListener("click", () => {
    menuIcon.classList.toggle("bx-x");
    navbar.classList.toggle("active");
});
* {
  color: white;
  text-align: center;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}


.nav-link {
  font-weight: bold;
  text-decoration: none;
  color: white;
  padding: 20px 0px;
  margin: 0px 20px;
  display: inline-block;
  position: relative;
  opacity: 0.75;
}

.nav-link:hover {
  opacity: 1;
}

.nav-link::before {
  transition: 300ms;
  height: 3px;
  content: "";
  position: absolute;
  background-color: white;
}

.nav-link-ltr::before {
  width: 0%;
  bottom: 10px;
}

.nav-link-ltr:hover::before {
  width: 100%;
}


.lyrics {
  padding-top: 5%;
}



.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 20px 100px;
  background: rgba(255,255,255,.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
  backdrop-filter: blur(10px);
  border-bottom: 2px solid rgba(255,255,255, .2);
  position: sticky; top:0;
}

.navbar a {
  font-size: 18px;
  text-decoration: none;
  margin-left: 35px;
  transition: .3s;
}

.navbar a:hover {
  -webkit-text-stroke: 1px white;
}

.container {
  display: inline-block;
  margin: 0 auto;
  padding-top: 15%;
}

.text {
  font-size: 30px;
  font-weight: 900;
  letter-spacing: 5px;
  border-right: 5px solid;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  animation:
    typing 2s steps(17),
    cursor .4s step-end infinite alternate;
}

/* cursor blinking effect */
@keyframes cursor {
  50% { border-color: transparent; }
}

/* Typewriter effect */
@keyframes typing {
  from { width: 0 }
}

#menu-icon {
  font-size: 36px;
  color: white;
  display: none;
}

@media (max-width: 992px) {
  .header {
    padding: 1.25rem 4%;
  }
}

@media (max-width: 768px) {
  #menu-icon {
    display:block;
  }

  .navbar {
    position:fixed;
    top: 100%;
    left: 0;
    width: 100%;
    padding: .5rem 4%;
    background:rgba(255,255,255, .1);
    border-bottom: 2px solid rgba(255,255,255, .2);
    display: none;
  }

  .navbar.active {
    display: block;
  }

  .navbar a {
    display: block;
    margin: 1.5rem 0;
  }
}
 <link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
    
    <header class="header">
        <a href="#" class="logo">Matt</a>

        <i class="bx bx-menu" id="menu-icon"></i>

        <nav class="navbar">
            <a class="nav-link nav-link-ltr" href="#">Home</a>
            <a class="nav-link nav-link-ltr" href="#">About</a>
            <a class="nav-link nav-link-ltr" href="#">Contact</a>
            <a class="nav-link nav-link-ltr" href="#">Projects</a>
        </nav>
    </header>


    <div class="container">
        <p class="text">Hello, Matt Here.</p>
    </div>

    <div class="lyrics">
        <h3>Molly - Playboi Carti.</h3>
        <p>
            Look at these diamonds, they shinin' (Yeah)<br>
            Look at these bitches, they lyin' (Yeah)<br>
            Baby, these diamonds not Johnny (Yeah)<br>
            I just called up Avianne (Yeah)<br>
            I don't got no stylist (Yeah)<br>
            All my planes are privates<br>
            Perkys on the privates<br>
            We don't fuck with molly<br>
        </p>
    </div>


Solution

  • For your mobile view, you have set width: 100%; in the .navbar class and changed the a links from display: inline; (default) to display: block;. As a result, the links now also take up the 100% width of your navigation bar. The easiest and fastest solution is to add the width property to your links and set it to fit-content. Finally, to center the text again you also need to change the left/right margin of the links from 0 to auto.

    So change this part:

    @media (max-width: 768px) {
        .navbar a {
            display: block;
            margin: 1.5rem 0;
        }
    }
    

    To this:

    @media (max-width: 768px) {
        .navbar a {
            display: block;
            margin: 1.5rem auto;
            width: fit-content;
        }
    }
    

    Finally, here is a working snippet:

    const menuIcon = document.querySelector("#menu-icon");
    const navbar = document.querySelector(".navbar");
    
    menuIcon.addEventListener("click", () => {
        menuIcon.classList.toggle("bx-x");
        navbar.classList.toggle("active");
    });
    * {
      color: white;
      text-align: center;
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body{
      background: blue;
    }
    
    .nav-link {
      font-weight: bold;
      text-decoration: none;
      color: white;
      padding: 20px 0px;
      margin: 0px 20px;
      display: inline-block;
      position: relative;
      opacity: 0.75;
    }
    
    .nav-link:hover {
      opacity: 1;
    }
    
    .nav-link::before {
      transition: 300ms;
      height: 3px;
      content: "";
      position: absolute;
      background-color: white;
    }
    
    .nav-link-ltr::before {
      width: 0%;
      bottom: 10px;
    }
    
    .nav-link-ltr:hover::before {
      width: 100%;
    }
    
    
    .lyrics {
      padding-top: 5%;
    }
    
    
    
    .header {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      padding: 20px 100px;
      background: rgba(255,255,255,.1);
      display: flex;
      justify-content: space-between;
      align-items: center;
      backdrop-filter: blur(10px);
      border-bottom: 2px solid rgba(255,255,255, .2);
      position: sticky; top:0;
    }
    
    .navbar a {
      font-size: 18px;
      text-decoration: none;
      margin-left: 35px;
      transition: .3s;
    }
    
    .navbar a:hover {
      -webkit-text-stroke: 1px white;
    }
    
    .container {
      display: inline-block;
      margin: 0 auto;
      padding-top: 15%;
    }
    
    .text {
      font-size: 30px;
      font-weight: 900;
      letter-spacing: 5px;
      border-right: 5px solid;
      width: 100%;
      white-space: nowrap;
      overflow: hidden;
      animation:
        typing 2s steps(17),
        cursor .4s step-end infinite alternate;
    }
    
    /* cursor blinking effect */
    @keyframes cursor {
      50% { border-color: transparent; }
    }
    
    /* Typewriter effect */
    @keyframes typing {
      from { width: 0 }
    }
    
    #menu-icon {
      font-size: 36px;
      color: white;
      display: none;
    }
    
    @media (max-width: 992px) {
      .header {
        padding: 1.25rem 4%;
      }
    }
    
    @media (max-width: 768px) {
      #menu-icon {
        display:block;
      }
    
      .navbar {
        position:fixed;
        top: 100%;
        left: 0;
        width: 100%;
        padding: .5rem 4%;
        background:rgba(255,255,255, .1);
        border-bottom: 2px solid rgba(255,255,255, .2);
        display: none;
      }
    
      .navbar.active {
        display: block;
      }
    
      .navbar a {
        display: block;
        margin: 1.5rem auto;
        width: fit-content;
      }
    }
    <link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
    <header class="header">
            <a href="#" class="logo">Matt</a>
    
            <i class="bx bx-menu" id="menu-icon"></i>
    
            <nav class="navbar">
                <a class="nav-link nav-link-ltr" href="#">Home</a>
                <a class="nav-link nav-link-ltr" href="#">About</a>
                <a class="nav-link nav-link-ltr" href="#">Contact</a>
                <a class="nav-link nav-link-ltr" href="#">Projects</a>
            </nav>
        </header>
    
    
        <div class="container">
            <p class="text">Hello, Matt Here.</p>
        </div>
    
        <div class="lyrics">
            <h3>Molly - Playboi Carti.</h3>
            <p>
                Look at these diamonds, they shinin' (Yeah)<br>
                Look at these bitches, they lyin' (Yeah)<br>
                Baby, these diamonds not Johnny (Yeah)<br>
                I just called up Avianne (Yeah)<br>
                I don't got no stylist (Yeah)<br>
                All my planes are privates<br>
                Perkys on the privates<br>
                We don't fuck with molly<br>
            </p>
        </div>