PiiMY
PiiMY

Reputation: 73

css/html dropdown menu on hover does not work for me

I'm trying to make a dropdown menu with html and css. I followed a ton of tutorials but they don't seem to work for me and I can not figure out why. I have an for a menubar that's always showing on the top of the screen and I want another to show when you hover the burgermenu on the left. This is my current code:

<body>
    <div class='menudiv'>
        <ul>
          <li><a><img class='dropdown' src='burgermenu.png' alt='OpenMenu' height='90px' width="90px" onmouseover="this.src='burgermenuwit.png'" onmouseout="this.src='burgermenu.png'"></a></li>
          <li style="float:right"><a href="#login"><img src='pp.png' alt='LogIn' height='90px' width="95px" onmouseover="this.src='ppwit.png'" onmouseout="this.src='pp.png'"></a></li>
        </ul>
    </div>
    <div class='logo'>
        <a href="#home"><img src='flowy_logo.png' alt='Logo' height='95px', widht='95px' onmouseover="this.src='flowy_logowit.png'" onmouseout="this.src='flowy_logo.png'">
    </div>
    <div class='menu2'>
        <ul>
            <li><a>Meten</a></li>
            <li><a>Huidige waardes</a></li>
            <li><a>Geschiedenis</a></li>
            <li><a>Contact</a></li>
        </ul>
    </div>
</body>
</html> 

and css:

.menudiv ul {
  font-family: "Georgia", "Times New Roman", "Serif";
  font-size: 25px;
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: rgb(102, 75, 255);
}

.menudiv ul li {
  float: left;
  cursor: pointer;
}

.menudiv ul li a {
  display: block;
  padding: 8px;
}

.logo img {
  position: relative;
  top: -105px;
  margin-left: auto;
  margin-right: auto;
  display: block;
}

.menu2 ul {
    position: relative;
    list-style-type: none;
    margin: 0;
    padding: 0;
    font-size: 30px;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    top: -100px;
}

.menu2 ul li a {
    display: block;
    width: 200px;
    background-color: rgb(102, 75, 255);
    padding-top: 10px;
    padding-bottom: 10px;
    padding-left: 10px;
    padding-right: 10px;
}

.menu2 ul li a:hover {
    color: white;
    cursor: pointer;
}

.menu2 {
    display: none;
}

.dropdown:hover .menu2 {
    display: block;
}

Can anybody tell me why it's not working?

Upvotes: 2

Views: 1077

Answers (3)

biberman
biberman

Reputation: 5767

You can achieve this by listening for the 'mouseover' event and changing the display style for menu2 to 'inline-block' (the ordinary 'block' takes the full width which is bad for 'mouseout'). You have to listen on both, the trigger ('Open Menu' link) and the menu itself.

To close the menu on 'mouseout' there is more code necessary then with a small inline onmouseout handler is possible:

  • First you have to check if the menu is hovered. Therefor you need a litle timeout before closing the menu from 'mouseout' on the trigger, so that the cursor has a chance to reach the menu.
  • Secondly you need to know that the 'mouseout' event is fired when changing to the next a or li tag in the menu. Since the 'mouseout' event is faster then the eventbubbling of the next 'mouseover' event from the a or li tag to the containing menu2, you need a second timeout for 'mouseout' on menu2 for checking if it is still hovered.
  • And third you have to check if the cursor is hovering again over the trigger when he has left the menu, otherwise the menu would remain closed and the 'mouseover' event on the trigger would not fire again. This can be checked in the second timeout check.
  • And fourth you need to wrap all that in an event handler that executes it not until the DOM is loaded. Otherwise the hover event listeners would have no effect because there would be no element to bind the listener to when the script is executed.

For the check if hovered use two variables that get true on 'mouseover' and false on 'mouseout'.

Here is a working example:

document.addEventListener('DOMContentLoaded', function() {
  const menu_trigger = document.querySelector('#menu-trigger');
  const menu2 = document.querySelector('.menu2');
  var trigger_hovered = false;
  var menu2_hovered = false;

  menu_trigger.addEventListener('mouseover', function() {
    trigger_hovered = true;
    menu2.style.display = 'inline-block';
  });

  menu_trigger.addEventListener('mouseout', function() {
    trigger_hovered = false;
    setTimeout(function() {
      if (menu2_hovered == false) {
        menu2.style.display = 'none';
      }
    }, 10);
  });

  menu2.addEventListener('mouseover', function() {
    menu2_hovered = true;
  });

  menu2.addEventListener('mouseout', function() {
    menu2_hovered = false;
    setTimeout(function() {
      if (menu2_hovered == false && trigger_hovered == false) {
        menu2.style.display = 'none';
      }
    }, 10);
  });
});
* {
  margin: 0;
  padding: 0;
}

.menudiv ul {
  display: flex;
  justify-content: space-between;
  overflow: hidden;
  width: 100vw;
  font-size: 25px;
  font-family: "Georgia", "Times New Roman", "Serif";
  list-style-type: none;
  background-color: rgb(102, 75, 255);
}

.menudiv ul li a {
  display: block;
  padding: 8px;
  cursor: pointer;
}

.menu2 {
  display: none;
}

.menu2 ul {
  list-style-type: none;
  font-size: 30px;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.menu2 ul li a {
  display: block;
  width: 200px;
  padding: 10px;
  background-color: rgb(102, 75, 255);
}

.menu2 ul li a:hover {
  color: white;
  cursor: pointer;
}
<div class='menudiv'>
  <ul>
    <li id="menu-trigger">
      <a>Open Menu</a>
    </li>
    <li><a href="#login">Login</a></li>
  </ul>
</div>
<div class='menu2'>
  <ul>
    <li><a>Meten</a></li>
    <li><a>Huidige waardes</a></li>
    <li><a>Geschiedenis</a></li>
    <li><a>Contact</a></li>
  </ul>
</div>

Upvotes: 1

Kundan
Kundan

Reputation: 11

bellow code will work only if there is no space between burgermenu button and menu2, I would suggest to add background color to menu2 div, so that you can see the div size

<script>
    var menu2 = document.querySelector('.menu2');
    document.querySelector('.dropdown')
    .addEventListener('mouseover', function() {
        menu2.style.display = 'block';
    });
    document.querySelector('.dropdown')
    .addEventListener('mouseout', function() {
        menu2.style.display = 'none';
    });
    menu2.addEventListener('mouseover', function() {
        menu2.style.display = 'block';
    });
    menu2.addEventListener('mouseout', function() {
        menu2.style.display = 'none';
    });
</script>

if there is some space in between menu button and menu, you can manage this by adding some time delay for display:none, I don't know this will be the good way or not, but it will work.

Upvotes: 0

vio
vio

Reputation: 177

Here is a JSFiddle with everything fixed: https://jsfiddle.net/dwauq9mL/

I had to change some things for my own convenience since I didn't have the images.

The problem: Since, menu2 is NOT a child of the the element on whose hover event you want it to display on, it will not work.

The solution: You need to put menu2 inside the li of the burger menu. You need to remove the .dropdown class from the burger image and add it to its parent li.

When you do this it is bound to mess the layout up. I wrote a JSFiddle for you (should be mentioned up) with everything fixed.

I recommend you not to use floats since they are deprecated. I removed the floats and used flexbox instead which is much better and recommended. I suggest you go learn Flexbox. I will link a few resources at the end of this answer.

CSS Tricks article on Flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Fun little game to learn Flexbox: https://flexboxfroggy.com/

Upvotes: 1

Related Questions