I am a bit confused on the new bootstrap version since they changed dropdown menus to divs:
Solution 1:
Simple, CSS only solution:
.dropdown :hover >.dropdown-menu {
display : block;
}
Copy
When clicked, it will still get the class show
toggled to it (and will remain open when no longer hovered).
To get around this properly is to use events and properties reserved to pointer based devices: jQuery's mouseenter
, mouseleave
and :hover
. Should work smoothly, intuitively, while not interfering at all with how the dropdown works on touch based devices. Try it out, let me know if it works for you:
Complete jQuery solution (touch untouched):
Pre v4.1.2 solution (deprecated ):
$('body' ).on ('mouseenter mouseleave' ,'.dropdown' ,function (e ){
var _d=$(e.target ).closest ('.dropdown' );
if (e.type === 'mouseenter' )_d.addClass ('show' );
setTimeout (function ( ){
_d.toggleClass ('show' , _d.is (':hover' ));
$('[data-toggle="dropdown"]' , _d).attr ('aria-expanded' ,_d.is (':hover' ));
},300 );
});
Copy
$('body' ).on ('mouseenter mouseleave' ,'.dropdown' ,function (e ){
var _d=$(e.target ).closest ('.dropdown' );
if (e.type === 'mouseenter' )_d.addClass ('show' );
setTimeout (function ( ){
_d.toggleClass ('show' , _d.is (':hover' ));
$('[data-toggle="dropdown"]' , _d).attr ('aria-expanded' ,_d.is (':hover' ));
},300 );
});
$('.dropdown a' ).on ('click tap' , e => e.preventDefault ())
Copy
<link href ="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel ="stylesheet" />
<script src ="https://code.jquery.com/jquery-3.1.1.slim.min.js" > </script >
<script src ="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" > </script >
<script src ="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" > </script >
<nav class ="navbar navbar-toggleable-md navbar-light bg-faded" >
<button class ="navbar-toggler navbar-toggler-right" type ="button" data-toggle ="collapse" data-target ="#navbarNavDropdown" aria-controls ="navbarNavDropdown" aria-expanded ="false" aria-label ="Toggle navigation" >
<span class ="navbar-toggler-icon" > </span >
</button >
<a class ="navbar-brand" href > Navbar</a >
<div class ="collapse navbar-collapse" id ="navbarNavDropdown" >
<ul class ="navbar-nav" >
<li class ="nav-item active" >
<a class ="nav-link" href > Home <span class ="sr-only" > (current)</span > </a >
</li >
<li class ="nav-item" >
<a class ="nav-link" href > Features</a >
</li >
<li class ="nav-item" >
<a class ="nav-link" href > Pricing</a >
</li >
<li class ="nav-item dropdown" >
<a class ="nav-link dropdown-toggle" href id ="navbarDropdownMenuLink" data-toggle ="dropdown" aria-haspopup ="true" aria-expanded ="false" >
Dropdown link
</a >
<div class ="dropdown-menu" aria-labelledby ="navbarDropdownMenuLink" >
<a class ="dropdown-item" href > Action</a >
<a class ="dropdown-item" href > Another action</a >
<a class ="dropdown-item" href > Something else here</a >
</div >
</li >
</ul >
</div >
</nav >
Copy
v4.1.2 shiplist introduced this change to how dropdowns work, making the solution above no longer work.
Here's the up to date solution for having the dropdown open on hover in v4.1.2 and above:
function toggleDropdown (e) {
const _d = $(e.target ).closest ('.dropdown' ),
_m = $('.dropdown-menu' , _d);
setTimeout (function ( ){
const shouldOpen = e.type !== 'click' && _d.is (':hover' );
_m.toggleClass ('show' , shouldOpen);
_d.toggleClass ('show' , shouldOpen);
$('[data-toggle="dropdown"]' , _d).attr ('aria-expanded' , shouldOpen);
}, e.type === 'mouseleave' ? 300 : 0 );
}
$('body' )
.on ('mouseenter mouseleave' ,'.dropdown' ,toggleDropdown)
.on ('click' , '.dropdown-menu a' , toggleDropdown);
Copy
function toggleDropdown (e) {
const _d = $(e.target ).closest ('.dropdown' ),
_m = $('.dropdown-menu' , _d);
setTimeout (function ( ){
const shouldOpen = e.type !== 'click' && _d.is (':hover' );
_m.toggleClass ('show' , shouldOpen);
_d.toggleClass ('show' , shouldOpen);
$('[data-toggle="dropdown"]' , _d).attr ('aria-expanded' , shouldOpen);
}, e.type === 'mouseleave' ? 300 : 0 );
}
$('body' )
.on ('mouseenter mouseleave' ,'.dropdown' ,toggleDropdown)
.on ('click' , '.dropdown-menu a' , toggleDropdown);
$('.dropdown a' ).on ('click tap' , e => e.preventDefault ())
Copy
<link href ="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
<script src ="https://code.jquery.com/jquery-3.3.1.slim.min.js" > </script >
<script src ="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" > </script >
<script src ="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" > </script >
<nav class ="navbar navbar-expand-lg navbar-light bg-light" >
<a class ="navbar-brand" href ="#" > Navbar</a >
<button class ="navbar-toggler" type ="button" data-toggle ="collapse" data-target ="#navbarSupportedContent" aria-controls ="navbarSupportedContent" aria-expanded ="false" aria-label ="Toggle navigation" >
<span class ="navbar-toggler-icon" > </span >
</button >
<div class ="collapse navbar-collapse" id ="navbarSupportedContent" >
<ul class ="navbar-nav mr-auto" >
<li class ="nav-item active" >
<a class ="nav-link" href ="#" > Home <span class ="sr-only" > (current)</span > </a >
</li >
<li class ="nav-item" >
<a class ="nav-link" href ="#" > Link</a >
</li >
<li class ="nav-item dropdown" >
<a class ="nav-link dropdown-toggle" href ="#" id ="navbarDropdown" role ="button" data-toggle ="dropdown" aria-haspopup ="true" aria-expanded ="false" >
Dropdown
</a >
<div class ="dropdown-menu" aria-labelledby ="navbarDropdown" >
<a class ="dropdown-item" href ="#" > Action</a >
<a class ="dropdown-item" href ="#" > Another action</a >
<div class ="dropdown-divider" > </div >
<a class ="dropdown-item" href ="#" > Something else here</a >
</div >
</li >
<li class ="nav-item" >
<a class ="nav-link disabled" href ="#" > Disabled</a >
</li >
</ul >
<form class ="form-inline my-2 my-lg-0" >
<input class ="form-control mr-sm-2" type ="search" placeholder ="Search" aria-label ="Search" >
<button class ="btn btn-outline-success my-2 my-sm-0" type ="submit" > Search</button >
</form >
</div >
</nav >
Copy
Important note: If using the jQuery solution, it is important to remove the CSS one (or the dropdown won't close when .dropdown-toggle
is clicked or when an menu option is clicked).
Solution 2:
Just Add this simple css code in your style-sheet and you are ready to go.
.dropdown :hover > .dropdown-menu {
display : block;
}
.dropdown > .dropdown-toggle :active {
pointer-events : none;
}
Copy
Solution 3:
Bootstrap 4 CSS-only
None of the CSS only answers work entirely. Either the dropdown menu stays open after click, or there is a gap that makes the dropdown menu hide before you can reach the menu links to click.
Here's the simple CSS only solution:
.navbar-nav li :hover .dropdown-menu {
display : block;
}
Copy
Remove data-toggle=dropdown
from the HTML markup to prevent the dropdown staying open in click. Use mt-0
(margin-top:0) to eliminate the gap above the menu, and make it possible to hover the menu items.
Demo https://www.codeply.com/go/awyU7VTIJf
Complete Code:
.navbar-nav li:hover .dropdown-menu {
display: block;
}
<nav class ="navbar navbar-expand-lg navbar-light bg-light" >
..
<div class ="collapse navbar-collapse" id ="navbarSupportedContent" >
<ul class ="navbar-nav mr-auto" >
<li class ="nav-item dropdown" >
<a class ="nav-link dropdown-toggle" href ="#" id ="navbarDropdown" >
Dropdown
</a >
<div class ="dropdown-menu mt-0" aria-labelledby ="navbarDropdown" >
<a class ="dropdown-item" href ="#" > Action</a >
<a class ="dropdown-item" href ="#" > Another action</a >
<div class ="dropdown-divider" > </div >
<a class ="dropdown-item" href ="#" > Something else here</a >
</div >
</li >
</ul >
</div >
</nav >
Copy
Solution 4:
Andrei's "complete" jQuery+CSS solution has the right intent, but it's verbose and still incomplete. Incomplete because while it probably covers all the necessary DOM changes, it's missing the firing of custom events . Verbose because it's wheel-reinventing when Bootstrap already provides the dropdown() method , which does everything.
So the correct, DRY solution, which does not rely on the CSS hack often repeated among other answers, is just jQuery :
$('body' ).on ('mouseover mouseout' , '.dropdown' , function (e ) {
$(e.target ).dropdown ('toggle' );
});
Copy
Solution 5:
Bootstrap's functionality appears to have changed slightly since v4 has been released. The .dropdown-menu
item appears to also now get the .show
class in addition to the .dropdown
. I adapted Andrei's answer to also toggle the class on the .dropdown-menu
. Note that the CSS is no longer necessary and the HTML is the same except I updated the links to the current versions and the nav class changed to navbar-expand-md
.
$('body' ).on ('mouseenter mouseleave' , '.dropdown' , function (e ) {
var dropdown = $(e.target ).closest ('.dropdown' );
var menu = $('.dropdown-menu' , dropdown);
dropdown.addClass ('show' );
menu.addClass ('show' );
setTimeout (function ( ) {
dropdown[dropdown.is (':hover' ) ? 'addClass' : 'removeClass' ]('show' );
menu[dropdown.is (':hover' ) ? 'addClass' : 'removeClass' ]('show' );
}, 300 );
});
Copy
<link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity ="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin ="anonymous" >
<script src ="https://code.jquery.com/jquery-3.2.1.min.js" integrity ="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin ="anonymous" > </script >
<script src ="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity ="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin ="anonymous" > </script >
<nav class ="navbar navbar-expand-md navbar-light bg-faded" >
<button class ="navbar-toggler navbar-toggler-right" type ="button" data-toggle ="collapse" data-target ="#navbarNavDropdown" aria-controls ="navbarNavDropdown" aria-expanded ="false" aria-label ="Toggle navigation" >
<span class ="navbar-toggler-icon" > </span >
</button >
<a class ="navbar-brand" href ="#" > Navbar</a >
<div class ="collapse navbar-collapse" id ="navbarNavDropdown" >
<ul class ="navbar-nav" >
<li class ="nav-item active" >
<a class ="nav-link" href ="#" > Home <span class ="sr-only" > (current)</span > </a >
</li >
<li class ="nav-item" >
<a class ="nav-link" href ="#" > Features</a >
</li >
<li class ="nav-item" >
<a class ="nav-link" href ="#" > Pricing</a >
</li >
<li class ="nav-item dropdown" >
<a class ="nav-link dropdown-toggle" href ="http://example.com" id ="navbarDropdownMenuLink" data-toggle ="dropdown" aria-haspopup ="true" aria-expanded ="false" >
Dropdown link
</a >
<div class ="dropdown-menu" aria-labelledby ="navbarDropdownMenuLink" >
<a class ="dropdown-item" href ="#" > Action</a >
<a class ="dropdown-item" href ="#" > Another action</a >
<a class ="dropdown-item" href ="#" > Something else here</a >
</div >
</li >
</ul >
</div >
</nav >
Copy
Post a Comment for "How To Implement A Navbar Dropdown Hover In Bootstrap V4?"