Want to convert a Bootstrap 4 nav menu dropdown to a multi column container or mega menu? Or need a navbar that breaks navigation links into responsive Bootstrap 4 columns, even in WordPress. Check the attached image to know what I have meant.
The most popular Bootstrap 4 Beta Responsive Front-end framework just released 6 days before writing the article. By default in BS 4 navbar or nav, items are displayed as a single column list, one menu item below another. If we have 5 or 6 sub menu, it’s efficient. But what if we have 10 or more menus to show under a parent navigation. I hope nobody will like to display them as a single long list.
So here in the article I want to break the dropdown list in 2, 3, 4 or 5 columns, each containing 4 to 6 menus max and all can be seen once you click the parent nav link. The idea is, put a container inside dropdown-menu & setup row/columns and re-arrange navigation links in those columns to make it a mega menu. All with just a little handy jQuery code.
Typical Twitter Bootstrap 4 Nav Menu structure:
<li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a> <div class="dropdown-menu"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> <a class="dropdown-item" href="#">Or a link</a> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> <a class="dropdown-item" href="#">Or a link</a> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> <a class="dropdown-item" href="#">Or a link</a> </div> </li>
Rather displaying all item in one column I wish to break them as a wider container with 2 columns, each containing 6 links. To do all this, first I added a class `has-mega-menu` to the list containing toggler and the dropdown. From here, our customization starts. So my code would look like:
<li class="nav-item dropdown has-mega-menu"> <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Tech</a> <div class="dropdown-menu"> <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>
If you’re using WordPress, you need to add `has-mega-menu` class to the parent, which shows the container mega menu on click. Check this article to know: How to add class to WordPress menu.
Read all Fellow Tuts articles related to Bootstrap 4 and 3.
Mega menu multi column container – jQuery
Now Copy the jQuery code below to your JS file (without `script` tag) or inline before closing `body` tag including script
. For WordPress, put the same code in your theme specific JS file.
<script> $('li.has-mega-menu').each(function(idx, val){ var set = 6, //Number of links to display in each column buffer = [], dropdown = $('.dropdown-menu', this), children = dropdown.children(), cols = Math.ceil(children.length/set), col_class = 'col-6 col-md-' + (cols >= 5 ? '2' : (cols == 4 ? '3' : (cols == 3 ? '4' : 'x'))), container_class = 'px-0 container container-' + (cols == 2 ? 'sm' : (cols == 3 ? 'md' : (cols == 4 ? 'lg' : (cols >= 5 ? 'xl' : 'x')))); for(var i = 0; i < cols; i++) { buffer.push('<div class="' + col_class + '">'); children.slice(i*set, (i+1)*set).each(function(){ buffer.push($(this).prop('outerHTML')); }); buffer.push('</div>'); } dropdown.html('<div class="' + container_class + '"><div class="row">' + buffer.join('\n') + '</div></div>'); }); </script>
The code above convert Bootstrap 4 navs into a mega menu. Let’s understand what are we doing here. `set` is number of navigation links we wish to display per column. For example if I have 10-12 nav items, I would like to distribute them in 2 columns. So I will assign 5 or 6 to `set` variable in line #3.
Doing so will give me value of cols
to 2 using formula at line #7. Keep in mind that generally 4 columns is reasonable so adjust value of `set` according or 5 columns container is also available. Just have little space to hold each nav menu item in dropdown.
- buffer: Array to hold html in each iteration.
- children: Object holding all anchors in given dropdown
- cols: Number of columns to produce withing container/row
- col_class: Class assigned to each column. If it will have 3 columns, there will be
col-md-4
class - container_class: We wish to restrict container width for our dropdown in Bootstrap 4 navbar. So I have specified 4 CSS rules for this purpose. It will increase size of container with number of columns calculated.
- The first 4 rules are only for alpha versions of Bootstrap 4. For beta and upper versions, use last 4 media queries rules.
/*Only for Bootstrap version 4 alpha*/ .has-mega-menu .container-sm { max-width: 540px; } .has-mega-menu .container-md { max-width: 720px; } .has-mega-menu .container-lg { max-width: 960px; } .has-mega-menu .container-xl { max-width: 1140px; } /*Only for Bootstrap version 4 Beta and up*/ @media screen and (min-width: 576px) { .has-mega-menu .container-sm { width: 540px; } } @media screen and (min-width: 768px) { .has-mega-menu .container-md { width: 720px; } } @media screen and (min-width: 992px) { .has-mega-menu .container-lg { width: 960px; } } @media screen and (min-width: 1200px) { .has-mega-menu .container-xl { width: 1140px; } }
Mega Menu- Bootstrap 4 Nav Menu Dropdown in Multi Column List
Within for
loop, first we are putting a column around, then picking matching children within dropdown using jQuery `slice()` function. And pushing their into buffer
array variable. A set of 6 menu items will pick first 6 children then next upto 6. Each iteration of for loop adds a new column to container.
Lastly we joined the array, surrounded it with a container and row to convert Bootstrap 4 Nav Menu Dropdown in Multi Column Container List or somewhere Mega Menu.
we have provided you an amazing news site.You don’t need to search any news site anywhere.
here is available all news site entire the world..so please visit here easily
http://mayongnews.com/news/306/los-angeles-times.html
This is amazing and works perfectly. Really thankful this exists. Thank you so much!
Simpler way:
li.has-mega-menu ul {
columns: 3;
}
https://css-tricks.com/guide-responsive-friendly-css-columns/
Hi Amit
Thank you for this tutorial but I wonder if you consider extend it to add responsiveness ?
Having a responsive mega menu with bootstrap 4 would be great
Hi @robertosolini:disqus
BS4 is still in beta so it’s not safe to extend it as full flagged mega menu. Also there is nothing special in that, you just have to put container/container-fluid class within dropdown as I did & you can use it as regular container to organize menu content.
If you’re using any CMS, you would need to extend nav class (ex. nav-walker in WordPress) else in PHP or any other framework, it should be simple.
Hi Amit. Thanks for posting this. Very helpful. How can I reduce the width of the columns (and the width of the entire mega menu as well)?
Thanks! –John
Hi John,
If you reduce width of container, the column width will automatically decrease. You can do it by specifying lesser width given at line #21, #27, #33, #39 in CSS rules
Great. Thanks much, Amit!
Hi Amit
Why do you use max-width for the mega menu container width.
I get this with your code
https://uploads.disquscdn.com/images/0cf0bcce79e876e12b1073b202a0048ab84160237dfb6e9bc0aa815e9f5d52c4.png
https://codepen.io/anon/pen/QqLwPp
but if you replace max-width with width you solve the problem
Hi @sonia sonia maklouf
Thanks for update, I had created the original solution when Bootstrap 4 version alpha 6 was there and published article lately when beta released.
I have updated the CSS code section for Bootstrap 4 Nav Menu for Beta version.