There is a standard, standard Bootstrap Navbar taken from the Bootstrap documentation. The principle of its work, I think, is familiar to everyone. When the width reaches 768px, a “ мобильное ” menu appears, and all the elements are immediately hidden in under the “ гамбургер ” menu. How to remake the mechanism so that only non-fitting elements are hidden in the menu?

  • Do not fit on the right you mean? - Vladimir Gamalyan
  • @VladimirGamalian yes. An element that does not fit on the right should be hidden in the "hamburger" menu. The rest remain in the navbar as long as they fit into it. - David Arutiunian
  • If in the forehead, it is possible, depending on the width of the screen, to add a class that will leave the menu item visible (for example, .navbar-brand). Can be automated with js. - Vladimir Gamalyan

1 answer 1

How to collapse only those menu items that do not fit on the screen

1. HTML

Here is a basic example of a navigation bar from the Bootstrap site.

Elements that do not collapse on a narrow screen should be in the <div class="navbar-header"> block, so as not to interfere with the <button ... class="navbar-toggle collapsed" ...> switch on the right edge.

Therefore, you need to figure out which menu items will remain on a narrow screen, and move them from the <div class="collapse navbar-collapse" ...> block to the <div class="navbar-header"> block.

And modify the personal CSS class for them so that they look normal on a narrow screen.

https://jsfiddle.net/glebkema/vju5mueq/

 @media (max-width: 767px) { .navbar-dont-collapse { float: left; margin: 0 !important; } .navbar-dont-collapse > li { float: left; } .navbar-dont-collapse > li > a { padding-top: 15px !important; padding-bottom: 15px !important; } } 
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <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="#">Brand</a> <ul class="nav navbar-nav navbar-dont-collapse"> <li><a href="#">Do</a></li> <li><a href="#">Not</a></li> <li><a href="#">Collapse</a></li> <li><a href="#">Us</a></li> </ul> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></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 role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left" role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></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 role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script> 

2. jQuery

The script removes the menu items under the "hamburger" and returns them back. To fill the panel without transitions to the second line, you need to know the width of each item. But when the item is in the collapsed part of the menu, its width is zero and it is unclear how much space it will need. Therefore, we do this:

  1. Prepare two lists ul . The list in the navbar-collapse block will be collapsed along with the rest of the menu, and the list in the navbar-header block will be constantly visible.
  2. We place all menu items in the visible part in order to measure and remember their width when loading the page.
  3. After that, and with each change of the page size, we throw extra items into the folding part of the menu or pick up the missing items back.

jsfiddle bootply codepen

 $(document).ready(function() { var ID_HIDE = '#hide-items'; var ID_SHOW = '#show-items'; var selectHide = $( ID_HIDE ); var selectShow = $( ID_SHOW ); /* запоминаем размеры, пока все элементы на виду */ /* 1) у элементов в свёрнутом списке ширина становится нулевой */ /* 2) selectShow.outerWidth(true) подводит, когда элементы встают в 2 строки */ var widthShow = 0; var widthItem = []; $( ID_SHOW + '>li' ).each(function( index ) { widthShow += widthItem[index] = $( this ).outerWidth(true); }); var indexLastShown = widthItem.length - 1; /* посчитаем, когда будем уверены, что navbar-toggle тоже виден */ var widthOccupied = 0; /* признак того, что обрабатываем загрузку страницы, а не изменение размеров */ var widthCurrent = 0; checkNavbar(); $(window).resize( checkNavbar ); function checkNavbar() { var widthNew = document.documentElement.clientWidth; if ( widthNew != widthCurrent && widthNew < 768 ) { if ( widthOccupied == 0 ) { widthOccupied = $( '.navbar-brand' ).outerWidth(true) + $( '.navbar-toggle' ).outerWidth(true); } var widthFree = widthNew - widthOccupied - widthShow; /* после загрузки или сужения страницы - прячем всё, что не помещается */ if ( widthCurrent == 0 || widthNew < widthCurrent ) { while ( indexLastShown >= 0 && widthFree <= 0 ) { $( ID_SHOW + '>li:last-child' ).prependTo( selectHide ); widthFree += widthItem[indexLastShown]; widthShow -= widthItem[indexLastShown]; indexLastShown--; }; /* после расширения страницы - добавляем всё, что поместится */ } else { while ( (indexLastShown + 1) < widthItem.length && widthFree > widthItem[indexLastShown + 1] ) { $( ID_HIDE + '>li:first-child' ).appendTo( selectShow ); widthFree -= widthItem[indexLastShown + 1]; widthShow += widthItem[indexLastShown + 1]; indexLastShown++; } } widthCurrent = widthNew; } } }); 
 @media (max-width: 767px) { #show-items { float: left; margin: 0 !important; } #show-items > li { float: left; } #show-items > li > a { padding-top: 15px !important; padding-bottom: 15px !important; } #show-items .open .dropdown-menu { position: absolute; right: 0; left: auto; padding: 5px 0; margin: 2px 0 0; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0,0,0,.15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175); box-shadow: 0 6px 12px rgba(0,0,0,.175); } #show-items .open .dropdown-menu > li > a { color: #000; padding: 3px 20px; line-height: 1.42857143; } #show-items .open .dropdown-menu > li > a:hover, #show-items .open .dropdown-menu > li > a:focus { color: #333; background-color: #e7e7e7 !important; background-image: none; } #show-items .open .dropdown-menu > .active > a, #show-items .open .dropdown-menu > .active > a:hover, #show-items .open .dropdown-menu > .active > a:focus { color: #555; background-color: #e7e7e7 !important; } #show-items .open .dropdown-menu > .disabled > a, #show-items .open .dropdown-menu > .disabled > a:hover, #show-items .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } 
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <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="#">Brand</a> <ul id="show-items" class="nav navbar-nav"> <li><a href="#">First link</a></li> <li><a href="#">2nd</a></li> <li class="active"><a href="#">Active link</a></li> <li><a href="#">One more very long link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></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 role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul id="hide-items" class="nav navbar-nav"> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Right 1</a></li> <li><a href="#">Right 2</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script> 

  • No, I did not mean that some elements should remain on a narrow screen. Everything should be dynamic. Depending on the width, the element that does not fit is transferred to the navbar-collapse. - David Arutiunian
  • @DavidArutiunian Option to plan manually through media queries suitable? Or do you need a script that will transfer elements from an open area to a collapsed one and back? - Gleb Kemarsky
  • I think the script will be easier. In this case, speed is not so important. - David Arutiunian
  • @DavidArutiunian Added a solution with a script in response. Check, please. - Gleb Kemarsky
  • Yes, in principle, everything works, although I have already done it, but thanks a lot! - David Arutiunian