Sidebar Open By Default on Desktop, Closed on mobile

15,393

Solution 1

It looks like this has been answered here: https://stackoverflow.com/a/36289507/378779 Basically, add one of the navbar-expand-* classes to your <nav>, e.g.:

<nav class="menu menu-open navbar-expand-md" id="theMenu">

Solution 2

First just a couple points:

  1. You said sidebar, but your markup doesn't really look like a sidebar to me, it looks like a responsive topnav. I'll try to make sense of it as best I can, and I will demonstrate a working sidebar as well, in case that is what you really do want.

  2. Your menu items are in a <ul> (unordered list) without any <li> (list items). The bootsrap js/css probably needs the <li>s in order to function correctly. Technically a <ul> without any <li> is valid html, but the only content allowed in a <ul> are <li>s so anchors (or anything else) inside a <ul> must be contained within <li>s to be valid.

  3. I'm not sure what exactly you are trying to do with the social icons so I just adjusted them slightly in a way that seems sensible.

  4. I added overflow-y: scroll; on the <html> element so that when you open the menu on a small screen it won't cause shifting if a scrollbar gets added. May not be needed depending on your site design and content layout.


So lets start with a very basic responsive menu.

Basic Bootstrap Responsive Menu

html {
  overflow-y: scroll;
}
.social {
  padding: 4px 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

<nav class="navbar navbar-expand-md bg-dark navbar-dark">
  <!-- Brand -->
  <a class="navbar-brand" href="#">Navbar</a>

  <!-- Toggler/collapsibe Button -->
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
    <span class="navbar-toggler-icon"></span>
  </button>

  <!-- Navbar links -->
  <div class="collapse navbar-collapse" id="collapsibleNavbar">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" href="#">Home</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">About</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Writing</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Events</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Speaking</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Music</a>
      </li>
    </ul>
      <a class="social" href="#"><i class="fa fa-facebook fa-2x"></i></a>
      <a class="social" href="#"><i class="fa fa-twitter fa-2x"></i></a>
      <a class="social" href="#"><i class="fa fa-instagram fa-2x"></i></a>
  </div>
</nav>

Okay, that looks okay, but you had an image in the menu. So I'll put an image in the menu and give it a little css to style it. Then with the image, we'll need a little extra CSS to position menu elements nicely:

  1. Position the hamburger button so it sits on the bottom of the navbar. I'll use the 200px of the picture and substract a few rem. You could change the top: calc(100px - 1rem); to top: 1rem; to put the hamburger on top, or bottom: 1rem; if you wanted the hamburger to stick to the bottom of the nav even when opened. Or just delete that whole rule to use the bootstrap default which puts the hamburger in the vertical middle.

  2. Position the menu items to also rest on the bottom of the menu bar when not collapsed.

  3. position the social icons on the bottom also but push them over to the right hand side.

  4. Numbers 2 & 3 above should only apply above the medium breakpoint when the menu is not collapsed so I'll put them in a media query to target over 768px (bootstrap's medium breakpoint). This could also be done with bootstraps sass breakpoint mixins, but we'll just use plain css here. You can see the positioning of these elements within the @media query rule in the css, where you could change it to push them to the top of the bar. Or just remove those rules to revert to bootstrap defaults, which vertically centers menu elements, and puts the social icons beneath them. You could also put the social icons into <li> elements within the menu <ul> if you just wanted the icons to fall right into the menu like the other menu items.

with image in menu

html {
  overflow-y: scroll;
}
.social {
  padding: 4px 4px;
}
.nav-logo {
  width: 200px;
  height: 100%;
}
.navbar-toggler {
  position: absolute;
  top: calc(100px - 1rem);
  right: 1rem;
}

@media all and (min-width: 768px) {
  .navbar-nav {
    position: absolute;
    bottom: 0;
  }
  .social-list {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

<nav class="navbar navbar-expand-md bg-dark navbar-dark">
  <!-- Brand -->
  <a class="navbar-brand" href="#"><img class="nav-logo" src="https://i.postimg.cc/nckTrT6T/21.jpg"></a>

  <!-- Toggler/collapsibe Button -->
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
    <span class="navbar-toggler-icon"></span>
  </button>

  <!-- Navbar links -->
  <div class="collapse navbar-collapse" id="collapsibleNavbar">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" href="#">Home</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">About</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Writing</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Events</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Speaking</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Music</a>
      </li>
    </ul>
    <div  class="social-list">
      <a class="social" href="#"><i class="fa fa-facebook fa-2x"></i></a>
      <a class="social" href="#"><i class="fa fa-twitter fa-2x"></i></a>
      <a class="social" href="#"><i class="fa fa-instagram fa-2x"></i></a>
    </div>
  </div>
</nav>

Okay, but you said it was a sidebar. I'm not that familiar with bootstrap, but I gather that neither v3 nor v4 provide a sidebar nav by default. Several bootstrap sidebar tutorials can be found here. I have simply used the most basic version from the tutorials linked above to create an example here.

Collapsible Sidebar

$(document).ready(function () {

    $('#sidebarCollapse').on('click', function () {
        $('#sidebar').toggleClass('active');
    });

});
/* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

.wrapper {
    display: flex;
    width: 100%;
    align-items: stretch;
}

#sidebar {
    min-width: 250px;
    max-width: 250px;
    background: #7386D5;
    color: #fff;
    transition: all 0.3s;
}

#sidebar.active {
    margin-left: -250px;
}

#sidebar .sidebar-header {
    padding: 20px;
    background: #6d7fcc;
}

#sidebar ul.components {
    padding: 20px 0;
    border-bottom: 1px solid #47748b;
}

#sidebar ul p {
    color: #fff;
    padding: 10px;
}

#sidebar ul li a {
    padding: 10px;
    font-size: 1.1em;
    display: block;
}

#sidebar ul li a:hover {
    color: #7386D5;
    background: #fff;
}

#sidebar ul li.active>a,
a[aria-expanded="true"] {
    color: #fff;
    background: #6d7fcc;
}

a[data-toggle="collapse"] {
    position: relative;
}

.dropdown-toggle::after {
    display: block;
    position: absolute;
    top: 50%;
    right: 20px;
    transform: translateY(-50%);
}

ul ul a {
    font-size: 0.9em !important;
    padding-left: 30px !important;
    background: #6d7fcc;
}

ul.CTAs {
    padding: 20px;
}

ul.CTAs a {
    text-align: center;
    font-size: 0.9em !important;
    display: block;
    border-radius: 5px;
    margin-bottom: 5px;
}

a.download {
    background: #fff;
    color: #7386D5;
}

a.article,
a.article:hover {
    background: #6d7fcc !important;
    color: #fff !important;
}

/* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

#content {
    width: 100%;
    padding: 20px;
    min-height: 100vh;
    transition: all 0.3s;
}

/* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

@media (max-width: 768px) {
    #sidebar {
        margin-left: -250px;
    }
    #sidebar.active {
        margin-left: 0;
    }
    #sidebarCollapse span {
        display: none;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

    <div class="wrapper">
        <!-- Sidebar  -->
        <nav id="sidebar">
            <div class="sidebar-header">
                <h3>Bootstrap Sidebar</h3>
            </div>

            <ul class="list-unstyled components">
                <p>Dummy Heading</p>
                <li class="active">
                    <a href="#homeSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">Home</a>
                    <ul class="collapse list-unstyled" id="homeSubmenu">
                        <li>
                            <a href="#">Home 1</a>
                        </li>
                        <li>
                            <a href="#">Home 2</a>
                        </li>
                        <li>
                            <a href="#">Home 3</a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="#">About</a>
                </li>
                <li>
                    <a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle">Pages</a>
                    <ul class="collapse list-unstyled" id="pageSubmenu">
                        <li>
                            <a href="#">Page 1</a>
                        </li>
                        <li>
                            <a href="#">Page 2</a>
                        </li>
                        <li>
                            <a href="#">Page 3</a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="#">Portfolio</a>
                </li>
                <li>
                    <a href="#">Contact</a>
                </li>
            </ul>

            <ul class="list-unstyled CTAs">
                <li>
                    <a href="https://bootstrapious.com/tutorial/files/sidebar.zip" class="download">Download source</a>
                </li>
                <li>
                    <a href="https://bootstrapious.com/p/bootstrap-sidebar" class="article">Back to article</a>
                </li>
            </ul>
        </nav>

        <!-- Page Content  -->
        <div id="content">

            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <div class="container-fluid">

                    <button type="button" id="sidebarCollapse" class="btn btn-info">
                        <i class="fa fa-align-left"></i>
                        <span>Toggle Sidebar</span>
                    </button>
                    <button class="btn btn-dark d-inline-block d-lg-none ml-auto" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                        <i class="fa fa-align-justify"></i>
                    </button>

                    <div class="collapse navbar-collapse" id="navbarSupportedContent">
                        <ul class="nav navbar-nav ml-auto">
                            <li class="nav-item active">
                                <a class="nav-link" href="#">Page</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="#">Page</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="#">Page</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="#">Page</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>

            <h2>Collapsible Sidebar Using Bootstrap 4</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

            <div class="line"></div>

            <h2>Lorem Ipsum Dolor</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

            <div class="line"></div>

            <h2>Lorem Ipsum Dolor</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

            <div class="line"></div>

            <h3>Lorem Ipsum Dolor</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </div>
    </div>

Solution 3

You can use CSS Media Query to hide/show content at different viewport/device.

Share:
15,393
Frank Doe
Author by

Frank Doe

Yes, Frank Doe is my real name.

Updated on July 20, 2022

Comments

  • Frank Doe
    Frank Doe almost 2 years

    I'm having some real trouble trying to get my sidebar/navigation content (using Bootstrap) to show (be expanded) by default on desktop and closed by default on mobile and have the icon showing only on mobile. I cannot seem to get this to work.

    <nav class="menu menu-open" id="theMenu">
          <div class="menu-wrap">
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
              <i class="fa fa-bars menu-close d-lg-none" id="menu-toggle"></i>
                </button>
              <div id="menu-logo">
                <img src="Final_Logo.png" width="210" height="214" alt="">
              </div>
              <div id="navbarToggleExternalContent">
              <ul id="main-menu">
                  <a href="#">Home</a>
                  <a href="#">About</a>
                  <a href="#">Writing</a>
                  <a href="#">Events</a>
                  <a href="#">Speaking</a>
                  <a href="#">Music</a>
              </ul>
              <ul id="social-icons">
                  <li class="facebook"><a href="#"><i class="fab fa-facebook fa-2x"></i></a></li>
                  <li class="twitter"><a href="#"><i class="fab fa-twitter fa-2x"></i></a></li>
                  <li class="instagram"><a href="#"><i class="fab fa-instagram fa-2x"></i></a></li>
              </ul>
            </div>
          </div>
      </nav>
    

    I have tried using this javascript code, but to no avail:

     $('.menu-close').on('click', function(){
        $('#menuToggle').toggleClass('active');
        $('body').toggleClass('body-push-toright');
        $('#theMenu').toggleClass('menu-open');
        alert("Test");
        });
    
  • kmoser
    kmoser over 4 years
    Sniffing the User Agent string leads to code that is difficult to maintain. Media queries are much better.
  • Anis R.
    Anis R. over 4 years
    What is "difficult to maintain" about one string? Anyway you can wrap this check in a function, so that whenever you need to update the string, you have only one line of code to edit.
  • Anis R.
    Anis R. over 4 years
    Also, you cannot use CSS media queries to toggle class names like the OP wants
  • kmoser
    kmoser over 4 years
    Devices' User Agent strings change over time as new devices are produced. That results in code that breaks every time a new devices is introduced. Sure, you can wrap that in a function, but it still requires you to change it whenever a new device is introduced. It's better to target devices by their size (using CSS media queries), not the user-agent string. No updates are required when a new device is introduced. OP didn't necessarily want to toggle class names; that was their best attempt at a solution, and one which I believe is inferior to media queries.
  • O0123
    O0123 over 3 years
    stackoverflow.com/questions/65456359/… Can you have a look at this bootstrap 5 question?