Bootstrap 4 - Nav - Hiding extra menu items
Solution 1
You can use the navbar as this given example.
When you resize the browser the nav items will be moved inside to the drop-down if it not have an enough space.
[1]: http://jsfiddle.net/swasatz/3fn4d5oq/
Snippet Demo
Open the snippet in full page mode and resize the browser to see the changes.
$(document).ready(function () {
var menu = $("#nav-bar-filter"),
subMenu = $(".subfilter"),
more = $("#more-nav"),
parent = $(".filter-wrapper"),
ww = $(window).width(),
smw = more.outerWidth();
menu.children("li").each(function () {
var w = $(this).outerWidth();
if (w > smw) smw = w + 20;
return smw
});
more.css('width', smw);
function contract() {
var w = 0,
outerWidth = parent.width() - smw - 50;
for (i = 0; i < menu.children("li").size(); i++) {
w += menu.children("li").eq(i).outerWidth();
if (w > outerWidth) {
menu.children("li").eq(i - 1).nextAll()
.detach()
.css('opacity', 0)
.prependTo(".subfilter")
.stop().animate({
'opacity': 1
}, 300);
break;
}
}
}
function expand() {
var w = 0,
outerWidth = parent.width() - smw - 20;
menu.children("li").each(function () {
w += $(this).outerWidth();
return w;
});
for (i = 0; i < subMenu.children("li").size(); i++) {
w += subMenu.children("li").eq(i).outerWidth();
if (w > outerWidth) {
var a = 0;
while (a < i) {
subMenu.children("li").eq(a)
.css('opacity', 0)
.detach()
.appendTo("#nav-bar-filter")
.stop().animate({
'opacity': 1
}, 300);
a++;
}
break;
}
}
}
contract();
$(window).on("resize", function (e) {
($(window).width() > ww) ? expand() : contract();
ww = $(window).width();
});
});
body {
font-family: verdana;
min-width: 250px;
}
ul#more-nav, ul#nav-bar-filter {
display: inline-block;
vertical-align: top;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
li {
padding: 4px 8px 4px 8px;
margin: 0;
}
#nav-bar-filter li {
display: inline-block;
font-weight: bold;
}
a {
text-decoration: none;
color: #666;
font-size: 13px;
}
.filter-wrapper {
width: 100%;
background: #eee;
padding: 5px 10px 5px 10px;
}
#more-nav {
float: right;
}
.subfilter{
padding-top: 10px;
}
.subfilter li {
margin: 0 0 0 20px;
padding: 5px 0 0 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="twelve columns filter-wrapper">
<ul class="nav-bar-filter" id="nav-bar-filter">
<li><a href="#">All</a>
</li>
<li><a href="#">Small</a>
</li>
<li><a href="#">Medium</a>
</li>
<li><a href="#">Extra large</a>
</li>
<li><a href="#">Text</a>
</li>
<li><a href="#">Small-1</a>
</li>
<li><a href="#">Medium-1</a>
</li>
<li><a href="#">Extra large text</a>
</li>
<li><a href="#">Large text</a>
</li>
<li><a href="#">Another text</a>
</li>
<li><a href="#">text</a>
</li>
</ul>
<ul id="more-nav">
<li><b><a href="#">More ></a></b>
<ul class="subfilter"></ul>
</li>
</ul>
</div>
Solution 2
For the menu-items that you would like to view as hidden on mobile devices, wrap a span around the list-item(s) that you want hidden and add the bootstrap 4 beta hidden values, like this.
<span class="d-none d-xs-block">
<li class="nav-item">
<a class="nav-link" href="#">aaaaaaaa 1234 </a>
</li>
</span>
You can also apply the class to an <a>
tag to hide that specific link within the drop-down menu. Furthermore, tinker with the d-xs-block
class to meet your specifications.
I would like to provide you with a couple of sources to help guide you with regards to hiding elements at specific breakpoints.
Solution 3
Here is another option for Bootstrap 4 that will collapse the extra Navbar items into a dropdown menu on the right side. Use some logic (this is using jQuery) to control the placement of items in the menu...
function (menu,maxHeight) {
var nav = $(menu);
// check height of menu
var navHeight = nav.innerHeight();
// when the height is taller the navbar has wrapped onto 2 lines
if (navHeight >= maxHeight) {
$(menu + ' .dropdown').removeClass('d-none');
$(".navbar-nav").removeClass('w-auto').addClass("w-100");
while (navHeight > maxHeight) {
// add child to dropdown
var children = nav.children(menu + ' li:not(:last-child)');
var count = children.length;
$(children[count - 1]).prependTo(menu + ' .dropdown-menu');
navHeight = nav.innerHeight();
}
$(".navbar-nav").addClass("w-auto").removeClass('w-100');
}
else {
var collapsed = $(menu + ' .dropdown-menu').children(menu + ' li');
if (collapsed.length===0) {
$(menu + ' .dropdown').addClass('d-none');
}
while (navHeight < maxHeight && (nav.children(menu + ' li').length > 0) && collapsed.length > 0) {
// remove child from dropdown
collapsed = $(menu + ' .dropdown-menu').children('li');
$(collapsed[0]).insertBefore(nav.children(menu + ' li:last-child'));
navHeight = nav.innerHeight();
}
if (navHeight > maxHeight) {
autocollapse(menu,maxHeight);
}
}
}
https://www.codeply.com/go/IETSah3bFG
janeh
Updated on June 24, 2022Comments
-
janeh almost 2 years
I have a Bootstrap 4 layout similar to this: https://www.codeply.com/go/yLO99L66MD
When there are too many nav items, I want them to be hidden, so I added this:
nav {overflow:hidden}
. This does the job, but the problem is that it also hides my dropdown menu. How can I hide extra menu items but still allow dropdowns to show up for visible items?<nav class="navbar navbar-expand-md navbar-dark bg-dark"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarsExampleDefault"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a> <div class="dropdown-menu" aria-labelledby="dropdown01"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </li> <li class="nav-item"> <a class="nav-link" href="#">aaaaaaaa aaaaa </a> </li> <li class="nav-item"> <a class="nav-link" href="#">bbbbbb bbbbb</a> </li> <li class="nav-item"> <a class="nav-link" href="#">cccccccc cccccccc </a> </li> <li class="nav-item"> <a class="nav-link" href="#">dddd ddddddddd </a> </li> <li class="nav-item"> <a class="nav-link" href="#">eeeeeeeeeeeeeeeeee cv kbc vxckjvhkxcv </a> </li> </ul> </div> </nav> <div class="container"> <div class="starter-template"> <h1>Bootstrap starter template</h1> <p class="lead">Use this document as a way to quickly start any new project. <br> All you get is this text and a mostly barebones HTML document.</p> </div> </div> <!-- /.container -->
-
janeh over 6 yearsThat would not be ideal, I can't count on 4 items fitting in the menu - what if somebody creates 2 or 3 items with very very long names? The 3rd one would stick outside of menu bounds. That's the tricky part is that menus are dynamically generated from user settings.
-
Taufik Nur Rahmanda over 6 years@janehouse I've updated my answer with corrected fiddle too, please check :-)
-
janeh over 6 yearsThanks, tho, <span> inside <ul> is not a valid html
-
Mister Moody over 6 yearsI had failed to realize that.
-
horbor over 6 yearsI faced the similar problem and there is no need to use any extra JS or other tricks, please take a look at my answer stackoverflow.com/questions/46477802/…
-
Satheesh Kumar over 6 years@horbor, Here the issue is not showing/hiding the nav items with appropriate to screen size. The actual scenario is the user has a number of nav items which doesn't have enough space to show. For that, I have come up with the solution to move the extra nav items into dropdown by using jquery. Hope you got a clear idea now. Thanks :)