Nearly all the links on my navbar are dropdowns. I would like them to appear on hover for large screens, but on click for smaller screens. Is that possible? In my search for the answer, I came across this: Bootstrap Menu: Dropdown on Hover for Desktop Only. This doesn't work for me because I don't want the entire dropdown to be invisible on mobile; I'd only like it to be visible on click instead of on hover.
-
Since the click event is not viable in CSS (yet!), we cannot simply do this with CSS media queries. Instead, use JavaScript to grab the browsers UserAgent string to check against a regex that matches mobile, seen here:(http://stackoverflow.com/questions/11381673/javascript-solution-to-detect-mobile-browser) – Ben Sewards Jul 10 '14 at 20:00
-
1Please note that large screens can still be touch-only (tablets in landscape mode). This is why Bootstrap uses touch/click events exclusively. – Blazemonger Jul 10 '14 at 20:00
-
2You can use [Modernizr to detect touch capability](http://modernizr.com/docs/#touch) in the browser. [Consider this article](http://www.html5rocks.com/en/mobile/touchandmouse/), however – Blazemonger Jul 10 '14 at 20:03
8 Answers
EDITED The answer from @ouwen-huang is fine, but since jQuery is a dependency for bootstrap.js, you might as well do it the jQuery way by just adding all of the events that you want to attach to in quotes space-separated:
$('.dropdown').on('mouseenter mouseleave click tap', function() {
$(this).toggleClass("open");
});
The selectors are based on the standard Bootstrap markup, taken directly from the docs like so:
<li class="dropdown">
<a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Another action</a></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Something else here</a></li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="http://twitter.com/fat">Separated link</a></li>
</ul>
</li>
The point here is that if you are on a mouse-enabled device like a desktop that doesn't have touch capability, then the mouseenter/mouseleave events are fired and the menu is activated without a click. If the user is not on a device that fires a mouseenter/mouseleave event then the click or tap events are fired when the person taps the link and the click or tap handler handles the dropdown toggle.
EDITED for accuracy.

- 17,134
- 2
- 38
- 48
-
1This solution means that when you're on a desktop, if you hover over the item, the dropdown appears. If you click on it, the dropdown disappears. When you hover over another item, it appears, and the one you clicked on also appears. The menu quickly becomes a mess. – darylknight Jun 07 '15 at 14:52
-
1I was recently searching for this exact feature and found a plugin that smartly handles Bootstrap 3 dropdown menus on desktops and mobiles: https://github.com/CWSpear/bootstrap-hover-dropdown – Stu Dec 21 '15 at 15:23
The other 2 solutions work but don't keep the bootstrap styling. A simpler solution is to just add the 'open' class.
$('.dropdown').on('mouseenter mouseleave click tap', function() {
$(this).toggleClass("open");
});

- 101
- 1
- 1
You can use javascript events for this.
Using the mobile check library you can say
var domObject = document.querySelector('.myClassOrIDWhateverFloatsYourBoat');
if(mobile checked is true){
domObject.addEventListener('hover', function(){
$('.dropdown-toggle').dropdown(); // http://getbootstrap.com/javascript/
})
}else{
domObject.addEventListener('click', function(){
$('.dropdown-toggle').dropdown(); // http://getbootstrap.com/javascript/
})
}

- 1,037
- 2
- 9
- 25
After trying many plugins and solutions posted across stackoverflow I came up with rather simple code that:
- shows dropdown on hover by native Bootstrap class (so it cooperates well with button click)
- makes button link work when href is set
- keeps original behaviour on mobile devices
Simple version
$('ul.nav li.dropdown').hover(function() {
if (!$('.navbar-toggle').is(':visible')) {
$(this).toggleClass('open', true);
}
}, function() {
if (!$('.navbar-toggle').is(':visible')) {
$(this).toggleClass('open', false);
}
});
$('ul.nav li.dropdown a').click(function(){
if (!$('.navbar-toggle').is(':visible') && $(this).attr('href') != '#') {
$(this).toggleClass('open', false);
window.location = $(this).attr('href')
}
});
$('.navbar-toggle').is(':visible')
checks if we are currently in mobile view,
$(this).toggleClass('open', true)
adds or removes open
css class used by bootstrap,
and window.location = $(this).attr('href')
sends user to location set in the link href.
To add jQuery transitions we have to modify the script a little bit.
Modified version
visible = false;
function toggleDropdown(dropdown, delay, fade, state) {
if (state === undefined) visible = !visible
else visible = state
dropdown.children('.dropdown-menu').stop(true, true).delay(delay)[visible ? 'fadeIn' : 'fadeOut'](fade, function() {
dropdown.toggleClass('open', visible);
dropdown.children('.dropdown-toggle').attr('aria-expanded', visible);
$(this).css('display', '');
});
}
$('ul.nav li.dropdown').hover(function() {
if ($('.navbar-toggle').is(':visible')) return;
toggleDropdown($(this), 50, 100, true)
}, function() {
if ($('.navbar-toggle').is(':visible')) return;
toggleDropdown($(this), 400, 200, false)
});
$('ul.nav li.dropdown a').click(function(){
if ($('.navbar-toggle').is(':visible')) return;
if ($(this).attr('href') != '#') {
toggleDropdown($(this).parent(), 50, 100, false)
window.location = $(this).attr('href')
}
else {
toggleDropdown($(this).parent(), 50, 100)
}
});
visible
variable makes everything work nicely when re-hovering while animation is running.

- 3,186
- 1
- 19
- 22
// toggle dropdown on mouse hover, click and tap events
$('.dropdown').on('mouseenter mouseleave click tap touchstart', function(event) {
if (!$('.navbar-toggle').is(':visible')) {
$(this).dropdown('toggle');
}
});
Here is a slightly modified version of @jme11 's Answer based on the Bootstrap 3 documentation for Javascript Dropdowns. The advantage of using this method is that it enables the drop down to function exactly as intended without having to modify any classes and is therefore cleaner IMO.

- 81
- 6
-
1This does not work correctly especially if you have more than one dropdowns, you should use `$(this)` instead. – Razvan Grigore May 23 '17 at 16:11
A nice way to achieve this is to have hover enabled only when the menu is not collapsed.
$('.dropdown').on('mouseenter mouseleave click tap', function(event) {
if (!$('.navbar-toggle').is(':visible')) {
$(this).toggleClass("open");
}
});

- 1,466
- 2
- 15
- 25
This is simple and works well, but on mobile, if you open a submenu and click on the menu item to close, it doesn't close
$('.dropdown').on('mouseenter mouseleave click tap', function() {
$(this).toggleClass("open");
});
For Bootstrap 4 following code works.
$('.dropdown').on('mouseenter mouseleave click tap', function() {
$(this).toggleClass("show");
});

- 1,792
- 6
- 20
- 39