Adding an hamburger toggle to my website

Hello guys,

Currently, I’m in the process of learning how to build a website. I have built a website with HTML CSS Javascript. Right now I’m trying to learn how to make my website able to collapse into vertical navigation just like it’s shown on this website, I attached the link here so you can get an idea: https://mdbootstrap.com/snippets/jquery/mdbootstrap/911242#html-tab-view

[<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="styles.css" />
    <script src="script.js" defer></script>
  </head>
  <body>
    <header>
        <img class="logo" src="images/new logo.png" alt="logo">
        <div class="navbar__toggle" id="mobile-menu">
          <span class="bar"></span>
          <span class="bar"></span>
          <span class="bar"></span>
        </div>
        <nav class="nav">
        <div class="dropdown" data-dropdown>
        <button class="link" data-dropdown-button>Information</button>
        <div class="dropdown-menu information-grid">
          <div>
            <div class="dropdown-heading">Free Tutorials</div>
            <div class="dropdown-links">
              <a href="#" class="link">All</a>
              <a href="#" class="link">Latest</a>
              <a href="#" class="link">Popular</a>
            </div>
          </div>
          <div>
            <div class="dropdown-heading">Courses</div>
            <div class="dropdown-links">
              <a href="#" class="link">Javascript</a>
              <a href="#" class="link">CSS</a>
              <a href="#" class="link">React</a>
            </div>
          </div>
          <div>
            <div class="dropdown-heading">Blog</div>
            <div class="dropdown-links">
              <a href="#" class="link">All</a>
              <a href="#" class="link">Latest</a>
              <a href="#" class="link">Popular</a>
            </div>
          </div>
          <div>
            <div class="dropdown-heading">Other</div>
            <div class="dropdown-links">
              <a href="#" class="link">Twitter</a>
              <a href="#" class="link">Newsletter</a>
              <a href="#" class="link">Discord</a>
            </div>
          </div>
        </div>
      </div>
      <a href="#" class="link">Pricing</a>
      <div class="dropdown" data-dropdown> 
      <button class="link" data-dropdown-button>Login</button>
      <div class="dropdown-menu">
        <form class="login-form">
          <label for="email">Email</label>
          <input type="email" name="email" id="email">
          <label for="password">Password</label>
          <input type="password" name="email" id="email">
          <button type="submit">Login</button>
        </form>
      </div>
      </div>
      <button class="link" id="signup">Sign Up</button>
    </nav>
    </div>
  </header>
  <script>
    const toggle = document.getElementById('toggle');
    toggle.onclick = function(){
      toggle.classList.toggle('active');
    }
  </script>
  </body>
</html>](http://127.0.0.1:5503/index.html)

Do you have a question here, @Apache, or some aspect with which you need help?

Yes, I have posted my question in this thread if you look up.

body {
    margin: 0;
}
header {
  background-color: rgb(212, 209, 209);
  display: flex;
  flex-wrap: wrap; /* so navbar will go under logo on small smartphones */
  align-items: center;
  padding: 5px 4%;
  justify-content: space-between;

}

.logo {   
    margin-left: 20px;
    cursor: pointer;     
}

.nav {
    display: flex;
    gap: 1rem;
    padding: 0;
    align-items:center;
}

.link {
    background: none;
    border: none;
    text-decoration: none;
    color: #777;
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    padding: 0;   
}

.dropdown.active > .link,
.link:hover {
    color: black;
}

.link:last-child {
    margin: auto;
}

.dropdown {
    position: relative;
}

.dropdown-menu {
    position: absolute;
    right: 0;
    top: calc(150% + 0.25rem);
    background-color: white;
    padding: 0.75rem;
    border-radius: 0.25rem;
    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-10px);
    transition: opacity 150ms ease-in-out, transform 150ms ease-in-out;
}

.dropdown.active > .link + .dropdown-menu {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.information-grid {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    gap: 2rem;
}

.dropdown-links {
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.login-form > input {
    margin-bottom: 0.5rem;
}
#signup {
    
    padding: 10px 25px;
    background-color: rgba(0,136,169,1);
    border: none;
    border-radius: 50px;
    cursor: pointer;
    transition: all 0.3s ease 0s;   
}
document.addEventListener("click", e => {
    const isDropdownButton = e.target.matches("[data-dropdown-button]")
    if (!isDropdownButton && e.target.closest("[data-dropdown]") != null)
    return

    let currentDropdown
    if (isDropdownButton) {
        currentDropdown = e.target.closest("[data-dropdown]")
        currentDropdown.classList.toggle("active")
    }

    document.querySelectorAll("[data-dropdown].active").forEach(dropdown => {
        if (dropdown === currentDropdown) return
        dropdown.classList.remove("active")
    })
})

You have the toggle menu in place but you have called it something else other than #toggle so the JS needs to change to reflect that. You called it #mobile-menu.

You haven’t actually styled the hamburger so you need to grab the styles that create the hamburger from wherever you saw that code.

Once in place you would set it to display:none by default and then use a media query at the width required to show it. At that same point in the media query you would restyle the navigation so it sits under the header as usually required.

Here’s a basic start but as you are learning I am leaving you to fill the gaps.

#mobile-menu {
  display: none;
  height: 50px;
  width: 100px;
  background: red; /* just for testing - you need to find the correct css for this*/
}

/* I've used 800px as the trigger point but this needs to change based on the design */
@media screen and (max-width: 800px) {
  #mobile-menu {
    display: block;
  }
  .nav {
    display: none;
  }
  .active + .nav {
    display: block;
  }
  /* Now from here you need to style the way you want that dropdown to look on small screen.
  This would probably be using absolute positioning to show the menu over any other content*/
  
  /* e.g. just for starters*/
  header {
    position: relative;
  }
  .nav {
    position: absolute;
    left: 0;
    top: 100%;
  }
  /* now adjust all the styling for the list elements as required*/
  /* ??? */
}
 The js is changed to reflect the correct hamburger id.

const toggle = document.getElementById("mobile-menu");
toggle.onclick = function () {
  toggle.classList.toggle("active");
};

That’s a basic start for you to get it working so all you need to do now is style it all as required:)

Thanks a lot, buddy. I really appreciate your unlimited support. You’re right. This code is left from a previous project that I forgot to delete. But just like you mentioned, I will try to figure out the rest, so the learning process will be more effective. Can I get back to you if I get stuck?

How about the html, should I do any changes? Or should I keep it just the way it is currently?

You might be interested in the discussion in a similar thread where I discuss using nested lists for the html.

The last example shows the difference when using a nested list. It’s not wrong to use normal html but it’s much more extensible in the nested list approach and allows for unlimited nestings more easily. There’s no need to change if you are not following that approach.

Note there is no hamburger in that example as we were only discussing the basic menu.

Of course just post if you get stuck. I am away now until Sunday afternoon but someone else will hopefully jump in before then :slight_smile:

1 Like

Ok! Wonderful. Did you mean this discussion with OBXjuggler? I don’t think we have a similar project. I needed the html code so I can combine it with the css code that you provide me :hugs:

In that discussion I talk about nested lists and show an example of my preferred approach. The original html was similar to yours to makes a useful comparison

I didn’t intend you should copy the code but rather to understand the differences to aid with your learning :slight_smile:

1 Like

Aha! Ok! Now I understood your intention. You’re definitely right, copying and pasting is not very effective learning, instead getting tips and figuring out the solution is the much better way to learn programming.

3 Likes

Hello again dear Paul,

I came back again to you again with almost the same topic. I tried by myself making my website collapse into a vertical navigation menu with both dropdown buttons on the left side when I click on the hamburger button. But I could not accomplish this step. Could you please help me with this issue?? Down here you can see a link för the style that I’m working on in example 2 :point_down: :point_down:

index.html (2.5 KB)
styles.css (1.7 KB)
script.js (1.0 KB)

I’ve copied the new code into a codepen and basically added the code I gave you in the previous answer :slight_smile:

I’ve very roughly styled the dropdown when the hamburger is open just so you can see what to do. It isn’t meant to be a finished product as such. I wouldn’t actually use the same html as you for the dropdown but I explained that in an earlier post and I would have used a more structured list approach and a more consistent button usage.

However the demo serves as an example of how to implement the hamburger and start the styling for the dropdown. :slight_smile:

1 Like

I think bootstrap do it much batter what you want. Did you implement it?

1 Like

Ok! What do you mean by bootstrap?

Ok! Great. You’ve rebuilt almost the exact design I wanted it to be. Well, I did find a way to make a hamburger button. Although, I tried multiple times to move it to the right and the toggle too, but just couldn’t do that.

index.html (2.6 KB)
styles.css (2.4 KB)

Obs! Could you please tell me how can I post my code on CODEOEN just like the way do??

I’ve given you the code for that so not sure what you are asking?

The css you posted doesn’t have the media query in place and you aren’t hiding the button on full screen. With the media query in place the nav is hidden and the hamburger goes to the right automatically because the nav is moved into its new position.

You seemed to have grabbed some other code for the hamburger but I suggest you use mine and style it as you wish. The hamburger code in your example looks like a checkbox hack and there should be a whole load of css that goes with it.

I suggest you work from my working code.

He probably means the framework you keep mentioning! Bootstrap5 is the latest version. It has components that create hamburgers and dropdowns out of the box.

However I don’t believe you are at a level where you could utilise it properly yet as it has a steep learning curve and indeed once you know how to use it you could have done without it.

1 Like

Sign up for a free account on codepen and once you have your pen completed just paste the url to your code pen into your post here and it will automatically show an embedded pen. :slight_smile:

1 Like