spassvogel
spassvogel

Reputation: 3541

Bootstrap 4: Show active nav-item on Navbar collapse

I'm trying to create a navbar using bootstrap that collapses at a certain viewport width. Now, what I'd like to see is that if the navbar is collapsed the navbar-brand disappears and the current active nav item (e.g 'Home', 'About' etc) will be visible on the left, thus enabling the visitor to see at which page they are.

I'm a total bootstrap noob, I had sort of expected to see a css class to be added when the navbar is collapsed/expanded but it doesn't work that way.

<html lang="en"><head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
 <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

</body></html>

Upvotes: 5

Views: 6430

Answers (3)

Carol Skelly
Carol Skelly

Reputation: 362270

Not exactly "out of the box", but a little CSS will work with Bootstrap 4 (no jquery or dup markup)...

https://www.codeply.com/go/5T4icATKjl

This overrides the navbar collapse behavior to use visibility instead of display. This way we can control display of the active nav-item.

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<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>
    
<style>
.navbar .collapse {
    visibility: hidden;
    display: block;
}

.navbar .collapse.show {
    visibility: visible;
}

@media (max-width: 767px) {
    .navbar-nav .nav-link.active {
        visibility: visible;
    }
    
    .collapsing {
        transition: all 0.35s ease;
        height: 40px !important;
    }
    
    .collapse:not(.show) .navbar-nav .nav-item:not(.active) {
        display: none;
    }
}

@media (min-width: 768px) {
    .navbar .collapse .navbar-nav .nav-item {
        visibility: visible;
    }
}
</style>
<body>
<nav class="navbar navbar-expand-md fixed-top navbar-dark bg-dark">
    <div class="container">
        <div class="collapse" id="navbar1">
            <div class="navbar-nav flex-md-row">
                <a class="nav-item navbar-brand" href="#">Project name</a>
                <a class="nav-item nav-link" href="#">Home</a>
                <a class="nav-item nav-link" href="#">About</a>
                <a class="nav-item nav-link active" href="#">Contact</a>
            </div>
        </div>
        <button class="navbar-toggler align-self-start" type="button" data-toggle="collapse" data-target="#navbar1">
            <span class="navbar-toggler-icon"></span>
        </button>
    </div>
</nav>
</body>

Notice the @media queries go along with the navbar-expand-md breakpoint of 768px. You can change that to use a diffferent breakpoint if needed.

navbar-expand-sm - 576px
navbar-expand-lg - 992px
navbar-expand-xl - 1200px


There is another solution using duplicate navbar-nav links, but that would require extra markup and I think the CSS only solution above is cleaner.

Upvotes: 3

Shashank Agrawal
Shashank Agrawal

Reputation: 25797

Not available directly in bootstrap but you can write a small Javascript code here:

function displayActiveMenu() {
  if ($(window).width() >= 768) {
    // do nothing if we are not collapsed
    return;
  }

  var element = $('li.active', '#navbar').clone();
  $('#active-navbar').html(element);
}

displayActiveMenu(); // for the first time
$(window).on('resize', displayActiveMenu);
@media (max-width: 767px) {
  #active-navbar {
    float: right;
    margin: 0;
  }
  #active-navbar>li>a {
     padding-top: 15px;
     padding-bottom: 15px;
  }
}
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>

<body>
  <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>

          <!-- this is the new element -->
          <ul class="nav navbar-nav visible-xs" id="active-navbar">
          </ul>

          <a class="navbar-brand" href="#">Project name</a>
      </div>

      <div id="navbar" class="collapse navbar-collapse">
        <ul class="nav navbar-nav">
          <li class="active"><a href="#">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </div>
      <!--/.nav-collapse -->
    </div>
  </nav>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
    window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')
  </script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

</body>

</html>

Upvotes: 0

seethrough
seethrough

Reputation: 742

Have a try of this solution. Although this needs to be advanced to make able nav menu links be clickable.

<html lang="en">
  <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
        <nav class="navbar navbar-inverse navbar-fixed-top">
          <div class="container">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="#">Project name</a>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
              <ul class="nav navbar-nav">
                <li class="active"><a href="#">Home</a></li>
                <li><a href="#about">About</a></li>
                <li><a href="#contact">Contact</a></li>
              </ul>
            </div><!--/.nav-collapse -->
          </div>
        </nav>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
      <script>
          $ = window.jQuery
          $(document).ready(function(){
            $('.navbar-brand').attr('data-brand',$('.navbar-brand').text())
               var txtMenu = $('#navbar ul.navbar-nav .active').text();
               $('.navbar-brand').text(txtMenu)
               $('nav.navbar').on('hide.bs.collapse', function(){ 
               var txtM = $('#navbar ul.navbar-nav .active').text();
               $('.navbar-brand').text(txtM)
            })
            $('nav.navbar').on('show.bs.collapse', function(){ 
               var txtB = $('.navbar-brand').attr('data-brand');
               $('.navbar-brand').text(txtB)
            })
          })
      </script>
</body></html>

Upvotes: 0

Related Questions