Bootstrap V4 Navbar Dropdown Hover

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Bootstrap V4 Navbar Dropdown Hover



I am a bit confused on the new bootstrap version since they changed dropdown menus to divs:


<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="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>



Do you guys have any idea to get a hover dropdown in the Dropdown link in that snippet without adding additional script code (only css and script from bootstrap)? I already saw the bootstrap css classes and I can't relate with the ones in bootstrap V3 (I accomplish this without adding jquery in V3).





I ran into a similar issue and came up with this solution stackoverflow.com/questions/47357143/…
– JacobLett
Nov 21 '17 at 22:00





Hover menu's are a bad idea and a bad UI/UX specially if you're planning for mobile
– Eonasdan
Mar 27 at 13:08




9 Answers
9



Simple, CSS only solution:


.dropdown:hover>.dropdown-menu
display: block;



When clicked, it will still get the class show toggled to it (and will remain open when no longer hovered).


show



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:


mouseenter


mouseleave


:hover



Complete, jQuery + CSS solution (touch untouched):


$('body').on('mouseenter mouseleave','.dropdown',function(e)
var _d=$(e.target).closest('.dropdown');_d.addClass('show');
setTimeout(function()
_d[_d.is(':hover')?'addClass':'removeClass']('show');
$('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
,300);
);


.dropdown:hover>.dropdown-menu
display: block;




$('body').on('mouseenter mouseleave','.dropdown',function(e)
var _d=$(e.target).closest('.dropdown');
_d.addClass('show');
setTimeout(function()
_d[_d.is(':hover')?'addClass':'removeClass']('show');
$('[data-toggle="dropdown"]', _d).attr('aria-expanded',_d.is(':hover'));
,300);
);


.dropdown:hover>.dropdown-menu
display: block;


<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="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>





Hi thanks for your asnwer, I accomplished that aswell, but if u click the dropmenu "stays". I wouldn't like to use something like "preventdefault", do you know some css trick (remove or add) to get the dropdown not staying on click?
– Exprove
Feb 12 '17 at 12:12





@Exprove There's is no clean CSS way of doing that. Because Bootstrap are using JavaSript. Bootstrap dropdowns do not work without js. Anyway, I took the time to look into how they do it and I came up with a script that doesn't touch touch behavior and provides what you asked for on desktops. Test it out, let me know if you find any trouble with it, I didn't, so far. Willing to improve it, if needed. Might come in handy for many if it's done right.
– Andrei Gheorghiu
Feb 12 '17 at 19:07



JavaSript


js





Everything works fine, but I really need to get the Dropdown link to work, if I press on the "Dropdown link" it should go to the example.com, I just can't accomplish that, I already had a close solution (like yours with jquery). Maybe if I override the click event with jquery might work, but it seems a sloppy solution.
– Exprove
Feb 12 '17 at 19:17






Use a split button. They are made exactly for that.
– Andrei Gheorghiu
Feb 12 '17 at 19:27



split button





Oh thanks, didn't know about that type of button :)
– Exprove
Feb 12 '17 at 19:30



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
/*Without this, clicking will make it sticky*/
pointer-events: none;





is pointer-events: none; does not added in bootstrap 4?
– Mohammad Ayoub Khan
Jul 20 at 23:09





This is handy and works great! Thanks.
– mdikici
Jul 26 at 8:39





this is best answer
– OzzyCzech
Jul 26 at 9:57





Thankyou OzzyCzech
– Mohammad Ayoub Khan
Jul 27 at 9:08



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.


.dropdown-menu


.show


.dropdown


.dropdown-menu


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);
);


<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>





You are the real mvp :) Thank you a lot!
– Mitca Vicentiu
Apr 18 at 21:56



Andrei's "complete" jQuery+CSS solution has the right intent, but it's verbose and still incomplete. Incomplete because it misses a few other changes meant to happen, and verbose because Bootstrap already provides the dropdown() method that we can use instead.



So this solution is just jQuery; no CSS required:


$('body').on('mouseover mouseout', '[data-toggle=dropdown]', function (e)
$(e.target).dropdown('toggle');
);





I tend to stay away from toggles on mouse events. If it only misfires once, the dropdown will stay open when not hovered and hide when hovered. Typically one can misfire an enter/leave pointer sequence by scribbling with the cursor over the element. But for proper testing, hover the element, change tab or window and go back to your window with the mouse in another position. Now hover the element.
– Andrei Gheorghiu
Jul 9 at 14:44


toggle





pureCSS solution which is described above is more accurate than this.
– Mohammad Ayoub Khan
Jul 20 at 23:13





@AndreiGheorghiu Oops my choice of mouse events wasn't the best; mouseover mouseout seems to fix that issue. Thanks, I'll edit my post.
– Lionel Wong
Jul 21 at 5:54


mouseover mouseout





@MohammadAyoubKhan A pure CSS solution misses various other behaviors though, which include firing events and toggling certain classes and attributes.
– Lionel Wong
Jul 21 at 6:08





You are right...
– Mohammad Ayoub Khan
Jul 21 at 14:43



I had already used and styled a navbar when I was requested to change it to a hover interaction instead, so ended up with this as a fix using jQuery.


function bootstrapHoverMenu (bp = 768)

// close all dropdowns that are open
$('body').click( function (e)
$('.dropdown-menu.show').removeClass('show');
);

// show dropdown for the link clicked
$('.nav-item').hover(function (e)
$('.dropdown-menu.show').removeClass('show');
if(( $(window).width() >= bp ))
$dd = $(this).find('.dropdown-menu');
$dd.addClass('show');

);

// get href for top level link if clicked and open
$('.dropdown').click(function (e)
if( $(window).width() < bp )
$('.dropdown-menu').css('display': 'none');

$href = $(this).find('.nav-link').attr('href');
window.open($href, '_self');
);


$(document).ready( function()
// when page ready run the fix
bootstrapHoverMenu();
);



Downside is mobile only has top level links.





i think pureCSS solution is best.
– Mohammad Ayoub Khan
Jul 20 at 23:13



I think this simply just work with bootstrap 4, i adding in inline but you always can bind event from script.


<a
onmouseover="$('#navbarDropdownMenuLink').dropdown('toggle')"
class="nav-link dropdown-toggle"
href="http://example.com"
id="navbarDropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
Dropdown link
</a>





you're going to stuff jquery script inside a plain javascript event handler inline?
– Eonasdan
Mar 27 at 13:07



<div style="width: 100%; overflow: scroll;"><table class="table table-striped table-bordered" style="font-size:12px">


<div style="width: 100%; overflow: scroll;"><table class="table table-striped table-bordered" style="font-size:12px">





Thank you for this code snippet, which may provide some immediate help. A proper explanation would greatly improve its educational value by showing why this is a good solution to the problem, and would make it more useful to future readers with similar, but not identical, questions. Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.
– GrumpyCrouton
Nov 7 '17 at 16:18





This is irrelevant to the question.
– Radmation
Jul 19 at 17:03



This solution switches on and off


<script>
$(document).ready(function()
// close all dropdowns that are open
$('body').click(function(e)
$('.nav-item.show').removeClass('show');
//$('.nav-item.clicked').removeClass('clicked');
$('.dropdown-menu.show').removeClass('show');
);

$('.nav-item').click( function(e)
$(this).addClass('clicked')
);

// show dropdown for the link clicked
$('.nav-item').hover(function(e)
if ($('.nav-item.show').length < 1)
$('.nav-item.clicked').removeClass('clicked');

if ($('.nav-item.clicked').length < 1)
$('.nav-item.show').removeClass('show');
$('.dropdown-menu.show').removeClass('show');
$dd = $(this).find('.dropdown-menu');
$dd.parent().addClass('show');
$dd.addClass('show');

);
);</script>



To disable the hover for lg sized collapse menus add


if(( $(window).width() >= 992 )) {



Bootstrap v4 Solution - jQuery based, but better than a pure css solution



This ensures that you can still follow top level link clicks and is
compatible with mobile.



This was built with desktop and mobile in mind. Fell free to wrap the jQuery with a conditional that checks if the window width is greater than 768px.


/** Dropdown on hover */
$(".nav-link.dropdown-toggle").hover( function ()
// Open up the dropdown
$(this).removeAttr('data-toggle'); // remove the data-toggle attribute so we can click and follow link
$(this).parent().addClass('show'); // add the class show to the li parent
$(this).next().addClass('show'); // add the class show to the dropdown div sibling
, function ()
// on mouseout check to see if hovering over the dropdown or the link still
var isDropdownHovered = $(this).next().filter(":hover").length; // check the dropdown for hover - returns true of false
var isThisHovered = $(this).filter(":hover").length; // check the top level item for hover
if(isDropdownHovered );
// Check the dropdown on hover
$(".dropdown-menu").hover( function ()
, function()
var isDropdownHovered = $(this).prev().filter(":hover").length; // check the dropdown for hover - returns true of false
var isThisHovered= $(this).filter(":hover").length; // check the top level item for hover
if(isDropdownHovered );


@media(min-width: 768px)
.dropdown-menu
margin-top: 0; // fixes closing on slow mouse transition







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard