Dropdown menu, stay when hovered over menu

I want to make dropdown menu, but it only works on hover, once I remove mouse from button it hides. BUT, when I get into that menu that it opened, I need it to keep that menu open. So I can get into sections, click on buttons etc…
What make my implementation different is that I use variable to show/hide dropdown menu, not sure how to make it different :expressionless: (my first time making this, trying to learn)

<div className="navbar-content">

                <div>
                    <a id="sports-link" href="#sports" onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>Sports</a>

                    {isDropdownVisible &&
                            <SportsDropDownMenu scrolled={scrolled} isDropdownVisible={isDropdownVisible} setDropdownVisible={setDropdownVisible} />
                    }

                    

                </div>

                <a href="#beliefs">Our beliefs</a>
                <a href="#economics">Economics</a>
                <a href="#FAQ">FAQ</a>
                <a href="#news">News</a>
                <a href="#join">Join now</a>
               
            </div>

And then in SportsDropDownMenu.jsx


const SportsDropDownMenu = ({ scrolled }) => {


    return (
        <>
            <div className={`sports-dropdown-menu ${scrolled ? 'scrolled' : ''} p-4`}  >
                <div>
                    <p className=" text-red_first font-semibold text-base">Our sports</p>
                </div>
            </div>
        </>
    )
}

.sports-dropdown-menu {
  position: absolute;
  top: 8.4rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  margin-left: 10px;

}




.sports-dropdown-menu.scrolled {
  position: absolute;

  top: 4.5rem;
  color: black;
  background-color: #F7FAFA;


  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
}

not sure, how else to implement this…

Usually you would use a nested list and when you hover the list parent you will show the nested UL (the dropdown) and in that way the list is always hovered while you navigate the nested element.

In your example your mouse code should go on the div that holds the anchor and the dropdown and not the button itself.

I have no idea why you would use JS instead of css hover (as in the menu you linked to) but the basis is the same.

Heres mostly your code but without the js or injected html so that you can see what structure you need to make this work. I also added the effect you mentioned.

As I said above I would use nested lists for a more semantic structure.

I would also advice against dynamically adding the dropdown content on request as that will make animation harder and makes the navigation pretty useless if js is disabled and of course makes it harder for the site to get indeed in search engines.

1 Like

well this works, but how can I have greater than “top: 100%;”, and not lose hover ?

This is closest I could get to it have hover. But I have that little of navbar height as well. I need it to be lower (opening menu), but then it won’t hover

But on other hand theworldgames, implements same way, it doesn’t have any more margin between button and dropdown menu

1
2
3

This is my css:

.navbar {
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
  background: rgba(255, 255, 255, 0.8);
  transition: all 0.3s ease;
  z-index: 1000;
  height: 165px;
}


// logo expanded 
.navbar .navbar-first-content {
  display: flex;
  margin-left: 15%;
  margin-right: 12%;
  margin-top: 2%;
  height: auto;
  justify-content: space-between;
  transition: opacity 0.3s ease;
}

.navbar-first-content.img {
  width: 200px;
  height: auto;
}


// links expanded
.navbar .navbar-content {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1rem;
  padding-bottom: 0px;
  transition: all 0.3s ease;
}



// ovo je sami navbar, kada je scrolled down
.navbar.scrolled {
  padding-top: 0;
  height: 50px;
}


// Hide the logo when scrolled 
.navbar.scrolled .navbar-first-content {
  display: none;
}


// content, kada je scrolled, down, onda ima taj svoj dizajn..
.navbar.scrolled .navbar-content {
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: 72px;
  padding: 1rem;
  transition: all 0.3s ease;
  background: rgba(255, 255, 255, 1);
}


.navbar-content a {
  width: 150px;
}



// ovo su linkovi unutar navbar 
.navbar a {
  text-decoration: none;
  color: white;
  font-size: 1rem;
  transition: all 0.3s ease;
  background-color: #AF2626;
  border: none;
  border-radius: 10px;
  padding: 0.5rem 1rem;
  margin: 0 0.5rem;
}


.navbar-first-content a {
  text-decoration: none;
  color: #716363;
  font-size: 1rem;
  transition: all 0.3s ease;
  background-color: rgba(113, 99, 99, 0);
  border: 1px solid #716363;
  border-radius: 10px;
}




.navbar-first-content a:hover {
  color: rgb(247, 250, 250) !important;
}







.navbar.scrolled a {
  text-decoration: none;
  color: black;
  font-size: 1rem;
  transition: all 0.3s ease;
  background-color: white;
}


.navbar a:hover {
  color: "#F7FAFA";
  background-color: #904242;
}

.navbar.scrolled a:hover {
  color: rgb(247, 250, 250)
}



 .sports-dropdown-menu {
  will-change: transform;
  position: absolute;
  margin-top: 15px;
  left: 0;
  right: 0;
  color: black;
  background-color: #f7fafa;
  white-space: nowrap;
  padding: 1rem;
  width: 75%;
  height: auto;
  margin-left: 9rem;
  border: 1px solid #f7fafa;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  opacity: 0;
  pointer-events: none;
  transition: ease-out 0.3s;
  transform: perspective(300px) rotateX(-90deg);
  transform-origin: 50% 0%;
}

.drop {
  padding: 1rem;
}

.drop:hover .sports-dropdown-menu {
  opacity: 1;
  pointer-events: initial;
  transform: perspective(300px) rotateX(0deg);
}




.sports-dropdown-menu.scrolled {
  position: absolute;
  top:  3rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  margin-left: 3rem ;
}


.beliefs-dropdown-menu {
  position: absolute;
  top: 8.4rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  margin-left: -10rem;
  width: 75%;
  height: auto;
}




.beliefs-dropdown-menu.scrolled {
  position: absolute;
  top: 4.5rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
}


.economics-dropdown-menu {
  position: absolute;
  top: 8.4rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
  margin-left: -20rem;
  width: 75%;
  height: auto;
}


.economics-dropdown-menu.scrolled {
  position: absolute;
  top: 4.5rem;
  color: black;
  background-color: #F7FAFA;
  border-bottom-left-radius: 2px;
  border-bottom-right-radius: 2px;
}



What you can do is that you use padding-top on the sports-drop-down element to push it further down the page but then you need to introduce an inner element and apply all the backgrounds to the inner element instead of the sports drop-down.

This gives the appearance of the menu being pushed down the page but you are still hovering the menu on its padding so it stays in place.

I see you have used a margin-top of 15px instead of top:100%. You can’t do that as it’s a magic number unlike top:100% which will always place the menu at the exact limit of the trigger element.

I’m on a mobile at the moment but will put up a new pen when I get back home.

Here you go: :wink:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.