346

Bootstrap 3 is still at RC, but I was just trying to implement it. I couldn't figure out how to put a sub menu class. Even there is no class in css and even the new docs don't say anything about it

It was there in 2.x with class name as dropdown-submenu

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
DevC
  • 7,055
  • 9
  • 39
  • 58
  • 2
    Remeber that some components have changed in version 3, including menu, navs and modals. – Deividi Cavarzan Aug 02 '13 at 18:21
  • 11
    the lack of native support for this (imho) useful feature in BS3 is one of the main reasons I haven't switched over yet. while I agree it isn't as useful in mobile, and they have a 'mobile first' approach now, it seems shortsighted to remove a feature they already implemented, that is VERY useful on the desktop – Andrew Brown Feb 06 '14 at 07:34
  • 4
    Agreed that it's short-sighted to remove expected functionality. This kind of breaking change gives enterprise developers a bad day. – RJB Jul 14 '14 at 03:06
  • To make a dropdown just use css http://codepen.io/Gothburz/pen/GpJKqP – Peter Girnus Oct 24 '15 at 23:42

11 Answers11

605

Bootstrap 5 (update 2023)

Add some JavaScript to prevent the submenu from closing when the parent dropdown is open. This can be done be toggle display:block...

let dropdowns = document.querySelectorAll('.dropdown-toggle')
dropdowns.forEach((dd)=>{
    dd.addEventListener('click', function (e) {
        var el = this.nextElementSibling
        el.style.display = el.style.display==='block'?'none':'block'
    })
})

Bootstrap 5 Multi-level Dropdown - click
Bootstrap 5 Multi-level Dropdown - hover
Bootstrap 5 Multi-level Dropdown - hover & animate transition

Or, you can use this CSS only method for Navbar dropdowns...

.dropdown-submenu {
  position: relative;
}

.dropdown-submenu .dropdown-menu {
  top: 0;
  left: 100%;
  margin-top: -1px;
}

.navbar-nav li:hover > ul.dropdown-menu {
    display: block;
}

Bootstrap 5 Navbar Dropdown Hover Submenus (CSS only)


Bootstrap 4 (update 2018)

The dropdown-submenu has been removed in Bootstrap 3 RC. In the words of Bootstrap author Mark Otto..

"Submenus just don't have much of a place on the web right now, especially the mobile web. They will be removed with 3.0" - https://github.com/twbs/bootstrap/pull/6342

But, with a little extra CSS you can get the same functionality.

navbar submenu on hover:

.navbar-nav li:hover > ul.dropdown-menu {
    display: block;
}
.dropdown-submenu {
    position:relative;
}
.dropdown-submenu>.dropdown-menu {
    top:0;
    left:100%;
    margin-top:-6px;
}

Navbar submenu dropdown hover
Navbar submenu dropdown hover (right aligned)
Navbar submenu dropdown click (right aligned)
Navbar dropdown hover (no submenu)


Bootstrap 3

Here is an example that uses Bootstrap 3: https://codeply.com/p/T9FWGhhL0S

CSS

.dropdown-submenu {
    position:relative;
}
.dropdown-submenu>.dropdown-menu {
    top:0;
    left:100%;
    margin-top:-6px;
    margin-left:-1px;
    -webkit-border-radius:0 6px 6px 6px;
    -moz-border-radius:0 6px 6px 6px;
    border-radius:0 6px 6px 6px;
}
.dropdown-submenu:hover>.dropdown-menu {
    display:block;
}
.dropdown-submenu>a:after {
    display:block;
    content:" ";
    float:right;
    width:0;
    height:0;
    border-color:transparent;
    border-style:solid;
    border-width:5px 0 5px 5px;
    border-left-color:#cccccc;
    margin-top:5px;
    margin-right:-10px;
}
.dropdown-submenu:hover>a:after {
    border-left-color:#ffffff;
}
.dropdown-submenu.pull-left {
    float:none;
}
.dropdown-submenu.pull-left>.dropdown-menu {
    left:-100%;
    margin-left:10px;
    -webkit-border-radius:6px 0 6px 6px;
    -moz-border-radius:6px 0 6px 6px;
    border-radius:6px 0 6px 6px;
}

Sample Markup

<div class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">  
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="collapse navbar-collapse navbar-ex1-collapse">
            <ul class="nav navbar-nav">
                <li class="menu-item dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Drop Down<b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li class="menu-item dropdown dropdown-submenu">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Level 1</a>
                            <ul class="dropdown-menu">
                                <li class="menu-item ">
                                    <a href="#">Link 1</a>
                                </li>
                                <li class="menu-item dropdown dropdown-submenu">
                                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Level 2</a>
                                    <ul class="dropdown-menu">
                                        <li>
                                            <a href="#">Link 3</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</div>

P.S. - Example in navbar that adjusts left position: https://codeply.com/p/XEiERVGcmz

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
  • Here's Bootstrap 3 upgrade / migration guidance: http://www.bootply.com/bootstrap-3-migration-guide – Carol Skelly Aug 07 '13 at 00:31
  • 5
    Yeah Thanks I have added it my theme's stylesheet, just copy pasted from old version of bootstrap http://wordpress.org/themes/bikaner – DevC Aug 31 '13 at 19:08
  • It doesn't work for me, and i can't find why. For some reason sub submenu overlaps with main submenu, it should open on the right of submenu but it overlaps. And i checked html, i checked css it's the same as in your examples. http://www.imagebam.com/image/ef1ab7301437435 – lonerunner Jan 15 '14 at 21:05
  • It works actually, but im using it on wordpress, and it was problem with wrong order of enqueuing styles. – lonerunner Jan 16 '14 at 00:41
  • 9
    For example http://bootply.com/86684, add the following line in css for correct background hover of parent menu item when displaying submenu: `.dropdown-submenu:hover {background: #e2e1e1;}` – Eduardo Moralles Jan 22 '14 at 18:13
  • 1
    Works with 3.1.1 as well. Many thanks for the solution. I was beating my head against the wall trying to alter the bootstrap.js file to work properly. – Joel Kinzel Apr 29 '14 at 14:12
  • 1
    Added css/markup to the solution. Really helpful answer would be a shame to see the link go down. [and a fiddle as well](http://jsfiddle.net/loktar/Q2QXy/) – Loktar Jul 22 '14 at 17:22
  • Tinkered with 3.2.0 version. Found out that it is not compatible with angular ui bootstrap module: http://angular-ui.github.io/bootstrap/ – Fandi Susanto Sep 07 '14 at 20:30
  • For a nav-right I needed to add right: auto; to .dropdown-submenu>.dropdown-menu because sometimes the submenu wouldn't be wide enough for the links. This is due to Bootstrap adding right: 1 to .nav-right .dropdown-menu – Hawkee Nov 14 '14 at 19:23
  • I tried the bootply examples [http://www.bootply.com/92442] and [http://www.bootply.com/J2vCTTfm9p], they are working in bootply's spitted window, but neither in the "Fullscreen preview' nor in the "Smartphone/mobile device preview". Clicking on "Clearing floats" the submenu doesn't appear, but the menu will be closed. The same also at me. Any idea why? – Tibor Nagy Jun 08 '15 at 16:46
  • 2
    I'm all about trying to simplify things as much as possible but there is a need for this on large websites with no way around multiple levels of navigation (such as government websites). – Troy Templeman Dec 19 '17 at 14:30
  • 1
    Submenu disappear even before I can move the mouse to it, so hovering isn't working! It not hover, relying on click, it works OK, though. – Polv Jul 29 '18 at 17:07
  • 1
    OK, my variant to make hover work: https://www.codeply.com/go/nx97JyPRF7 Note that, in my real project, I don't have to `setTimeout( , 100)` – Polv Jul 29 '18 at 19:09
  • how can i do second ul and other all ul menus side by side same height ? at the same height as the first submenu ? –  Feb 26 '20 at 08:11
  • Unfortunately, this answer (for Bootsrap 5) does not work for many use cases. (For example, multiple submenus under one menu.) The only solution that worked for me for Bootsratp 5 is at this link: https://github.com/dallaslu/bootstrap-5-multi-level-dropdown . – justadeveloper Jul 01 '22 at 11:25
63

@skelly solution is good but will not work on mobile devices as the hover state won't work.

I have added a little bit of JS to get the BS 2.3.2 behavior back.

PS: it will work with the CSS you get there: http://bootply.com/71520 though you can comment the following part:

CSS:

/*.dropdown-submenu:hover>.dropdown-menu{display:block;}*/

JS:

$('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) {
  // Avoid following the href location when clicking
  event.preventDefault();
  // Avoid having the menu to close when clicking
  event.stopPropagation();
  // If a menu is already open we close it
  $('ul.dropdown-menu [data-toggle=dropdown]').parent().removeClass('open');
  // opening the one you clicked on
  $(this).parent().addClass('open');
});

The result can be found on my WordPress theme (Top of the page): http://shprinkone.julienrenaux.fr/

Igor Ivancha
  • 3,413
  • 4
  • 30
  • 39
Shprink
  • 780
  • 8
  • 16
  • 2
    This solution doesn't account for wanting to keep hover functionality when on desktop and it also doesn't work for the second level of submenu. In order for this to work for more levels of submenus change the last two lines to the following line: `$(this).closest(".dropdown-submenu").toggleClass("open");`, which will open/close the links menu items. In order to keep hover on desktop a check on the browsers viewport width is necessary and will differ for each site. – edhedges Nov 19 '15 at 18:12
  • thanks for your code. but in mobile phone your code has bug. – John Shang Apr 06 '17 at 03:34
44

Until today (9 jan 2014) the Bootstrap 3 still not support sub menu dropdown.

I searched Google about responsive navigation menu and found this is the best i though.

It is Smart menus http://www.smartmenus.org/

I hope this is the way out for anyone who want navigation menu with multilevel sub menu.

update 2015-02-17 Smart menus are now fully support Bootstrap element style for submenu. For more information please look at Smart menus website.

vee
  • 4,506
  • 5
  • 44
  • 81
  • I was having trouble trying to get bootstrap to hover on PC, and click on tablet with multiple levels. You just made my day! Works beautifully - Uses pretty much the same markup as bootstrap. Thank you! :) – Hippie Jan 24 '14 at 01:29
  • 2
    This solution is free, open source and work very well with BootStrap 3. – Patrick Desjardins Mar 31 '14 at 22:23
  • 5
    Amazing! Easy! For specific details on Bootstrap 3 integration, see here: http://vadikom.github.io/smartmenus/src/demo/bootstrap-navbar.html – manafire Jul 02 '14 at 21:20
  • 2
    Smartmenus is nice, however it only works with navbars, not with simple button dropdowns. – Nikolai Prokoschenko Sep 12 '14 at 13:14
  • This solves the problem, makes the menus hover and touch compatible, and requires only the default Bootstrap 3 HTML markup. < Great solution, transparent and fast to implement! – Jpsy Dec 09 '14 at 12:26
  • @vee I've tried his examples, but I could not get the samples to work with correct behavior on mobile and desktop. Either it was hover on both or click on both. It's probably a simpler solution, but as such, it seems more limited and personally, I'd rather stick with code that has documentation and doesn't require additional hacks to get it working as expected. – Lunyx Nov 06 '16 at 14:55
8

With Bootstrap 5, it's now very easy to implement dropdown submenu without using any javascript code thanks to the new autoClose option and dropend class.

Live demo: https://jsfiddle.net/b038kc2y/

.dropdown-menu .dropdown-menu {
  top: -.5rem !important;
}
<div class="dropdown m-5">
  <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
    Dropdown link
  </a>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
    <li class="dropend">
      <a class="dropdown-item" href="#" id="dropdownSubMenuLink" data-bs-toggle="dropdown" aria-expanded="false">Submenu Action</a>
      <ul class="dropdown-menu" aria-labelledby="dropdownSubMenuLink">
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><a class="dropdown-item" href="#">Something else here</a></li>
      </ul>
    </li>
  </ul>
</div>
Seb33300
  • 7,464
  • 2
  • 40
  • 57
5

Shprink's code helped me the most, but to avoid the dropdown to go off-screen i updated it to:

JS:

$('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) {
    // Avoid following the href location when clicking
    event.preventDefault(); 
    // Avoid having the menu to close when clicking
    event.stopPropagation(); 
    // If a menu is already open we close it
    $('ul.dropdown-menu [data-toggle=dropdown]').parent().removeClass('open');
    // opening the one you clicked on
    $(this).parent().addClass('open');

    var menu = $(this).parent().find("ul");
    var menupos = $(menu).offset();

    if (menupos.left + menu.width() > $(window).width()) {
        var newpos = -$(menu).width();
        menu.css({ left: newpos });    
    } else {
        var newpos = $(this).parent().width();
        menu.css({ left: newpos });
    }

});

CSS: FROM background-color: #eeeeee TO background-color: #c5c5c5 - white font & light background wasn't looking good.

.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
  background-color: #c5c5c5;
  border-color: #428bca;
}

I hope this helps people as much as it did for me!

But i hope Bootstrap add the subs feature back ASAP.

WHOMEZz
  • 79
  • 7
4

Comment to Skelly's really helpful workaround: in Bootstrap-sass 3.3.6, utilities.scss, line 19: .pull-left has float:left !important. Since that, I recommend to use !important in his CSS as well:

.dropdown-submenu.pull-left {
    float:none !important;
}
Community
  • 1
  • 1
bencergazda
  • 620
  • 8
  • 18
2

I bumped with this issue a few days ago. I tried many solutions and none really worked for me on the end i ended up creating an extenion/override of the dropdown code of bootstrap. It is a copy of the original code with changes to the closeMenus function.

I think it is a good solution since it doesn't affects the core classes of bootstrap js.

You can check it out on gihub: https://github.com/djokodonev/bootstrap-multilevel-dropdown

George Donev
  • 563
  • 7
  • 13
0

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Dropdown Navbar</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
<nav class="navbar navbar-inverse">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">The Providers</a>
    </div>
    <div class="collapse navbar-collapse" id="myNavbar">
      <ul class="nav navbar-nav">
        <li ><a href="#">Home</a></li>
        <li  id="course" class="dropdown" ><a  href="#">Courses<span class="caret"></span></a>
        <ul class="dropdown-menu">
          <li><a href="#">SEO</a></li>
          <li><a href="#">A.I</a></li>
          <li><a href="#">M.L</a></li>
          <li><a href="#">Graphics</a></li>
          <li id="sub-dropdown" class="dropdown"><a href="#">web Design<span style="margin-left: 43px;" class="glyphicon glyphicon-chevron-right"></span> </a>
        <ul id="sub-dropdown-menu" class="dropdown-menu">
          <li><a href="#">HTML</a></li>
          <li><a href="#">CSS</a></li>
          <li><a href="#">Bootstrap 3</a></li>
          <li><a href="#">JavaScript</a></li>
          <li><a href="#">Angular</a></li>
        </ul>
      </li>
          </li>
        </ul>
      </li>
        <li><a href="#">Gallery</a></li>
        <li><a href="#">Contact us</a></li>
        <li><a href="#">Policy</a></li>
      </ul>
    </div>
  </div>
</nav>
</body>
</html>

CSS

body{
    font-family: monospace;
    outline: none;
    background-image: url(image.jpg);
    background-size: cover;
    background-repeat: no-repeat;
    height: 100vh;
}
.navbar-inverse{
    background-color: #2a84eb ;
    border-color: transparent;
}

.navbar-inverse .navbar-brand{
    color: #fff;
    font-size: 30px;
    margin-right: 40px;
}

#myNavbar .navbar-nav li a{
    color: #fff;
    font-size: 19px;
}
#myNavbar #course{
    transition: all 0.3s ease-in-out;
}
#myNavbar #course:hover{
    background-color:#0751a6; 
}   
.dropdown-menu{
  display: none;
  position: absolute;
  background-color: #f0f0f0;
  box-shadow: 2px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
}

#sub-dropdown-menu{
display: none;
  position: absolute;
  background-color: #f0f0f0;
  margin-left: 186px;
  margin-top: -26px;
}

#sub-dropdown-menu a , .dropdown-menu a {
    color: #000 !important;
    font-size: 16px !important;
}

.dropdown:hover .dropdown-menu {display: block;transition: all 0.5s ease-in-out;}

.dropdown .dropdown-menu a:hover{background-color: #c9c7c7;}

#sub-dropdown:hover #sub-dropdown-menu {display: block;}

Source: https://www.youtube.com/watch?v=6CgnWhJ-amE

PeterPazmandi
  • 533
  • 10
  • 13
0

In 2022 for Bootstrap 5, this JS code at this GitHub repo is the ultimate solution for submenus: https://github.com/dallaslu/bootstrap-5-multi-level-dropdown.

justadeveloper
  • 203
  • 3
  • 12
0

This is my solution (I use bootstrap 5):

HTML

<div class="btn-group dropend" role="group">
    <button id="submenu" type="button" class="dropdown-item  dropdown-toggle submenu" data-bs-toggle="dropdown" aria-expanded="false">
        Menu Item
    </button>
    <div class="dropdown-menu" aria-labelledby="submenu">
        <a class="dropdown-item">Submenu</a>
    </div>
</div>

JS

$('.submenu').click(function(e){
    e.preventDefault();
    e.stopPropagation();
});
-2

I make another solution for dropdown. Hope this is helpfull Just add this js script

<script type="text/javascript"> jQuery("document").ready(function() {
  jQuery("ul.dropdown-menu > .dropdown.parent").click(function(e) {
    e.preventDefault();
    e.stopPropagation();
    if (jQuery(this).hasClass('open2'))
      jQuery(this).removeClass('open2');
    else {
      jQuery(this).addClass('open2');
    }

  });
}); < /script>

<style type="text/css">.open2{display:block; position:relative;}</style>
Igor Ivancha
  • 3,413
  • 4
  • 30
  • 39