htmlcsstwitter-bootstrapbootstrap-5

Bootstrap 5 - How to apply :hover effect on the top "Home" <li> 100% width when menu is collapsed


When the nav bar collapses for mobile devices I would like to have the :hover effect on the top menu option "Home" to apply across the top bar 100% wide. So the hover color is behind the toggler button.

Codepen: https://codepen.io/R-P-P/pen/zxOdyJb?editors=1100

.navbar .nav-link {
    padding: 10px 8px 12px 8px !important;
    font-size: 2rem;
    color: White;
}
 .navbar .nav-link:hover {
    color: red; 
}
#nav-home:hover {background-color: #ffffff;} 
<html lang="en">

<head>
<title>Home Hover</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"> 
</script>
</head>
<body>

    <nav class="navbar navbar-expand-xxl navbar-dark row g-0 m-0 p-0" style="background-color: rgb(150 150 150) !important;">
  
    <div class="container m-0 p-0">
       <ul class="navbar-nav me-auto">
        <li class="nav-item" id="nav-home"><a class="nav-link" href="">Home</a></li>
       </ul>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
       <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="mynavbar">
      <ul class="navbar-nav me-auto">
        <li class="nav-item"><a class="nav-link" href="">Link</a></li>
        <li class="nav-item"><a class="nav-link" href="">Link</a></li>
      </ul>  
    </div>
  </div>
</nav>
  
</body>
</html>


Solution

  • Update

    CSS

    After making a JavaScript answer I realized I can resolve the issues with CSS so now there's CSS solution as well. The biggest obstacle was that space between #nav-home🞶 and .navbar-toggler so once #nav-home was stretched out, there was no need to change the background of any ancestor.

    JavaScript

    The required hover behavior for #nav-home and .navbar-toggler with CSS is not worth the trouble (even if it's possible). Since they're both descendants of .container and .navbar it was possible to either have #nav-home's behavior or .navbar-toggler's behavior but not both because the ancestors' must be included in the selector so the space between #nav-home and .navbar-toggler was properly colored.

    The final solution was to give #mynavbar an inline style to protect it's yellow background from inheriting the purple hover background and then use JavaScript to delegate pointerEvents fired on #nav-home and .navbar-toggler then toggle the background of .box✳ from yellow to purple and vice versa. The width of #nav-home is stretched to the side of .navbar-toggler, now it feels more comfortable having the link being more than half the width of it's "sibling" links (I know they are not siblings but they certainly look related).

    🞶I realized that when I was referring to #nav-home I really meant it's parent ul.navbar-nav:first-of-type not catchy.

    ✳Added .box class to .container because Bootstrap pages usually have a top tier element with the .container class.

    CSS

    .navbar {
      background-color: rgb(251 152 5);
    }
    
    .navbar .nav-link {
      font: 500 19px "roboto", sans-serif;
      color: #fff;
    }
    
    .navbar .nav-link:hover {
      color: #fff;
    }
    
    .navbar-toggler-icon {
      background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important;
    }
    
    .navbar-toggler {
      padding-block: 6px !important;
      border-radius: 0 !important;
    }
    
    .navbar-toggler:focus {
      outline: 0 !important;
      box-shadow: none !important;
    }
    
    .nav-link {
      padding: 10px 8px 12px 8px !important;
    }
    
    #nav-link1:hover {
      background-color: #0200ac;
    }
    
    #nav-link2:hover {
      background-color: #05bd08;
    }
    
    @media only screen and (max-width: 1200px) {
      #nav-social-follow {
        text-align: left;
      }
    
      #nav-social-share {
        text-align: left;
      }
    }
    
    .flex-grow-1:hover,
    .flex-grow-1:hover + .navbar-toggler {
      background-color: #91008b;
    }
    
    .navbar .navbar-toggler:hover {
      background-color: #fb9805;
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Bootstrap Example</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
    </head>
    
    <body>
      <nav class="navbar navbar-expand-xxl row g-0 m-0 p-0">
        <div class="box d-flex container m-0 p-0">
          <ul class="flex-grow-1 navbar-nav me-auto">
            <li class="nav-item" id="nav-home"><a class="nav-link" href="">Home</a></li>
          </ul>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
          <span class="navbar-toggler-icon"></span>
        </button>
          <div class="collapse navbar-collapse" id="mynavbar">
            <ul class="navbar-nav me-auto">
              <li class="nav-item" id="nav-link1"><a class="nav-link" href="">Link1</a></li>
              <li class="nav-item" id="nav-link2"><a class="nav-link" href="">Link2</a></li>
            </ul>
          </div>
        </div>
      </nav>
    
    </body>
    
    </html>

    JavaScript

    const lnk = document.querySelector("#nav-home");
    const ico = document.querySelector(".navbar-toggler-icon");
    
    const hoverHome = event => {
      const tgt = event.target;
      let mod = tgt.matches("#nav-home");
      const box = document.querySelector(".box");
      let colors = ["#91008b", "#fb9805"];
      const action = event.type;
      
      switch (action) {
        case "pointermove":
          event.preventDefault();
          break;
        case "pointerenter":
          box.style.backgroundColor = mod ? colors[0] : colors[1];
          break;
        case "pointerleave":
          box.style.backgroundColor = colors[1];
          break;
      }
    };
    
    lnk.addEventListener("pointerenter", hoverHome);
    lnk.addEventListener("pointermove", hoverHome);
    lnk.addEventListener("pointerleave", hoverHome);
    
    ico.addEventListener("pointerenter", hoverHome);
    ico.addEventListener("pointermove", hoverHome);
    ico.addEventListener("pointerleave", hoverHome);
    .navbar {
      background-color: rgb(251 152 5);
    }
    
    .navbar .nav-link {
      font: 500 19px "roboto", sans-serif;
      color: #fff;
    }
    
    .navbar .nav-link:hover {
      color: #fff;
    }
    
    .navbar-toggler-icon {
      background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important;
    }
    
    
    .navbar-toggler:focus {
      outline: 0 !important;
      box-shadow: none !important;
    }
    
    .nav-link {
      padding: 10px 8px 12px 8px !important;
    }
    
    #nav-link1:hover {
      background-color: #0200ac;
    }
    
    #nav-link2:hover {
      background-color: #05bd08;
    }
    
    @media only screen and (max-width: 1200px) {
      #nav-social-follow {
        text-align: left;
      }
    
      #nav-social-share {
        text-align: left;
      }
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Bootstrap Example</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
    </head>
    
    <body>
      <nav class="navbar navbar-expand-xxl row g-0 m-0 p-0">
        <div class="box d-flex container m-0 p-0">
          <ul class="flex-grow-1 navbar-nav me-auto">
            <li class="nav-item" id="nav-home"><a class="nav-link" href="">Home</a></li>
          </ul>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
          <span class="navbar-toggler-icon"></span>
        </button>
          <div class="collapse navbar-collapse" id="mynavbar" style="background-color: #fb9805">
            <ul class="navbar-nav me-auto">
              <li class="nav-item" id="nav-link1"><a class="nav-link" href="">Link1</a></li>
              <li class="nav-item" id="nav-link2"><a class="nav-link" href="">Link2</a></li>
            </ul>
          </div>
        </div>
      </nav>
    
    </body>
    
    </html>