10

I am working on my first react-bootstrap website and I am noticing that the dropdown in navbar won't allow dropdown on hover.

I am wondering if there is a workaround. I tried adding some code to my CSS. demo - https://codesandbox.io/s/react-bootstrap-nav-active-link-5v5jq?fontsize=14&hidenavigation=1&theme=dark

/*MENU*/
.dropdown:hover {
  display: block;
}
/*END MENU*/

However, this did not work

This is the code.

import React from 'react';
import {Nav, Navbar, NavDropdown } from 'react-bootstrap';
import '../App.css';

function Header() {
    return (
            <Navbar bg="transparent" variant="dark" expand="lg">
            <Navbar.Brand href="#home" className="App-logo">AdStichr</Navbar.Brand>
            <Navbar.Toggle aria-controls="basic-navbar-nav" />
            <Navbar.Collapse id="basic-navbar-nav">
                <Nav className="ml-auto">
                <Nav.Link href="#home">Home</Nav.Link>
                <Nav.Link href="#link">Link</Nav.Link>
                <NavDropdown title="Dropdown" id="basic-nav-dropdown" alignRight>
                    <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
                    <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
                    <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
                    <NavDropdown.Divider />
                    <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
                </NavDropdown>
                </Nav>

            </Navbar.Collapse>
            </Navbar>
    )
}
export default Header;

even tried this

const Header = props => {
    const { location } = props;
    const [isOpen, updateIsOpen] = useState(false);
    return (
        <Navbar bg="transparent" variant="dark" expand="lg">
        <Navbar.Brand href="#home" className="App-logo">AdStichr</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="ml-auto" activeKey={location.pathname}>
            <Nav.Link href="/">Home</Nav.Link>
            <Nav.Link href="/advertisers">Advertisers</Nav.Link>
            <NavDropdown title="Publishers" id="basic-nav-dropdown" alignRight
             onMouseOver={() => updateIsOpen(true)}
             onFocus={() => updateIsOpen(true)}
             onMouseLeave={() => updateIsOpen(false)}
             onBlur={() => updateIsOpen(false)}
             toggle={() => updateIsOpen(!isOpen)}
             isOpen={isOpen}>
                <NavDropdown.Item href="/publishers/radio">Radio Stations</NavDropdown.Item>
                <NavDropdown.Divider />
                <NavDropdown.Item href="/publishers/podcasters">Audio Podcasters</NavDropdown.Item>
                <NavDropdown.Divider />
                <NavDropdown.Item href="/publishers/videopodcasters">Video Podcasters</NavDropdown.Item>
            </NavDropdown>
            <Nav.Link href="/case-studies">Case Studies</Nav.Link>
            <Nav.Link href="/contact">Contact</Nav.Link>
            </Nav>

        </Navbar.Collapse>
        </Navbar>
    );
  };
  const HeaderWithRouter = withRouter(Header);
  export default HeaderWithRouter;

But no success.

6
  • where is your dropdown class in the dom ?? Commented Feb 24, 2020 at 10:25
  • I thought I did not need to add it as a custom className as I was using a bootstrap class they already use. - or do I still need to add it? Commented Feb 24, 2020 at 10:30
  • @AkhilAravind I added className="dropdown" and it did not work Commented Feb 24, 2020 at 10:40
  • @ can you create a stackblitz demo and share link, i will check Commented Feb 24, 2020 at 10:41
  • Check if this helps you - github.com/reactstrap/reactstrap/issues/1088 Commented Feb 24, 2020 at 10:49

7 Answers 7

28
const [show, setShow] = useState(false);
const showDropdown = (e)=>{
    setShow(!show);
}
const hideDropdown = e => {
    setShow(false);
}
  <NavDropdown title="Dropdown" 
   id="collasible-nav-dropdown" 
   show={show}
   onMouseEnter={showDropdown} 
   onMouseLeave={hideDropdown}
   >

I Have Used This For Open Dropdown Menu On Hover in React Bootstrap.

2
  • 2
    Solution is greate but I believe it will only work for single dropdown. What if there is multiple dropdown on multiple menu item? Commented Jan 9, 2021 at 14:11
  • for multiple dropdown menu handeling you have to use custom hooks. Commented Jan 10, 2021 at 5:18
14

It doesn't render the dropdown menu when the NavDropdown component mounts for the first time.

CSS Solution: You just need to add renderMenuOnMount={true} on your NavDropdown element like this:

<NavDropdown title={name} id={name} renderMenuOnMount={true}>
...menu items...
</NavDropdown>

And in CSS:

.nav-item.dropdown:hover .dropdown-menu {
    display: block;
}
2
  • 1
    best answer - pure css, no react logic. good stuff Commented Feb 4, 2023 at 22:56
  • The accepted answer opens all Navdropdown menus at the same time. This is the best answer.
    – Ram Venkat
    Commented Mar 28, 2023 at 8:28
2

Use this code.

  const [showDropdown, setShowDropdown] = useState(false);
  return (
    <Dropdown
      onMouseLeave={() => setShowDropdown(false)}
      onMouseOver={() => setShowDropdown(true)}
      style={{ width: '166px' }}
    >
      <Dropdown.Toggle
        className="main-style"
        id="dropdown-basic"
      >
        Dropdown Button
      </Dropdown.Toggle>

      <Dropdown.Menu show={showDropdown}>
        <Dropdown.Item href="#/action-1">
          Action
        </Dropdown.Item>
        <Dropdown.Item href="#/action-2">
          Another action
        </Dropdown.Item>
        <Dropdown.Item href="#/action-3">
          Something else
        </Dropdown.Item>
      </Dropdown.Menu>
    </Dropdown>
  );

Codesandbox

0

Add the below code to the css, Checked in sandbox and worked fine. Let me know if you still have issue.

Check the sandbox snippet Here

.nav-item:hover .dropdown-menu{
  display:block!important
}
2
  • doesn't seem to work in current Chrome on Mac
    – llamerr
    Commented Jan 5, 2021 at 21:57
  • actually it sometimes works - your sandbox snippet not working at all, but code I have starts working after I first click on it. Before click, hover not working. But after click, it starts working on hover
    – llamerr
    Commented Jan 5, 2021 at 22:01
0

This should work:

.nav-item.dropdown:hover .dropdown-menu {
    display: block;
}
3
  • 3
    It does but I first have to click it and then next time I hover over it drops in down. Commented Feb 25, 2020 at 9:41
  • Any solution for this issue?
    – codebot
    Commented Feb 28, 2021 at 11:45
  • This is because dropdown menu is not rendered on mount by default. You can enable it by adding renderMenuOnMount as a prop in NavDropdown. It's a boolean so you need not mention true explicitly.
    – wahVinci
    Commented Aug 11, 2021 at 16:24
0

For multiple dropdowns I took a modified approach to Rubel's solution.

I created a NavHoverDropdown wrapper component that managed it's own isOpen state and renders children.

const NavHoverDropDown = (props) => {
const [dropdownOpen, setDropdownOpen] = useState(false);

const handleMouseOver = () => {
    setDropdownOpen(true);
}

const handleMouseOut = () => {
    setDropdownOpen(false);
}

return (
    <UncontrolledDropdown isOpen={dropdownOpen} onMouseOver={handleMouseOver} onMouseOut={handleMouseOut} nav inNavbar>
        {props.children}
    </UncontrolledDropdown>
) }

export default NavHoverDropDown

Then I went back to my NavMenu component and replaced all my UncontrolledDropdown's with my NavHoverDropdown. Contents of the dropdown remain the same.

<NavHoverDropdown >
    <DropdownToggle nav caret>
    Options
    </DropdownToggle>
    <DropdownMenu end>
        <DropdownItem>    
            <NavItem>
                <NavLink tag={Link} className="text-dark" to="/options/opton1">Option 1</NavLink>
            </NavItem>
        </DropdownItem>
        <DropdownItem>
                <NavLink tag={Link} className="text-dark" to="/options/option2">Option 2</NavLink>
        </DropdownItem>
    </DropdownMenu>
</NavHoverDropdown>
0

Fahad Munir's answer is excellent. Just 2 things I would like to mention:

  • Setting display: none can avoid menu being retained when user clicks it.

  • Some (mobile) devices cannot hover. Better use media query to avoid changing the original behaviour in that case.

/* One or more available input mechanisms can conveniently hover over elements. */
@media (any-hover: hover) {
  .nav-item.dropdown .dropdown-menu {
    display: none;
  }
  .nav-item.dropdown:hover .dropdown-menu {
    display: block;
  }
}

See: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-hover

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.