Time for a sensible train in flexbox! On this tutorial we are going to use flexbox to create a mobile-first, responsive, toggleable navigation bar with completely different layouts for cellular, pill, and desktop screens.
This tutorial has been up to date to incorporate a responsive submenu and pure JavaScript as a substitute of jQuery.Responsive Flexbox Navigation Bar
Right here’s an entire video model of the tutorial. Observe together with us over on our Envato Tuts+ YouTube channel:
Flexbox is Excellent for Responsive Navigation
Flexbox is a flexible format module with which we are able to create one-dimensional layouts that require flexibility, equivalent to responsive menus. Utilizing flexbox’s ordering, alignment, and sizing properties, we are able to construct navigation bars that adapt their layouts to the viewport measurement whereas maintaining the HTML define logical and accessible.
On this tutorial, we’ll look into the best way to create a responsive navigation bar with flexbox. Our flexbox navigation could have three completely different layouts, relying on the viewport measurement:
- a cellular format through which solely the emblem and a toggle button might be seen by default and customers can open and shut the menu utilizing the toggle,
- a pill format through which we will present two call-to-action buttons between the emblem and toggle within the default state and the remainder of the menu will stay toggleable,
- a desktop format through which all of the menu gadgets, apart from the toggle button, might be seen on the display screen.
We’ll use media queries to detect the viewport measurement of the consumer’s browser. Our responsive navigation bar might be mobile-first, so we are going to create the cellular format first. Then, we are going to add the tablet- and desktop-specific CSS utilizing min-width
media queries.
The navigation bar may also have a JavaScript-based dropdown submenu that opens and closes when the consumer clicks the mother or father menu merchandise.
Right here’s how the menu will look on cellular:
Right here’s the pill model:
And, that is the way it will look on desktop:
You can even take a look at, fork, and mess around with the interactive demo on CodePen:
New to Flexbox?
Should you aren’t used to flexbox, or want a refresher, these newbie guides provides you with all the talents it’s essential full this tutorial:
1. Create the HTML
The HTML is an easy <ul>
checklist, as you possibly can see under. The .menu
class would be the flex container and the checklist gadgets would be the flex gadgets. Their order will adapt to the viewport measurement of the consumer’s machine. For instance, the Log In and Signal Up buttons will come first on cellular, however might be displayed on the finish of the menu on desktop. We’ll obtain this impact by making use of flexbox’s ordering properties.
<nav> <ul class="menu"> <li class="brand"><a href="#">Artistic Thoughts Company</a></li> <li class="merchandise"><a href="#">House</a></li> <li class="merchandise"><a href="#">About</a></li> <li class="merchandise has-submenu"> <a tabindex="0">Providers</a> <ul class="submenu"> <li class="subitem"><a href="#">Design</a></li> <li class="subitem"><a href="#">Improvement</a></li> <li class="subitem"><a href="#">search engine optimisation</a></li> <li class="subitem"><a href="#">Copywriting</a></li> </ul> </li> <li class="merchandise has-submenu"> <a tabindex="0">Plans</a> <ul class="submenu"> <li class="subitem"><a href="#">Freelancer</a></li> <li class="subitem"><a href="#">Startup</a></li> <li class="subitem"><a href="#">Enterprise</a></li> </ul> </li> <li class="merchandise"><a href="#">Weblog</a></li> <li class="merchandise"><a href="#">Contact</a> </li> <li class="merchandise button"><a href="#">Log In</a></li> <li class="merchandise button secondary"><a href="#">Signal Up</a></li> <li class="toggle"><a href="#"><i class="fas fa-bars"></i></a></li> </ul> </nav>
You could have most likely observed that menu gadgets with a submenu (“Providers” and “Plans”) have an <a>
tag with out an href
attribute. We do that as a result of these “empty” mother or father menu gadgets don’t result in some other web page–they simply open and shut the submenu. Utilizing the anchor tag with out href is permitted and prevents the web page from leaping up on small screens when the consumer clicks the empty menu merchandise to open or shut the submenu.
We additionally add the tabindex="0"
attribute to <a>
parts with out a href
attribute. It is because empty <a>
tags are omitted from the default tab order, so we have to put them again to the tabbing order with the tabindex
attribute to maintain the menu keyboard-accessible.
Notice: the toggle button on the finish of the checklist makes use of a Font Superior icon. To make the demo work, you’ll want so as to add the Font Superior library to the <head>
part of the HTML doc from CDN utilizing the code under. (If you wish to make the menu work offline, you’ll must host Font Superior domestically.)
<hyperlink rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
2. Add Some Primary Styling
For primary styling, I’ve set some default values and colours, nonetheless you should use any of your personal type guidelines as properly:
/* Primary styling */ * { box-sizing: border-box; padding: 0; margin: 0; } physique { font-family: sans-serif; font-size: 16px; } nav { background: #222; padding: 0 15px; } a { shade: white; text-decoration: none; } .menu, .submenu { list-style-type: none; } .brand { font-size: 20px; padding: 7.5px 10px 7.5px 0; } .merchandise { padding: 10px; } .merchandise.button { padding: 9px 5px; } .merchandise:not(.button) a:hover, .merchandise a:hover::after { shade: #ccc; }
3. Begin With the Cell Navigation
As our navigation might be mobile-first, we begin with the cellular format. Most responsive flexbox menus use column-based layouts for cellular, as menu gadgets could be shortly packed under one another by including the flex-direction: column;
rule to the flex container. Despite the fact that this is a superb answer, we received’t use it in our instance.
As a substitute, we are going to create a wrapping, row-based format for cellular in order that we are able to show the emblem and toggle button subsequent to one another on prime of the menu.
The CSS trick right here is that we make common menu gadgets equivalent to House and About span throughout your complete container utilizing the width: 100%;
rule. So, flexbox will show them under one another, whereas the emblem and toggle will retain their pure sizes and sit on prime of the navbar in the identical row.
Within the CSS under, we additionally use the justify-content
and align-items
properties to align the flex gadgets horizontally and vertically. Apart from this, we conceal the .merchandise
parts utilizing the show: none;
rule. Menu gadgets might be solely revealed when the consumer clicks the toggle button. The .lively
class just isn’t within the HTML code, we are going to dynamically add it with JavaScript.
/* Cell menu */ .menu { show: flex; flex-wrap: wrap; justify-content: space-between; align-items: heart; } .menu li a { show: block; padding: 15px 5px; } .menu li.subitem a { padding: 15px; } .toggle { order: 1; font-size: 20px; } .merchandise.button { order: 2; } .merchandise { order: 3; width: 100%; text-align: heart; show: none; } .lively .merchandise { show: block; } .button.secondary { /* divider between buttons and menu hyperlinks */ border-bottom: 1px #444 stable; }
As you possibly can see above, we now have additionally modified the order of menu gadgets with the assistance of the order
property. Our HTML define follows a logical order. That is how we wish display screen reader customers and search engine bots to undergo the menu.
Nonetheless, within the cellular format, we wish to present the emblem and toggle button on prime of the menu. We additionally wish to show the 2 call-to-action buttons (“Log In” and “Signal Up”) earlier than common menu gadgets. So, we arrange the next order:
-
.brand
will get theorder: 0;
worth, as it will likely be the primary merchandise (nonetheless, as that is the default worth oforder
, we don’t want so as to add it to the CSS), -
.toggle
will get1
, because it comes proper after.brand
, -
.merchandise.button
belonging to the Log In and Signal Up buttons will get2
, - and
.merchandise
belonging to the remainder of menu gadgets will get3
.
4. Fashion the Submenu
As that is mobile-first navigation, we’ll primarily type the submenu with cellular screens in thoughts. This can be a nice approach, because it’s normally more durable to create a user-friendly submenu for small screens than for bigger ones. Then, we are able to use the identical submenu format for pill screens as properly. For desktop, we’ll solely want to vary the positioning of the submenu.
By default, the submenu is about to show: none;
and might be solely revealed when the consumer clicks the mother or father menu merchandise. We’ll add the required JavaScript performance within the subsequent two steps earlier than shifting on to the pill menu.
/* Submenu up from cellular screens */ .submenu { show: none; } .submenu-active .submenu { show: block; } .has-submenu i { font-size: 12px; } .has-submenu > a::after { font-family: "Font Superior 5 Free"; font-size: 12px; line-height: 16px; font-weight: 900; content material: "f078"; shade: white; padding-left: 5px; } .subitem a { padding: 10px 15px; } .submenu-active { background-color: #111; border-radius: 3px; }
As you possibly can see above, now we add the Font Superior icons utilizing CSS as a substitute of HTML. These icons we add utilizing the ::after
pseudo component would be the little down arrows proven subsequent to every menu merchandise that has a submenu.
Should you bear in mind we added the Font Superior icon for the toggle button with HTML in Step 1. It is because the toggle button might be focused with JavaScript, so it needs to be current within the DOM. Nonetheless, the down arrows listed here are simply type parts that point out the presence of the submenu. Since no performance depends on them, it’s higher so as to add them with CSS.
5. Add the Toggle Performance with JavaScript
We’ll arrange the toggle performance by including a click on occasion listener to the toggle button that opens and closes the menu on cellular. Within the JavaScript code, we are going to use the ES6 syntax that offers us entry to the const
and let
notation and the for...of
loop and already has good browser assist.
For the customized JavaScript, create an empty script.js
file and add it to the HTML earlier than the closing </physique>
tag:
<script src="https://webdesign.tutsplus.com/tutorials/script.js"></script>
And right here’s the JavaSript code accountable for the toggle performance:
const toggle = doc.querySelector(".toggle"); const menu = doc.querySelector(".menu"); /* Toggle cellular menu */ perform toggleMenu() { if (menu.classList.accommodates("lively")) { menu.classList.take away("lively"); // provides the menu (hamburger) icon toggle.querySelector("a").innerHTML = "<i class=’fas fa-bars’></i>"; } else { menu.classList.add("lively"); // provides the shut (x) icon toggle.querySelector("a").innerHTML = "<i class=’fas fa-times’></i>"; } } /* Occasion Listener */ toggle.addEventListener("click on", toggleMenu, false);
-
First, we choose the menu and the toggle button utilizing the
querySelector()
technique in order that we are able to entry them with JavaScript. - Then, we add the customized
toggleMenu()
perform that might be referred to as when the toggle is clicked. - Lastly, we add the occasion listener that might be listening to the press occasion utilizing the
addEventListener()
technique.
6. Add the Dropdown Performance with JavaScript
Now, when the consumer clicks the toggle button, the menu is activated and deactivated, nonetheless, the submenu remains to be hidden. We’ll add this performance with the next JavaScript:
const gadgets = doc.querySelectorAll(".merchandise"); /* Activate Submenu */ perform toggleItem() { if (this.classList.accommodates("submenu-active")) { this.classList.take away("submenu-active"); } else if (menu.querySelector(".submenu-active")) { menu.querySelector(".submenu-active").classList.take away("submenu-active"); this.classList.add("submenu-active"); } else { this.classList.add("submenu-active"); } } /* Occasion Listeners */ for (let merchandise of things) { if (merchandise.querySelector(".submenu")) { merchandise.addEventListener("click on", toggleItem, false); merchandise.addEventListener("keypress", toggleItem, false); } }
Right here, we add the .submenu-active
class to every menu merchandise with a submenu when the consumer clicks it.
- First, we choose all menu gadgets with the
querySelectorAll()
technique that returns a node checklist (slightly than a single component likequerySelector()
). - Within the customized
toggleItem()
perform, we add and take away.submenu-active
to/from the clicked component. Notice that within theelse if
block, we take away the category from each different menu gadgets that had been beforehand opened. This fashion, it received’t occur that two submenus are open on the identical time, as they will cowl one another on desktop. - Lastly, we loop via the
gadgets
classList utilizing afor...of
loop. Throughout theif
block, we add two occasion listeners to menu gadgets which have a submenu: one for theclick on
occasion for normal customers who entry the menu by clicking or tapping, and one for thekeypress
occasion for keyboard customers.
7. Create the Pill Menu
We’ll create the pill format utilizing a min-width
media question. On pill, 4 menu gadgets might be seen by default: the emblem, the 2 call-to-action buttons (“Log In” and “Signal Up”), and the toggle. To make all the pieces fairly, our CSS will:
- change the
order
of the menu gadgets to adapt the format to pill viewports, - realign the gadgets (see the reason under),
- make the Log In and Signal Up buttons appear like actual buttons (within the cellular format, they appear like hyperlinks, as they’re a part of the toggleable dropdown checklist).
In code:
/* Pill menu */ @media all and (min-width: 700px) { .menu { justify-content: heart; } .brand { flex: 1; } .merchandise.button { width: auto; order: 1; show: block; } .toggle { flex: 1; text-align: proper; order: 2; } /* Button up from pill display screen */ .menu li.button a { padding: 10px 15px; margin: 5px 0; } .button a { background: #0080ff; border: 1px royalblue stable; } .button.secondary { border: 0; } .button.secondary a { background: clear; border: 1px #0080ff stable; } .button a:hover { text-decoration: none; } .button:not(.secondary) a:hover { background: royalblue; border-color: darkblue; } }
Within the pill format, menu gadgets are aligned otherwise. Should you check out the 4 seen menu gadgets, you will note that the 2 buttons are displayed within the heart, whereas the emblem and toggle are pushed to the left and proper finish of the container:
We will obtain this impact utilizing the flex: 1;
CSS rule. The flex
property is a shorthand for flex-grow
, flex-shrink
, and flex-basis
. It will possibly exist with many various worth combos. When it’s declared with just one worth, it belongs to flex-grow
, with flex-shrink
and flex-basis
maintaining their default values.
Within the CSS above, we now have added the flex: 1;
rule to the .brand
and .toggle
parts. On this method, we are able to inform the browser that if there’s any constructive area on the display screen, we wish to share it between these two parts. Because the Log In and Signal Up buttons retain their default 0
worth for flex-grow
, they received’t get something from the additional area. So, they’ll keep within the heart of the container, as they adhere to the justify-content: heart;
rule set on the flex container.
8. Create the Desktop Menu
The desktop menu hides the toggle, units again the unique order and pure width of every merchandise, and repositions the submenu.
It’s vital to take into account that the tablet-specific guidelines additionally apply to the desktop menu. It is because right here, the viewport width is bigger than each 700px
and 960px
, so each media queries take impact. So, .brand
retains its flex: 1;
property and pushes the remainder of the gadgets to the tip of the container.
/* Desktop menu */ @media all and (min-width: 960px) { .menu { align-items: flex-start; flex-wrap: nowrap; background: none; } .brand { order: 0; } .merchandise { order: 1; place: relative; show: block; width: auto; } .button { order: 2; } .submenu-active .submenu { show: block; place: absolute; left: 0; prime: 68px; background: #111; } .toggle { show: none; } .submenu-active { border-radius: 0; } }
9. Let Customers Shut the Submenu By Clicking Anyplace on the Web page
Now there’s just one step again. Because the dropdown menu is activated on the press occasion, it doesn’t shut routinely when the consumer hovers away from the highest menu merchandise. That is particularly annoying on desktop the place the dropdown can cowl the content material.
So, it might be good to allow customers to shut the submenu by clicking anyplace on the display screen. We will add the characteristic with JavaScript:
/* Shut Submenu From Anyplace */ perform closeSubmenu(e) { if (menu.querySelector(".submenu-active")) { let isClickInside = menu .querySelector(".submenu-active") .accommodates(e.goal); if (!isClickInside && menu.querySelector(".submenu-active")) { menu.querySelector(".submenu-active").classList.take away("submenu-active"); } } } /* Occasion listener */ doc.addEventListener("click on", closeSubmenu, false);
The customized closeSubmenu()
perform checks if there’s an open submenu on the display screen, and if sure, it additionally checks if the consumer clicked inside it with the assistance of the goal
property. If the consumer clicked anyplace else on the display screen, the .submenu-active
class might be eliminated, and the submenu will shut itself. We add the occasion listener to the doc
object, as we wish to hear for clicks on the entire web page.
You’ve Constructed a Responsive Navigation Bar With Flexbox and JavaScript!
Our mobile-first, responsive navigation bar is up and operating in three completely different layouts.
Right here’s a reminder of the tip outcome:
Flexbox is a good software to implement advanced layouts with none tweaks. Should you mix flexbox’s alignment, ordering, and sizing properties with media queries, you possibly can create completely different layouts for various viewports with out having to control the HTML supply code.
Helpful Assets
For an inventory of finest practices you need to take into account when constructing responsive navigation, or in case you want a assist getting began with occasion listeners in JavaScript, check out these newcomers’ guides:
Lastly, in case you are curious about how you should use flexbox in your on a regular basis work, take a look at these different sensible tutorials–each helps you study by constructing issues you possibly can truly use: