Twitter Bootstrap Multilevel Dropdown Menu
Asked Answered
I

6

92

Is it possible to have a multi level dropdown menu by using the elements of twitter bootstrap 2? The original version doesn't have this feature.

Impound answered 18/3, 2012 at 13:10 Comment(3)
actually searched for an implementation but I wasn't luck with it.Impound
Maybe you need a suckerfish menu? htmldog.com/articles/suckerfish/dropdownsNefen
have a look at this, too: github.com/twitter/bootstrap/issues/424Demoniac
T
114

Updated Answer

* Updated answer which support the v2.1.1** bootstrap version stylesheet.

**But be careful because this solution has been removed from v3

Just wanted to point out that this solution is not needed anymore as the latest bootstrap now supports multi-level dropdowns by default. You can still use it if you're on older versions but for those who updated to the latest (v2.1.1 at the time of writing) it is not needed anymore. Here is a fiddle with the updated default multi-level dropdown straight from the documentation:

http://jsfiddle.net/2Smgv/2858/


Original Answer

There have been some issues raised on submenu support over at github and they are usually closed by the bootstrap developers, such as this one, so i think it is left to the developers using the bootstrap to work something out. Here is a demo i put together showing you how you can hack together a working sub-menu.

Relevant code

CSS

.dropdown-menu .sub-menu {
    left: 100%;
    position: absolute;
    top: 0;
    visibility: hidden;
    margin-top: -1px;
}

.dropdown-menu li:hover .sub-menu {
    visibility: visible;
    display: block;
}

.navbar .sub-menu:before {
    border-bottom: 7px solid transparent;
    border-left: none;
    border-right: 7px solid rgba(0, 0, 0, 0.2);
    border-top: 7px solid transparent;
    left: -7px;
    top: 10px;
}
.navbar .sub-menu:after {
    border-top: 6px solid transparent;
    border-left: none;
    border-right: 6px solid #fff;
    border-bottom: 6px solid transparent;
    left: 10px;
    top: 11px;
    left: -6px;
}

Created my own .sub-menu class to apply to the 2-level drop down menus, this way we can position them next to our menu items. Also modified the arrow to display it on the left of the submenu group.

Demo

Tenebrae answered 19/3, 2012 at 15:54 Comment(10)
As of a Bootstrap 2.0.4, you must also have the declaration "display: block;" in selector ".dropdown-menu li:hover .sub-menu".Popery
I tried to implement it, the first submenu works fine. But if i'll add another submenu in the same menu, then things go wrong. For some reason it opens the first submenu instead of the second. Any idea's or clues would be welcome. Already thankx :)Aesop
Hermes - See my answer for how to fix the submenu's sticking.Quintin
@HermesTrismegistus fixed the demo with the suggested fix by Omar, everything is working now. Thanks for the heads up guys.Tenebrae
@AndresIlich Have you tried a JS implementation ? By using another namespace for the click ?Melchizedek
So I forked to add a third level menu: Demo. I just had to replace .dropdown-menu li:hover .sub-menu with .dropdown-menu li:hover > .sub-menu.Dominions
hey @AndresIlich, The submenu with the style HOVER can't be used in Smartphone (Touch Screen). Any solution about this?Shumate
@Shumate mobilizing this fix would require some extra markup and probably some javascript as well. I suggest just displaying the second level dropdown content instead of hiding it on mobile devices as to keep things clean. I will try to work on a solution later during the day. I have not tested the default bootstrap solution though, so if anything you can always go with that.Tenebrae
The updated version only works with Bootstrap 2.3.2, it was removed in Bootstrap 3.0Offenbach
is there a reason they removed it? Only reason i can imagine is that the sub-menues wont work on mobile devices. Edit: okay found the answer: "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" - Bootstrap author Mark Otto.Kreitman
O
34

[Twitter Bootstrap v3]

To create a n-level dropdown menu (touch device friendly) in Twitter Bootstrap v3,

CSS:

.dropdown-menu>li /* To prevent selection of text */
{   position:relative;
    -webkit-user-select: none; /* Chrome/Safari */        
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* IE10+ */
    /* Rules below not implemented in browsers yet */
    -o-user-select: none;
    user-select: none;
    cursor:pointer;
}
.dropdown-menu .sub-menu 
{
    left: 100%;
    position: absolute;
    top: 0;
    display:none;
    margin-top: -1px;
    border-top-left-radius:0;
    border-bottom-left-radius:0;
    border-left-color:#fff;
    box-shadow:none;
}
.right-caret:after,.left-caret:after
 {  content:"";
    border-bottom: 5px solid transparent;
    border-top: 5px solid transparent;
    display: inline-block;
    height: 0;
    vertical-align: middle;
    width: 0;
    margin-left:5px;
}
.right-caret:after
{   border-left: 5px solid #ffaf46;
}
.left-caret:after
{   border-right: 5px solid #ffaf46;
}

JQuery:

$(function(){
    $(".dropdown-menu > li > a.trigger").on("click",function(e){
        var current=$(this).next();
        var grandparent=$(this).parent().parent();
        if($(this).hasClass('left-caret')||$(this).hasClass('right-caret'))
            $(this).toggleClass('right-caret left-caret');
        grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');
        grandparent.find(".sub-menu:visible").not(current).hide();
        current.toggle();
        e.stopPropagation();
    });
    $(".dropdown-menu > li > a:not(.trigger)").on("click",function(){
        var root=$(this).closest('.dropdown');
        root.find('.left-caret').toggleClass('right-caret left-caret');
        root.find('.sub-menu:visible').hide();
    });
});

HTML:

<div class="dropdown" style="position:relative">
    <a href="#" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">Click Here <span class="caret"></span></a>
    <ul class="dropdown-menu">
        <li>
            <a class="trigger right-caret">Level 1</a>
            <ul class="dropdown-menu sub-menu">
                <li><a href="#">Level 2</a></li>
                <li>
                    <a class="trigger right-caret">Level 2</a>
                    <ul class="dropdown-menu sub-menu">
                        <li><a href="#">Level 3</a></li>
                        <li><a href="#">Level 3</a></li>
                        <li>
                            <a class="trigger right-caret">Level 3</a>
                            <ul class="dropdown-menu sub-menu">
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                                <li><a href="#">Level 4</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li><a href="#">Level 2</a></li>
            </ul>
        </li>
        <li><a href="#">Level 1</a></li>
        <li><a href="#">Level 1</a></li>
    </ul>
</div>
Okie answered 2/8, 2013 at 20:11 Comment(9)
Unfortunately this doesn't show the menu when the 'collapsed' button of the menu is showing. In Chrome and in FF.Peroneus
@BenPower Can you please provide a jsfiddle demo of it, so that I can look into it because the jsfiddle demo I have given is working fine. Also which versions of Bootstrap, JQuery and Web browsers you are using?Okie
Its working for Bootstrap v3.0. Buddy...Could you please make it supportive for Bootstrap v2.3.2?Condensate
@Niks for v2.3.2 see the updated answer of Andres Ilich above. I tested it for v2.3.2 and here is the bootply example: bootply.com/114740Okie
@Niks my above code also works in v2.3.2, here is the bootply example: bootply.com/114744Okie
I added trigger.off('click'); before setting the listeners in order to prevent "double listening" to an event in case the javascript initialization is triggered more than once.Unrest
@ChirayuChiripal Is possible to not close the menu when click on other part of the page?Anticipative
@Anticipative Yes. See this JsFiddle: jsfiddle.net/06hjeqtd/3 Based on following answer: https://mcmap.net/q/162663/-keep-bootstrap-dropdown-open-when-clicked-offOkie
Inverting the caret added several lines of code and is unnecessary.Germanophile
R
23

This example is from http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3

Works for me in Bootstrap v3.1.1.

HTML

<div class="container">
<div class="row">
    <h2>Multi level dropdown menu in Bootstrap 3</h2>
    <hr>
    <div class="dropdown">
        <a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" data-target="#" href="/page.html">
            Dropdown <span class="caret"></span>
        </a>
        <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
          <li><a href="#">Some action</a></li>
          <li><a href="#">Some other action</a></li>
          <li class="divider"></li>
          <li class="dropdown-submenu">
            <a tabindex="-1" href="#">Hover me for more options</a>
            <ul class="dropdown-menu">
              <li><a tabindex="-1" href="#">Second level</a></li>
              <li class="dropdown-submenu">
                <a href="#">Even More..</a>
                <ul class="dropdown-menu">
                    <li><a href="#">3rd level</a></li>
                    <li><a href="#">3rd level</a></li>
                </ul>
              </li>
              <li><a href="#">Second level</a></li>
              <li><a href="#">Second level</a></li>
            </ul>
          </li>
        </ul>
    </div>
</div>

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;
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: #ccc;
margin-top: 5px;
margin-right: -10px;
}

.dropdown-submenu:hover>a:after {
border-left-color: #fff;
}

.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;
}
Rounds answered 18/3, 2014 at 15:54 Comment(1)
Thanks you ! the 3.0 version doesn't support anymore the validated answerWaffle
Q
13

I was able to fix the sub-menu's always pinning to the top of the parent menu from Andres's answer with the following addition:

.dropdown-menu li {
    position: relative;
}

I also add an icon "icon-chevron-right" on items which contain menu sub-menus, and change the icon from black to white on hover (to compliment the text changing to white and look better with the selected blue background).

Here is the full less/css change (replace the above with this):

.dropdown-menu li {
    position: relative;

    [class^="icon-"] {
        float: right;
    }

    &:hover {
        // Switch to white icons on hover
        [class^="icon-"] {
            background-image: url("../img/glyphicons-halflings-white.png");
        }
    }
}
Quintin answered 26/6, 2012 at 17:50 Comment(0)
S
4

I just added class="span2" to the <li> for the dropdown items and that worked.

Sewell answered 4/6, 2012 at 3:2 Comment(0)
V
3

Since Bootstrap 3 removed the submenu part and we need to adapt ourselves the style, I think it's better to go with SmartMenu Bootstrap: https://vadikom.github.io/smartmenus/src/demo/bootstrap-navbar.html#

That would save us time on mobile responsive and style.

This plugin also very promising.

Vaccinia answered 5/8, 2015 at 10:38 Comment(3)
What's your opinion about github.com/istvan-ujjmeszaros/bootstrap-dropdown-hover ? I cannot decide.Conservatory
@CsabaToth, this one was also in my consider, if you want to have only the bootstrap javascript API, you can go with this one, light enough to add and can be familiar with general bootstrap skill if you need any customize.Vaccinia
Finally I gonna use one of them in one project and the other in a companion site. Each solution fits one of them betterConservatory

© 2022 - 2024 — McMap. All rights reserved.