Search code examples
htmlcssdrop-down-menunavbar

resizing my drop down nav to be the same size as its parent/button


I have been trying to create just a personal webpage. It has a navbar up the top i am mostly happy with except that i cannot get the drop down nav box (controlled with JS using event listeners) to be the same size as its parent element --> the button. All i want to do is have them be the same width. Here are snippets of the HTML, CSS and a screenshot of what it currently looks like.

The HTML Code

ul.navbar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  margin: 0;
  padding-inline: 40px;
  overflow: hidden;
  background-color: var(--light-grey);
  box-shadow: 0 5px 3px var(--dark-grey);
  font-size: var(--fs-lrg);
  font-weight: var(--fw-semibold);
}

ul.navbar li {
  flex: 1;
}

li.link > a {
  display: block;
  margin-inline: 5px;
  padding: 14px 16px;
  text-align: center;
  text-decoration: none;
  color: var(--dark);
  border: 2px solid var(--light-grey);
  border-radius: 8px;
  transition: 0.1s;
}

li.link > a:hover {
  background-color: var(--dark-grey);
  translate: 0 -2px;
  transition: 0.2s;
}

/*Drop Down Menu*/
.drop {
  display: none;
  position: absolute;
  z-index: 1;
  box-shadow: var(--shadow);
  background-color: var(--dark-grey);
  color: var(--dark);
  border-radius: 0 0 15px 15px;
}

.drop ul {
  width: 100%;
}

div.drop ul li {
  padding: 0.6rem;
  transition: 0.2s;
  width: 100%;
}

div.drop ul li:hover {
  background-color: var(--accent-orange);
  transition: 0.3s;
}

div.drop ul li:last-of-type {
  border-radius: 0 0 15px 15px;
}

div.drop ul li:hover:last-of-type {
  border-radius: 0 0 15px 15px;
}

.show {
  display: block;
}

.logo {
  height: 100px;
}

span.nav_divider::before {
  content: "";
  border: 1px solid var(--dark-grey);
}
<nav>
  <ul class="navbar">
    <img src="/Images/logo.png" class="logo" alt="logo">
    <li class="link"><a href="/index.html">Home</a></li>
    <span class="nav_divider"></span> <!-- this span styles the lines in between the links in the nav bar via a ::before psuedo class-->
    <li class="link" id="ms_access"> <!-- the list item containing the link and the drop down. this is the parent element.-->
      <a href="#">MS Access</a>
      <div class="drop" id="drop_msaccess" > <!--this is the drop down menu.-->
        <ul>
          <li><a href="/Pages/survey.html">Customer Survey</a></li>
          <li><a href="#">Territorian Passes</a></li>
          <li><a href="#">Distributor Tickets</a></li> 
          <li><a href="#">Reports</a></li>
          <li><a href="#">Feedback & Help</a></li>
        </ul>
      </div>
    </li>
    <span class="nav_divider"></span>
    <li class="link" id="re_express"> 
      <a href="#">Retail Express</a>
      <div class="drop" id="re_drop">
        <ul>
          <li><a href="#">Reporting</a></li>
          <li><a href="#">End of Day</a></li>
          <li><a href="#">End of Month</a></li>
        </ul>
      </div>
    </li>
    <span class="nav_divider"></span>
    <li class="link"><a href="#">Distributor Tickets</a></li>
    <img src="/Images/logo.png" alt="logo" class="logo">
  </ul>
</nav>

enter image description here

I have tried to give ul.navbar li a fixed width and then give the .drop width: inherit; but that didnt seem to work either. I realise I could try and calculate the width of the nav bar links with calc and then use that, but that seems very difficult and fiddly with all the other elements (pictures and spans) as well as their respective margins and paddings.

Please note I only do this for funsies and am still very green to coding in general so any help is appreciated and constructive critisicm is welcomed.

Thanks in advance


Solution

  • How you can adjust your CSS:

    1. Set the parent element (.link) to position: relative.
    2. Make sure the dropdown menu (.drop) is position: absolute and has width: 100%.

    Updated CSS:

    ul.navbar li {
      flex: 1;
      position: relative; /* Add this line */
    }
    
    .drop {
      display: none;
      position: absolute;
      top: 100%; /* Adjust as needed */
      left: 0;
      width: 100%; /* Make it the same width as the parent */
      z-index: 1;
      box-shadow: var(--shadow);
      background-color: var(--dark-grey);
      color: var(--dark);
      border-radius: 0 0 15px 15px;
    }
    

    JavaScript Event Listener: Ensure that the JavaScript for toggling the dropdown sets the class .show correctly.

    For example:

    document.querySelectorAll('.link').forEach(item => {
      item.addEventListener('click', event => {
        let dropdown = item.querySelector('.drop');
        if (dropdown.classList.contains('show')) {
          dropdown.classList.remove('show');
        } else {
          // close any open dropdowns
          document.querySelectorAll('.drop').forEach(drop =>
            drop.classList.remove('show'));
          // open the clicked dropdown
          dropdown.classList.add('show');
        }
      });
    });