Vertical menu for Bootstrap 3

In my current project to redesign a site using the latest Bootstrap 3, I realized I wanted a vertical menu in the sidebar. I found all kinds of examples using lists as and just stacking them, but I wanted the mobile menu to function the same. So essentially I wanted a stacked sidebar menu that would function just like standard framework mobile menu. After some searching and trial and error, here’s what I came up with.


Update

In anticipation of Bootstrap 4, here’s a demo on creating a Bootstrap 4 Vertical Menu.


At a resolution of 768px or greater you see vertical menu in one of my two main columns.

bootstrap-side-menu-2

When scaled down to less than 768px, the menu collapses and works just like the normal theme menu.

bootstrap-side-menu-3

I only made one small addition to the standard HTML – I added a container div around the menu with a class called “sidebar-nav”.

<div class="row">
  <div class="col-sm-3">
    <div class="sidebar-nav">
      <div class="navbar navbar-default" role="navigation">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <span class="visible-xs navbar-brand">Sidebar menu</span>
        </div>
        <div class="navbar-collapse collapse sidebar-navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Menu Item 1</a></li>
            <li><a href="#">Menu Item 2</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li class="divider"></li>
                <li class="dropdown-header">Nav header</li>
                <li><a href="#">Separated link</a></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
            <li><a href="#">Menu Item 4</a></li>
            <li><a href="#">Reviews <span class="badge">1,118</span></a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>
  </div>
  <div class="col-sm-9">
    Main content goes here
  </div>
</div>

Then I just added this css.

/* make sidebar nav vertical */ 
@media (min-width: 768px) {
  .sidebar-nav .navbar .navbar-collapse {
    padding: 0;
    max-height: none;
  }
  .sidebar-nav .navbar ul {
    float: none;
  }
  .sidebar-nav .navbar ul:not {
    display: block;
  }
  .sidebar-nav .navbar li {
    float: none;
    display: block;
  }
  .sidebar-nav .navbar li a {
    padding-top: 12px;
    padding-bottom: 12px;
  }
}

Hope that helps someone.

At the request of a few people I have set up a really simple demo:

ย View Vertical Menu for Bootstrap 3 Example


Web Design
  • Edgard da Cunha Pontes

    Thanks for sharing this solution! Helped so much!

    • Glad it worked for you. This one was killing me. After looking everywhere and not finding anything I liked, I figured it was worth taking a stab at it myself.

  • Deewarz

    Thanks you ! ๐Ÿ™‚

  • NoTA Sheep

    Very nice. Just what I was looking for.

  • morganmissen

    This is great. A simple solution I wouldn’t have come up with on my own. Thanks!

  • madahmani

    Thank you for this snippet of code.
    For Bootstrap v3.1.1, you may also remove this value: max-height: 340px; and that’s around line 3659.
    Other than that, all is good.

    • Great point. I think of that as more optional so I forgot to include it. I do that on my own because I can’t stand the “scroll” on the larger menus. Good reminder, thanks.

      • madahmani

        The code is awesome anyway. I saved me a lot of time. Thank you!

  • Andre Veiga Magalhaes

    Hi

    I think the 2 columns should be with classes col-sm-3 and col-sm-9. Otherwise, the menu gets stacked in resolutions between 768 and 991 pixels. Resolutions below 768 pixels are classified as xs, and not sm, in Bootstrap 3.

    • Hey Andre – Great catch, thanks. For the site I was working on, I wanted it to break to the mobile menu with the col-md-3/col-md-9 but for the example intended to have it break, as you said, at 768px. I must have copied html somewhere in-between.

      I updated the example above with your two changes. Also, wanted to point out that I removed the class “visible-sm” from from the span containing “Sidebar menu”. Should be working pretty well. Thanks again.

  • Chiefsfan

    Jonathan, This worked perfectly. Thanks for sharing.

  • Akshay Sharma

    Works perfectly, thank you!!

    One thing though, for my code, and I admit there must be some overrides/conflicts on my side, but removing “position: absolute” from navbar-nav fixed the weird positioning problem.
    (Prior to doing that, the navbar was being pushed up / sucked in by the top of the page and only the last two links were visible)

    • Weird. Ya, that doesn’t happy for me using any of the really simple layouts I’ve used to test. Thanks for pointing it out incase someone has a similar problem.

  • Deepak Mani

    Thank you for sharing. It saved a lot of errors ๐Ÿ™‚

  • Evaldas Buinauskas

    Thank you. Great article ๐Ÿ™‚

  • Juhana Rรคsรคnen

    Exactly what I was just about to start working on myself! So glad I found out this first, thanks a bunch!

  • Brom Sulaiman

    Thanks Jonathan, just what I was after!

  • Jake Smith

    This helped me out quite a bit. What would be the best way to fix the navigation so that it followed you while you scrolled vertically? I tried placing “position: fixed” on the “navbar navbar-default” but that stopped it from resizing the width altogether. I’ll keep looking for a solution to this, but I haven’t been able to find anything for a while. I’ll post on here if I find anything but would appreciate any help on this if people can offer it ๐Ÿ™‚

    • Hey Jake – will see if I can take a few minutes to look at this for you soon.

    • Jake – So this might not be the best way to do it – but on my first pass this was the only way I could get it to work. You’re right, just adding “position: fixed” to the navbar class breaks the ability to size the menu. Using my example placing the menu in a column with a class “col-sm-3” I was able to add the fixed property and define the width at the three different break points and still have it look nice and function the way it should. Here’s what I added for mine. You would probably need to adjust your widths. Hope that helps. If you find a simpler solution – please share, I’d love to see it. (I’m not gonna update the example above, but here’s what I did). Sorry it doesn’t keep the formatting.

      @media (min-width: 768px) {
      .navbar {
      position: fixed;
      width: 170px;
      z-index: 2;
      }
      }
      @media (min-width: 992px) {
      .navbar {
      width: 212px;
      }
      }
      @media (min-width: 1200px) {
      .navbar {
      width: 262px;
      }
      }

      • Jake Smith

        Thanks for the reply ๐Ÿ™‚ Unfortunately I couldn’t get your solution to work, but I think I must have missed a step in your tutorial. I ended up going with a different solution from startbootstrap.com: http://startbootstrap.com/templates/simple-sidebar.html

        They have a ton of templates that you can look up on github (links on their site) and customize as you wish.

        I appreciate your time. I spent a good while trying to get it to work, but I’m still learning css. I’ve been ignoring it for too long…

        • Jake Smith

          It looks like the key to getting what I wanted was the wrapper divs. I wanted to be able to scroll the content on the right, but have the sidebar always in the same location and responsive to device variability. This ended up working quite nicely and was very similar to what you offered us here. Thanks again for the post, it was the reason for wanting to switch from a top nav to a side nav. Cheers!

  • Hi Jonathan. This helped me A LOT, but I ran an issue when handling dropdown menus inside my sidebar. I fixed it adding a :not() selector in the css. Hope you could add it so it doesn’t happen to anyone else. Have a nice day!

    .sidebar-nav .navbar ul:not(.dropdown-menu)

    • Thanks Hรฉctor. I haven’t experienced that problem. Let me try to duplicate the problem and try out that selector.

    • Hรฉctor – nice catch and fix! Thanks. I’ve updated the example above with a drop down in the menu as well as the updated CSS. I did make one small tweak. I only applied the :not() selector to the display:block portion – otherwise the menu didn’t look proper. Seems to be working just fine for me. Have to let me know how it works for you.

  • BrevAlessio

    Just what I’m looking for, thanks a lot!

  • Tony Green

    Saved me hours! Thank you very much.

  • David Mann

    This is really good. Shows how clean the bootstrap markup is when you can make it vertical by adjusting the floats of the lists and list items. I’ve noticed that when this is applied to the sample at http://getbootstrap.com/components/#navbar, the content in the .navbar-header can become hidden if the subsequent items in the navbar float up beside it. This seems to fix it: .sidebar-nav .navbar-header{ float: none; }

  • KK

    This is great! Helped me on my new website.

  • Ganiru

    Sure helped out. Thanks!

  • Kamel38

    Is there a demo page ? I’m not English native so I don’t understand everything. I just want to see the result :/

    • No there is not. Give me a day or so and I will set one up for you to see. I’ll reply here when it’s ready. ๐Ÿ™‚

      • Kamel38

        Oh, it’s really nice of you ! I look forward !

        • Kamel38 – Finally got your demo for you (linked at the bottom of the article).

          • Kamel38

            Thank you so much !

  • ed wrede

    Hey Jonathan.

    Great tutorial, thanks a bunch.

    Any ideas how you could modify the code to give you a full length navigation on the left hand side of the page?

    So in other words, from top to bottom, you have a “panel” for your navigation that you can make a different colour to the rest of the page? I quite like breaking it up like that.

    Thanks again!
    Ed

  • Titouan Crรฉac’h

    helped me a lot, thanks ! How could I reduce the default size ?

  • Kylie Rose

    Thanks for the heads up with this. Much appreciated!

  • Carl S

    This really helped me. I was trying to do this exact thing for a week or so, but I was over-complicating things, and I also tried just giving up and using buttons and button groups.

    Note that apparently .divider has changed to .nav-divider in Bootstrap 3.

  • MCodeMedia

    Thank you for this, I will try it out.

  • Otis Wright

    Hey Jonathan, I was wondering would it be possible to force the mobile style accordion drop-downs all the the e.g when it is at the side and as a mobile top nav.

    • Hey Otis – I’m sure it’s possible. I haven’t looked at this in forever. Let me see what I can figure out!

  • elpd

    +1 Excellent. Thank you.

  • Damien Aviles

    I tried to get this working on my page, but couldn’t get it going because I’m using a navbar at the top of the page. How do I make it so i can use two nav-bars, one at the top, one on the side? I tried to change some of the classes to navbar-V, but that doesn’t work. Thanks for the code!

    • You should be able to just a class to the nav on the side and then add the selector to CSS in the example. I haven’t tested this, but maybe do something this to the HTML:

      Then update the CSS to look something like this:


      /* make sidebar nav vertical */
      @media (min-width: 768px) {
      .sidebar-nav.vertical .navbar .navbar-collapse {
      padding: 0;
      max-height: none;
      }
      .sidebar-nav.vertical .navbar ul {
      float: none;
      }
      .sidebar-nav.vertical .navbar ul:not {
      display: block;
      }
      .sidebar-nav.vertical .navbar li {
      float: none;
      display: block;
      }
      .sidebar-nav.vertical .navbar li a {
      padding-top: 12px;
      padding-bottom: 12px;
      }
      }

      Again, I'm just guessing - but give that a try.

      • Damien Aviles

        Thanks for replying so quickly! I gave something like that a shot before and it didn’t work… tried your solution, nada either. ๐Ÿ™ Here’s a screenshot. Hopefully i piqued your interest in this ๐Ÿ™‚

        • Can you send me a link?

          • Damien Aviles
          • Hi Damien –

            Instead of putting the “vertical” class on the ” on line 109, put it on the div on line 97.

            Let me know if that helps!

          • Damien Aviles

            SWEET!! Nice man. Thanks a lot!

      • koyo

        it’s great! thanks so much *

      • Jelle van Lindenhuizen

        I also had a menu at the top and a submenu on the side. The styling went wrong, mostly because you used this line in html: . This took over my main menu styling.
        I just changed it to: and continued styling form there. Might help for some people…

  • gskema

    I was looking for this, thanks!

  • I cannot tell you the amount of time this saved me. It’s so simple. Thank you very much for sharing this.

  • Christer Fernstrom

    Thanks a lot for this elegant solution! If you put the menu on the right hand side by. putting the div col-sm-3 and the navbar code after the col with the page content, this works but the collapsed navbar of course now will appear at the bottom of the page. Any ideas of how to fix this?

    • Link? My first thought is ordering columns. I’ll explain when I can see. ๐Ÿ™‚

      • Christer Fernstrom

        It’s a WordPress application running on my laptop, but I grabbed the source code in a browser and put a copy where I hope you can see it here: http://78.222.112.147/test2/

        • Hi Christer –

          Can’t see it. I’ll try to do some guess work and explain what I’ve done in the past. Where I’ve wanted to have a right column on the desktop but have it be ordered at the top when you get to mobile is use the bootstrap push and pull classes. For example.


          Col will be on the right, then on top in xs
          Col will be on the left, then on bottom in xs

          That might not be 100%, but it may give you a starting point.

          • Christer Fernstrom

            Thanks Jonathan. I see exactly what you mean and feel confident this will fix my problem. I wasn’t aware of the push/pull. Thanks a lot and thanks for reacting so fast!!!!
            Cheers,
            — christer

          • Glad it worked!

  • Greg

    Thanks a lot for this example!
    I tried to use it, but somehow the collapsed menu won’t open if the page is not in the root directory. More specifically: it works in /index.html, but not in /something/index.html. Could you (or anyone else) guess what the problem could be?

    • Could you possibly provide a link for me to look at?

    • Hi Greg – that URL did not work. Just FYI

  • Michel Dilo

    Hello,
    I have a worry a shift of some px with texts which are higher than the window of the browser.

    An idea?

    Thank you,

    Michel (Fr)

    • Do you mean how the menu is taller than the body sometimes (especially when the window is smaller)?

      • Michel Dilo

        Bonjour,

        Look at well the passage between menu_vertical1.html and menu_vertical2.html, you will see that the menu moves laterally according to whether the central text is long or short. As if the long text widened the container.

        • Do you mean that it floats with the text when you scroll? If not, can you post a screen shot? I’m not 100% sure I understand the problem. Sorry – love to keep trying to help though!

          • Michel Dilo

            Hello,
            Here a video capture.

            http://main-courante.web4me.fr/capture_menu.mp4

            Thank you,

          • I think I see it now. The very slight shift where everything moves slightly to the left on menu_vertical2.html? If that’s what you’re talking about – it’s because of your scrollbar that appears on the right on vertical2.html because you now have to scroll (but didn’t on vertical1.html). ๐Ÿ™‚

          • Michel Dilo

            Eureka! height: 3500px; in div body and the scrollbar and always presents. More shift.
            Thank you,
            Afflicted not to have a perfect command of your languageโ€ฆ

  • Filipe Aguiar

    Thank YOU!

  • Arpit Aggarwal

    This helped me so much Jonathan!

    With your blog, it took me just 10 minutes to upgrade the design on my blog ๐Ÿ˜€

    One thing though:

    If you try to fix the sidebar with position:fixed; it seemed to cut itself in half on devices with width>768px.

    This little code seems to fix this behaviour:
    @media (min-width: 768px) {
    .sidebar-nav {

    position:fixed;

    width:inherit;

    }

    }
    Hope it helps ๐Ÿ™‚

  • Vito

    When the screen size shrinks, it transforms into the side navbar, but when I click the button to expand the menu, nothing happens. Any ideas?

    • Are you referring to the demo or your HTML? If yours and you can share a link I’ll take a look.

      • Vito

        I am referring to my project. Your demo works perfectly. The site is only on my local machine right now however.

      • Vito

        No idea what happened, but it now works. Thanks!

  • MDBritt

    Thank you very much! It is great to find a compact, efficient solution when so many alternatives are huge, bloated messes!

  • Louise Phillips

    Can you help with adding further sub-menu’s to the drop down? At the moment the menu only seems to allow for one dropdown level – would be useful to have 2nd, 3rd etc… Thanks!

    • Sorry – I just saw this. It’s been something I’ve been thinking about. I’ll try to take a look at it. ๐Ÿ™‚

  • KizMac

    This is awesome. Such a simple solution for something that was making my head hurt. Thank you ๐Ÿ™‚

  • Tomas Hesse

    Thanks for the Demo update!

  • A. Joseph

    Thank you so much for sharing this – simple, yet very effective. For yourself and your other visitors, if you want to have the “badge count” aligned to the right, then add this to your CSS:

    .badge { float: right; }

  • sameer sharma

    Thanks a lot for help. But I observed that button flows out of header in xs screen how can we fix that?

    • I haven’t had anyone else report that error nor does it happen on the demo so I’m guessing you have some other conflicting CSS element.

  • agata

    Hello everyone, First thanks for this tuto. In my case, I want to make the contrary, I want to make a horizontal menu in bottom of mobile and it became a button with drop down menu for web. Can you help me to do that?
    Thanks for advance.

    • Maybe I’m misunderstanding, but try using the fixed top navbar and then just tweak the CSS a little.

      So, your nav would be:

      Then just add this to overwrite the navbar position.

      .navbar-fixed-top {
      bottom: 0;
      }

      • agata

        Thankx a lot, I will try it ๐Ÿ™‚

  • TWyPGn

    Thanks for the tutorial. That’s exactly what I have been looking for. I don’t know what I’m doing wrong, but the menu doesn’t seem to be working. I am new to Bootstrap. Any kind of suggestion will be appreciated. Thank you!

    • I would start with making sure you can get the menu to work on a clean version of Bootstrap with no other CSS – just to make sure some other CSS you’ve written isn’t conflicting with it. Let me know if you’re still having problems. ๐Ÿ™‚

      • TWyPGn

        Thanks a lot Jonathan for the tip! I got it working finally ๐Ÿ™‚ I forgot to put the links to bootstrap min.css and min.js (silly me).

        Now I have another problem. I want to get the top bar displayed with full width on all screens. Right now there’s left n right margin on both side. I want to get rid of the side margin. Is there a way to do so? Your response and help will be very much appreciated. Thank you!

  • Zafra Miriam

    This is so helpful. I have one request – I want to have a “brand” image in the corner above the menu, like the default dreamweaver navbars have and you can also see on the vertical version here: http://www.bootply.com/n2fEs7ZBai#. (I tried just using the code from that link but could not for the life of me figure out how to have a main content div to the right of the menu at larger screen sizes – every attempt ended up with the div below.) Is there a way to add the brand space above the menu with your solution? Thanks much!

  • Patrick Lorenz

    Thanks for that solution! Exactly what I was looking for!

  • Candida

    Hi, Jonathan. I am doing a project in college with this sort of vertical menu with Bootstrap 3.3.7
    The main problem is that I need to display the menu on the right and make it responsive as you have it on this post.

    Do you have any solution for that case?

    Thanks so much. Regards.

    • Sure! So, basically you need something similar to what I have in the demo, but with the menu in the right column instead of left?

      • Candida

        Of course, in the right column instead of the left one. I mean, I want to see onto my laptop the page with the right menu, and then when I minimize the browser window, move from the left to centralize in the navigate zone from smartphone. How would you do it in my case? Thanks in advance.

        • If you look at the demo I shared, there are two columns. One has a class of `col-sm-3` and the other `col-sm-9`. If you update those to be `col-sm-3 col-sm-push-9` and `col-sm-9 col-sm-pull-3` you should see what you’re looking for.

          • Candida

            Hi again, Jonathan. I try changing those parameters, and it works! That’s exactly what I expect. Thanks a lot for your help!

  • Great Article i used this and working great

  • Alejandro Rueda

    Muchas gracias! justo lo que necesitaba.

  • Thanks for sharing this solution!