Bootstrap 4 navbar with two rows, bottom row colla

2020-05-01 10:28发布

问题:

I would like the 2 navbars to appear in two separate rows, with all the links (collapsible items) in the bottom, and a header and toggle button in the top row.

Like this:

------------------------------------------------------
         ONE_________BIG_________TITLE        [Toggle]
------------------------------------------------------
Nav items Icon Links Forms ...
------------------------------------------------------

Top row will be expanded in both mobile and desktop devices, but the toggle button should be hidden on desktop. Bottom row will be expanded on desktop and collapsed on mobile devices.

I was able to do this in bootstrap 3 by wrapping everything in one div.navbar and using display:table to position and vertical align logo/title and toggle next to each other.

In desktop devices only, after scrolling, I want the bottom row to be fixed to the top. I used to achieve this using affix in bootstrap 3, any ideas how I can do it with the new version?

Also in mobile devices the top row which is NOT collapsed should be fixed to the top.

Here is my bootstrap 3 code:

#navcollapse {
  top: 0;
  width: 100%;
  z-index: 10050;
}

@media (max-width: 767px) {
  #navcollapse {
    position: static;
  }
}

#topnavrow.affix {
  top: 0;
  width: 100%;
  z-index: 10050;
}

@media (min-width: 768px) {
  #topnavrow.affix {
    position: static;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<div class="navbar" data-offset-top="0" data-spy="affix" id="topnavrow">
  <div class="container" style="display:table;">
    <div style="display:table-cell;vertical-align:middle;">
      <a href="#" title="">
            _________TITLE_________
            </a>
    </div>
    <div style="display:table-cell;vertical-align:middle;">
      <button aria-expanded="false" class="navbar-toggle collapsed" data-target="#navcollapse" data-toggle="collapse" type="button">
              Toggle 
            </button>
    </div>
  </div>
  <nav class="collapse navbar-collapse container-fluid navbar-default" data-offset-top="100" data-spy="affix" id="navcollapse" style="max-width:100%;min-width:100%;">
    <div class="container">
      <ul class="nav navbar-nav">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </div>
  </nav>
</div>

Here is a code suggested by @ZimSystem in the comments. because "navbar-collapse" and "collapse" are applied to a div inside the navbar, there is always a gray border when the navbar is collapsed.

I can't figur out how to apply it to the parent nav without breaking the styles...

/* only affix the top navbar on mobile */
@media (max-width: 768px) {
    .fixed-top-sm {
        position: fixed;
        top: 0;
        right: 0;
        left: 0;
        z-index: 1030;
    }
    body {
        padding-top: 44px;
    }
}
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
   <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>


<nav class="navbar navbar-expand-md fixed-top-sm justify-content-start flex-nowrap bg-light navbar-light">
    <a href="/" class="navbar-brand">Top</a>
    <button class="navbar-toggler ml-auto" type="button" data-toggle="collapse" data-target="#navbar2">
        <span class="navbar-toggler-icon"></span>
    </button>
</nav>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
    <div class="navbar-collapse collapse pt-2 pt-md-0" id="navbar2">
        <ul class="navbar-nav">
            <li class=""><a class="nav-link" href="#">Link 2</a></li>
        </ul>
    </div>
</nav>

回答1:

The example below is a pure Bootstrap 4 solution to this problem.

Breakdown:

  • We are using two .navbars, one below the other. Both having the same .navbar-expand-{breakpoint} classes, .navbar-expand-lg in this case.
  • Title is positioned to center with the .ml-auto .mr-auto classes. That leaves the toggler button intact at the right edge.
  • In order to eliminate the border when the bottom navbar is collapsed (caused by the paddings of the bottom navbar), .py-0 is introduced on the navbar itself, and .my-2 is added to the .navbar-collapse to re-gain the spacing.
  • Finally, applying .sticky-top to both navbars. So, when only the top navbar is visible, it will stay fixed to top, however when the bottom navbar is visible too, that will be fixed to the top instead of the top navbar.

#content {
    height: 200vh;
}
<nav id="topnavrow" class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
    <a class="navbar-brand ml-auto mr-auto" href="#">_________TITLE_________</a>

    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navcollapse" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
</nav>

<nav class="navbar navbar-expand-lg navbar-light bg-light py-0 sticky-top">
    <div id="navcollapse" class="collapse navbar-collapse my-2">
        <div class="navbar-nav">
            <a class="nav-item nav-link active" href="#">Item 1</a>
            <a class="nav-item nav-link" href="#">Item 2</a>
            <a class="nav-item nav-link" href="#">Item 3</a>
            <a class="nav-item nav-link" href="#">Item 4</a>
        </div>
    </div>
</nav>

<section id="content">
    [page content]
</section>


<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>