How to open dropdown on hover in bootstrap 4 - html

Right now my navigation drop down can open on click.
I want it to open upon hover. How do I do this?

simply add following css
.dropdown:hover>.dropdown-menu {
display: block;
}
fiddle
.dropdown:hover>.dropdown-menu {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<ul class="navbar-nav">
<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>
</nav>

The css from Znaneswar works great but I would add this line as well.
.dropdown-menu {
margin: -0.125rem 0 0;
}
The dropdown is spaced 0.125rem away from the element that spawns the dropdown. So you'll have a hard time navigating from the link to the dropdown without it disappearing when you mouse over that gap.
And if you want the dropdown link to actually be a link as well, just remove this attribute from the a tag
data-toggle="dropdown"

Below css works fine
.dropdown:hover>.dropdown-menu {
display: block;
}
.dropdown>.dropdown-toggle:active {
pointer-events: none; // Add this, to prevent clicking dropdown's default click function
}

<div class="dropdown">
...
</div>
You could try this with jQuery:
$(".dropdown").hover(function(){
$(this).addClass("show");
});

I got this solution using Angular with ng-bootstrap and bootstratp:
CSS:
.dropdown:hover>.dropdown-menu {
display: block;}
HTML:
<li class="nav-item dropdown" ngbDropdown>
<a class="nav-link h5 dropdown-toggle" id="navbarDropdown" ngbDropdownToggle>
Parent</a>
<div ngbDropdownMenu class="dropdown-menu">
<a class="dropdown-item" href="#" ngbDropdownItem>Child1</a>
<a class="dropdown-item" href="#" ngbDropdownItem>Child2</a>
</div>
</li>
So, if don't use the CSS property, the dropdown will happens only when click on parent link.

While I appreciate the answers to this question, the answers given are seemingly not the best. This is because these answers are disregarding accessibility.
Notice that, when using only CSS to make the dropdown show on .nav-link hover, the aria-expanded parameter on the .nav-link element does not change to true.
You must use some JS then in order to have the full range of accessibility functionality.
Below is what I have come up with to combat this.
// header_scripts.js
$('body').on('hover', '.nav-item.dropdown', function() {
$(this).find('.dropdown-toggle').dropdown('toggle');
});
/* header.css */
.dropdown-menu {
margin: 0 0 0 0;
}
The above code should provide the same functionality that you are seeing in the other answers to this question, but with full accessibility concerns.
The CSS I gave is very general and has pretty low specificity so work with that as you see fit.

Related

Is there any way to change Bootstrap CSS icon on mouse hover

I have a Bootstrap dropdown in Angular. For dropdown menu I am using bootstrap css chevron-right icon. When user mouse hover, I want to change it to chevron-down icon.
This is my code
<style>
.dropdown:hover .dropdown-menu{
display: block;
}
.dropdown-menu{
margin-top: 0;
}
</style>
<div class="col-md-3 changeIcon">
<div class="nav-item dropdown">
<a href="#" data-toggle="dropdown">A-E
<i style="float: right;" class="bi bi-chevron-right"></i>
</a>
<div class="dropdown-menu">
Inbox
Sent
</div>
</div>
</div>
These css classes I tried but its not working
.changeIcon{
content: '\F285';
}
.changeIcon2:hover i::before{
content: "\uF356";
}
This is my UI, when user mouse hover, dropdown menus showing up but along with that I am not able to change right side icon
How can I do that ?
I have different solution for you.Here what i have try for you.
<div class="dropdown">
<button class="btn" type="button" data-bs-toggle="dropdown" aria-expanded="false">
A-E
<i class="bi bi-chevron-right icon"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
Apply following css to it
.btn.show .icon::before {
transform: rotate(90deg);
transition: transform 0.5s;
}
And if you want to rotate icon on dropdown hover then replace above css with this one.
.dropdown:hover .icon::before {
transform: rotate(90deg);
transition: transform 0.5s;
}
Hope you like it :)

Dropdown menu not showing the listed elements when hovered

For some reason this dropdown menu is not showing the listed elements when hovered. Using bootstrap.
Am I missing something here? Maybe it's something simple but I just cannot see it.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Services -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown">Services</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<h6 class="dropdown-header">Dropdown header</h6>
<a class="dropdown-item" href="#">Rewiring</a>
<a class="dropdown-item" href="#">Light Fixes</a>
<a class="dropdown-item" href="#">Showers</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Rewiring</a>
<a class="dropdown-item" href="#">Light Fixes</a>
<a class="dropdown-item" href="#">Showers</a>
</div>
</li>
In Bootstrap, dropdown runs by default on mouse click, if you want to show dropdown on mouse hover then you have to use css or js
I have used css
.dropdown:hover ul.dropdown-menu{ display: block; }
.dropdown:hover ul.dropdown-menu{ display: block; }
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.2/dist/js/bootstrap.bundle.min.js"></script>
<div class="dropdown">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown">
Services
</button>
<ul class="dropdown-menu">
<li><h6 class="dropdown-header">Dropdown header</h6></li>
<li><a class="dropdown-item" href="#">Rewiring</a></li>
<li><a class="dropdown-item" href="#">Light Fixes</a></li>
<li><a class="dropdown-item" href="#">Showers</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Rewiring</a></li>
<li><a class="dropdown-item" href="#">Light Fixes</a></li>
<li><a class="dropdown-item" href="#">Showers</a></li>
</ul>
</div>
More things to talk about here:
Opening dropdown in BS is done by Popper.js (which is not part of bootstrap.min.js). So in order to make dropdown working, you need to load Bootstrap JS via bundle, where Popper.js is included
https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js
Since you are using BS5, you need to change data-toggle="dropdown" to data-bs-toggle="dropdown". That is new markup from version 5 onwards.
As mentioned in another answer, opening dropdown on click (and not hover) is core part of BS philosophy (unfortunately). So in case you want to open submenu on hover, additional CSS has to be added.
Also be careful with the markup. It would be more clean to use the structure recommended by BS for the navigation (using <ul>, <li>, etc.)
change <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown">Services</a>
to
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown"> Dropdown button </button>
Change it to a button then it shoud work!!
I have found the solution:
This was the line causing trouble.
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown">Services</a>
I simply just added the following via Bootstrap:
aria-haspopup="true" aria-expanded="false"

How do I change the color of my dropdown text (Bootstrap)

I am new to bootstrap and I used a template to help me develop a nav bar for mu website, but I am confused on how to style the nav bar using a seperate CSS doc. Specifically, my toggle for the dropdown won't change color. I tried to set as many elements to color:black but they never actually effected the dropdown toggle text. The only way I could change the color was through the tag in html (I had to use the style:"color:black;") and still it wouldn't change back to white on hover like the other elements. Does anyone know what I'm doing wrong. I also wanted to add an onclick animation if anyone could help me with that as well. This is the template I used
<nav class="navbar navbar-expand-lg navbar-custom">
<a class="navbar-brand" href="#"> <span> Artemis Server Hosting </span> </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#basicExampleNav"
aria-controls="basicExampleNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="homepageNav">
<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="features.html">Features
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="pricing.html">Pricing
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">idk</a>
<div class="dropdown-menu dropdown-primary" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">yet</a>
</div>
</li>
</ul>
<img src="https://cdn4.iconfinder.com/data/icons/shopping-21/64/shopping-01-512.png" style="align:center;" height="3%" width="3%" href="cart.html">
</div>
</nav>
.navbar-brand {
color: white;
}
.navbar-brand:hover {
color: black;
}
.nav-link {
color: black;
}
.nav-link:hover {
background-color: black;
color: white;
border-radius: 8px;
}
So first of all, to make your last li to a cursor:pointer you have two options:
Either put href="#"into the <a> tag, like: <a href="#" class="nav-link dropdown-toggle" ...</a> or you use this property in the css: a:hover { cursor: pointer }
To color your dropdown black try this:
.dropdown-menu > a {
background-color:black;
color:white;
}
About your animation: please be a little more specific what sort of animation you want, like change the whole background color, show or hide something or whatever, but in general, if you use jQuery, you can do the following. The excample code shows an alert box
$(".navbar-toggler").on("click", function() {
alert("Hello");
});
Please note, that this code fires if someone clicks on any navbar-toggler button on your website - if you have multiple ones, all of the will fire it! If you only want to fire it when someone click a specific dropdown toggler, you should give it an id and do $("#your_id"). instead of $(".navbar-toggler").
if you don't use jQuery, the easiest would be to assign an onclick event to your button:
<button class="navbar-toggler" [...] onclick="doSomething()">
and then write your JavaScript function doSomething() that does whatever you want it to do.
If you tell me what animation you want to trigger I might be able to tell you a little bit more. (Also, as a side note: you should ask only one question per post. That's how Stack Overflow works and you'll get answers faster)

How to implement a Navbar Dropdown Hover in Bootstrap v4?

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).
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).
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);
});
$('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);
});
/* this is not needed, just prevents page reload when a dd link is clicked */
$('.dropdown a').on('click tap', e => e.preventDefault())
<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>
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);
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);
/* not needed, prevents page reload for SO example on menu link clicked */
$('.dropdown a').on('click tap', e => e.preventDefault())
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<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>
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).
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;
}
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;
}
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>
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');
});
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);
});
<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>
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.
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.
jQuery
/** 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 || isThisHovered) {
// still hovering over the link or the dropdown
} else {
// no longer hovering over either - lets remove the 'show' classes
$(this).attr('data-toggle', 'dropdown'); // put back the data-toggle attr
$(this).parent().removeClass('show');
$(this).next().removeClass('show');
}
});
// 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 || isThisHovered) {
// do nothing - hovering over the dropdown of the top level link
} else {
// get rid of the classes showing it
$(this).parent().removeClass('show');
$(this).removeClass('show');
}
});
CSS
#media(min-width: 768px) {
.dropdown-menu {
margin-top: 0; // fixes closing on slow mouse transition
}
}
Hoverable dropdown without losing functionality of popper.js for bootstrap 4 only
Javascript
$('.dropdown-hoverable').hover(function(){
$(this).children('[data-toggle="dropdown"]').click();
}, function(){
$(this).children('[data-toggle="dropdown"]').click();
});
HTML
<nav class="nav">
<li class="nav-item dropdown dropdown-hoverable">
<a class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#">Menu link</a>
<ul class="dropdown-menu">
</ul>
</li>
</nav>
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 )) {
CSS solutions not working properly on touch device
I found that any CSS solutions made the menu stay open on touch devices, they didn't collapse anymore.
So I read the article: https://www.brianshim.com/webtricks/drop-down-menus-on-ios-and-android/ (by Brian Shim)
Very useful! It states that a touch device always first checks the existence of a hover class on an element.
But: by using jQuery .show() you introduce a style attribute (display:block;) that makes the menu open up on first touch. Now the menu has opened without the bootstrap 'show' class. If a user chooses a link from the dropdown menu it works perfectly. But if a user decides to close the menu without using it he has to tap twice to close the menu: At the first tap the original bootstrap 'show' class gets attached so the menu opens up again, at the second tap the menu closes due to normal bootstrap behaviour (removal of 'show' class).
To prevent this I used the article: https://codeburst.io/the-only-way-to-detect-touch-with-javascript-7791a3346685 (by David Gilbertson)
He has some very handy ways of detecting touch or hover devices.
So, combined the two authors with a bit jQuery of my own:
$(window).one('mouseover', function(){
window.USER_CAN_HOVER = true;
if(USER_CAN_HOVER){
jQuery('#navbarNavDropdown ul li.dropdown').on("mouseover", function() {
var $parent = jQuery(this);
var $dropdown = $parent.children('ul');
$dropdown.show(200,function() {
$parent.mouseleave(function() {
var $this = jQuery(this);
$this.children('ul').fadeOut(200);
});
});
});
};
});
Check once if a device allows a hover event. If it does, introduce the possibility to hover using .show(). If the device doesn't allow a hover event, the .show() never gets introduced so you get natural bootstrap behaviour on touch device.
Be sure to remove any CSS regarding menu hover classes.
Took me three days :) so I hope it helps some of you.
1. Remove data-toggle="dropdown" attribute (so click will not open dropdown menu)
2. Add :hover pseudo-class to show dropdown-menu
.dropdown:hover .dropdown-menu {display: block;}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/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 dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" 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>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
</ul>
</div>
</nav>
I couldn't find here the full solution. So, it's my one which works with Bootstrap v4.4.1 and has the next benefits:
A click on the dropdown-toggle works as a normal nav link.
Supports any nesting level of dropdown menus.
Bootstrap 4 {show/shown/hide/hidden}.bs.dropdown events work well.
// Toggles a B4 dropdown-menu to a given state.
const toggleDropdownElement = ($dropdown, shouldOpen = false) => {
const $dropdownToggle = $dropdown.children('[data-toggle="dropdown"], a');
const $dropdownMenu = $dropdown.children('.dropdown-menu');
// Change the dropdown menu. It's similar to B4 Dropdown.show()/.hide(), see /bootstrap/js/src/dropdown.js.
if (shouldOpen) {
$dropdown.trigger('show.bs.dropdown');
$dropdownToggle.attr('aria-expanded', true).focus();
$dropdownMenu.addClass('show');
$dropdown.addClass('show').trigger($.Event('shown.bs.dropdown', $dropdownMenu[0]));
} else {
$dropdown.trigger('hide.bs.dropdown');
$dropdownToggle.attr('aria-expanded', false);
$dropdownMenu.removeClass('show');
$dropdown.removeClass('show').trigger($.Event('hidden.bs.dropdown', $dropdownMenu[0]));
}
};
// Toggles a B4 dropdown-menu with any nesting level.
const toggleDropdown = (event) => {
const $dropdown = $(event.target).closest('.dropdown');
const $parentDropdownMenu = $dropdown.closest('.dropdown-menu');
const shouldOpen = event.type !== 'click' && $dropdown.is(':hover');
// If the dropdown was closed already, break the 'mouseleave' event cascade.
if (!shouldOpen && !$dropdown.hasClass('show')) return;
// Change the current dropdown menu (last nested).
toggleDropdownElement($dropdown, shouldOpen);
// We have to close the dropdown menu tree if it was a click or the menu was leave at all.
if (event.type === 'click' || $parentDropdownMenu.length && !$parentDropdownMenu.is(':hover')) {
$dropdown.parents('.dropdown').each((index, element) => {
toggleDropdownElement($(element), false);
});
}
};
if (viewport && viewport.is('>=xl')) {
$('body')
.on('mouseenter mouseleave', '.dropdown', toggleDropdown)
.on('click', '.dropdown-menu a', toggleDropdown);
// Disable the default B4's click. Other words, change a dropdown-toggle to a normal nav link.
$(document).off('click.bs.dropdown', '[data-toggle="dropdown"]');
$(document).off('click.bs.dropdown.data-api', '[data-toggle="dropdown"]'); // Not sure about it.
}
If you don't use ES6 just change arrow functions to the old function style.
Thanks, #tao for your example, it was helpful for me.
Code related links: B4 Dropdown Events, viewport (Responsive Bootstrap Toolkit), WP Bootstrap Navwalker.
all I am working with bootstrap 5, above solutions were looking big I just removed data-bs-toggle='dropdown'because it was blocking the parent link to navigate and toggling script to open the dropdown on click.
And added CSS
.dropdown:hover > .dropdown-menu {
display: block;
margin-top: 0;
// removes the gap so it doesn't close ;
}
Works fine for me
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>
I use bootstrap 4.0.0
since we want to simulate .show to hover event, it simply easy. just add all styles in .dropdown.show .dropdown-menu to the :hover. like this:
.dropdown:hover>.dropdown-menu {
opacity: 1;
visibility: visible;
transform: translate3d(0px, 0px, 0px);
}
$('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);
});
/* this is not needed, just prevents page reload when a dd link is clicked */
$('.dropdown a').on('click tap', e => e.preventDefault())
<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>
CSS and Desktop only solution
#media (min-width: 992px) {
.dropdown:hover>.dropdown-menu {
display: block;
}
}
Neither of the top solutions worked for me.
This works perfectly, keeps submenus open while browsing, add uses the native Bootstrap javascript.
// Mouse over
$('body').on('mouseover', '.dropdown', function(e) {
$(this).children('.dropdown-toggle').dropdown('show');
});
// Mouse leave
$('body').on('mouseleave', '.dropdown', function(e) {
$(this).children('.dropdown-toggle').dropdown('hide');
});
Google brought me here but... The examples provided work if the dropdown menu is overlaping (at least by 1px) with its parent when show. If not, it loses focus and nothing works as intended.
Here is a working solution with jQuery and Bootstrap 4.5.2 :
$('li.nav-item').mouseenter(function (e) {
e.stopImmediatePropagation();
if ($(this).hasClass('dropdown')) {
// target element containing dropdowns, show it
$(this).addClass('show');
$(this).find('.dropdown-menu').addClass('show');
// Close dropdown on mouseleave
$('.dropdown-menu').mouseleave(function (e) {
e.stopImmediatePropagation();
$(this).removeClass('show');
});
// If you have a prenav above, this clears open dropdowns (since you probably will hover the nav-item going up and it will reopen its dropdown otherwise)
$('#prenav').off().mouseenter(function (e) {
e.stopImmediatePropagation();
$('.dropdown-menu').removeClass('show');
});
} else {
// unset open dropdowns if hover is on simple nav element
$('.dropdown-menu').removeClass('show');
}
});
just use Tao's CSS code:
.dropdown:hover > .dropdown-menu {
display: block;
}
and remove the 2px-gap between the .dropdown-toggle and the .dropdown-menu by setting its top-margin to zero:
.dropdown-menu { margin-top: 0!important }
(June 2020) I found this solution and I thought I should post it here:
Bootstrap version: 4.3.1
The CSS part:
.navbar .nav-item:not(:last-child) {
margin-right: 35px;
}
.dropdown-toggle::after {
transition: transform 0.15s linear;
}
.show.dropdown .dropdown-toggle::after {
transform: translateY(3px);
}
.dropdown-menu {
margin-top: 0;
}
The jQuery part:
const $dropdown = $(".dropdown");
const $dropdownToggle = $(".dropdown-toggle");
const $dropdownMenu = $(".dropdown-menu");
const showClass = "show";
$(window).on("load resize", function() {
if (this.matchMedia("(min-width: 768px)").matches) {
$dropdown.hover(
function() {
const $this = $(this);
$this.addClass(showClass);
$this.find($dropdownToggle).attr("aria-expanded", "true");
$this.children($dropdownMenu).addClass(showClass);
},
function() {
const $this = $(this);
$this.removeClass(showClass);
$this.find($dropdownToggle).attr("aria-expanded", "false");
$this.children($dropdownMenu).removeClass(showClass);
}
);
} else {
$dropdown.off("mouseenter mouseleave");
}
});
Source: https://webdesign.tutsplus.com/tutorials/how-to-make-the-bootstrap-navbar-dropdown-work-on-hover--cms-33840
<div style="width: 100%; overflow: scroll;"><table class="table table-striped table-bordered" style="font-size:12px">

Menu Toggle Element

I'm reworking a WHMCS menu to be responsive and touch sensitive. Everything is fine except for one thing. I can't get the proper elements to display/toggle properly.
What the jQuery script does is add "open" class to parent element onclick. So
<div id="menu-icon"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu</a></div>
Becomes:
<div id="menu-icon" class="open"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu</a></div>
When the "Menu" link is clicked.
I need the "#nav" to "display:none" by default, and "display:block" when Menu is clicked. I can't quite capture it via CSS.
My HTML
<nav id="nav-wrap">
<div id="menu-icon"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu</a></div>
<ul id="nav">
My CSS
#nav-wrap #nav {
display: none;
}
#nav-wrap #menu-icon.open #nav {
display: block;
}
With the code above, I can hide the #nav by default, but that's it. Any pointers on how to capture #nav?
Boss, there is fundamental mistake you have done.
You have given this code:
<nav id="nav-wrap">
<div id="menu-icon">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu</a>
</div>
<ul id="nav">​
See, the #nav doesn't come under #menu-icon. Change the code to:
<nav id="nav-wrap">
<div id="menu-icon">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu</a>
<ul id="nav">​
</div>
And it works!
Demo here: http://jsfiddle.net/qqbUY/
Screenshot