Creating responsive navigation bars with a hamburger menu
I've set out to learn more about navigation bars and how to properly create them, i'd like to create the navigation bar as shown in the image and i'm having some issues.
1 - I usually create a navbar in the structure below, add flex to main-header and main-nav. But now i need to add the buttons at the end of the row. I'd usually add a div and put those 2 buttons in it and assign them flex-end but this did not work. How can i get them on the flex-end side whilst keeping it responsive?
2- I mostly refer to this video of Kevin on creating mobile button/hamburger menu but i find it quite specific towards the website he's making himself. ( https://www.youtube.com/watch?v=HbBMp6yUXO0), I've tried some of his implementations like the aria stuff and sr-only but this feels a bit to advanced and often does not work. What are the basic components i need to know to create simple hamburger menu's?
3- the header contains the navbar but also the "A modern publishing platform" with buttons section, should i put it all in a section since they share the same background?
Kevin Powell
YouTube
Responsive navbar tutorial using HTML CSS & JS
You can find the Frontend Mentor project here: https://www.frontendmentor.io/challenges/space-tourism-multipage-website-gRWj1URZ3
And the free Scrimba course here: https://scrimba.com/learn/spacetravel
🔗 Links
✅ Why I use HSL: https://youtu.be/Ab9pHqhsfcc
✅ More on feature queries (@supports): https://youtu.be/wPI8CEoheSk
✅ More info on .sr-...
22 Replies
1. If you give the nav ".main-nav" a value of
flex: 1;
that should force it to take up all the available width and push your button container to the right.
2. I haven't watched that video for a long time....
What Kevin is doing is using data-attributes (eg "data-visible") to control the visibility of the navbar. This could equally be done by using a class name of your choice, eg "nav-visible". The advantage of using data attributes is that they don't tend to get modified when adjusting the styling. It is all too easy (and common) to change the name of a class for styling reasons and inadvertently breaking the JavaScript.
The reason why Kevin uses the aria attributes is for screen readers. These are strongly recommended and can indeed be used as alternative selectors much like any other data attribute. For example he is toggling the aria-expanded on the button to let the know the screen reader "know" that the nav is expanded. He is then using this same attribute as a CSS selector to toggle the icon itself via the CSS
However, the basics of the hamburger menu are:
- For smaller screens, the menu items (navbar) are hidden to the viewer. This can be however you like, eg by sliding out, scaling down, or even just by setting display: hidden. I would suggest that that most common method is to have them placed outside of the viewport using transform translate.
- On clicking the button, the JavaScript updates the nav bar to set it ( via use of the data attribute or class name) to "visible".
- The CSS selector for this "visible" state will have the appropriate properties that toggle the styles that you had used to hide the nav bar. For example if you had used "transform translate" to slide it out to "300px", this "visible" class would set that to "0px" and thus slide it back in.
Kevins video then goes further by setting different breakpoints, padding, background images etc. but you don't need to worry about these as regards the basic functionality itself.
3. This may well depend on other factors such as how this background and the header contents react to different screen sizes. However, as both the nav area and this "hero" section do appear to have a common background it does seem to make sense to have them within a common container.Is there a reason why he uses id's for styling and not classes? i know he needs a id for the javascript part but cant you just use a seperate id and style with classes. I also noticed he had a id "primary-nav flex", how does flex automaticly apply on the ID? i tried it in my code and it didnt work
Is there a reason why he uses id's for styling and not classes?Where is he using an id for styling? I have just skimmed through it again and can't see anywhere were he does that.
I also noticed he had a id "primary-nav flex", how does flex automaticly apply on the ID?I presume you mean "class" and not "id". As he explains at min 3:40 he has set up a few utility classes, one of which is called "flex". He doesn't actually show that class in the video but it is probably no more than this You can see this class at min 4:40 - line 128 in his code. It also has a gap defined using a custom property with a default fallback value. These sort of utility classes are useful if you want to apply the property to multiple elements.
ah that might be it, i also noticed sr-only didnt apply, does it need some import or setup to work? i just added it to a button and its still visible
He won't have used any imports for this demo.
I can't see the sr-only class in the video but it probaly looks something like this (I copied this from Tailwind):
This class "hides" the element from the viewport but doesn't remove it from the DOM so it is still accesible.
he applied it on the button but i didnt see the css atttributes so i assume just applying the class itself hid the button
I don't know if he mentions it specifically as I have really just skimmed through the video but Kevin does link to this article within the video description: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html
i see, thanks!
are navbars with mobile menus always this comprehensive to create?
The first thing to bear in mind is that, as with most things, there are many ways to create a mobile menu. Both in terms of code and in visual effect.
In this video, Kevin, rightly so, clearly wanted to cover all accessibility issues, hence the use of aria labels etc. He is also integrating it with an existing design which may make it seem more complicated than the basic code really is.
As I mentioned earlier, you could even do a "simple" mobile menu even without the need for any JavaScript at all.
In this example, https://codepen.io/cbolson/pen/YzbmKrQ, I have used a "label" as the icon button combined with a hidden checkbox. The label toggles the checkbox and the CSS selector,
:checked
, toggles the display of the menu accordingly. It is also responsive. However this solution, whilst much simpler, is not as accessible as Kevins complete video as it lacks any indication (for screen readers) as to whether the menu is "open" or "hidden".
Also, bear in mind that that video is now over 2 years old. There may well be simpler ways to do some of the things that he does, especially within the CSS, for example by making use of the :has() selector.
Whilst the video is very good, I can see why it might seem complicated to somebody starting out, especially as he glosses over things like the sr-only class. I have no doubt there are simpler videos out there which may not be as complete in terms of accessibility but might be better starting points for you..il take a look at the codepen, thanks!
Even that is slightly overly complicated as I actually created it to make the animated harmburger menu icon as a demo.
This part could be much simpler if you just use a couple of svg icons just as Kevin does.
I have created another codepen for you.
This time using JavaScript for the toggle but without any extra "stuff".
https://codepen.io/cbolson/pen/NWVQWyP
How come there are 2 svg's but only 1 hamburger icon? what does the other svg do? also where do you get your icons from? i just heroicons or ionicons
The second one is the "close" icon.
It is intally hidden (scale 0) and then revealed when the parent gets the "visible" class.
These icons are from here: https://tabler.io/icons
thanks, il have to practice creating these since they are used on most sites. it does feel like a bit of a learning curve
For this sort of icon you don't need to create them yourself. That site (other icon sites are available) provides you with the icon and there are different ways to include them - via a library, as an image, CSS code or, as I tend to do especially for demo code, directly as the SVG itself.
i just use the cdn link and then copy it in
I tend to just copy the SVG itself using the "copy SVG" button. For a demo or test this is fine. There is no need to include anything via the CDN.
i see, thanks! for actual sites do you download them?
When I want to use a CDN for icons, I tend to lean towards Google fonts material icons https://fonts.google.com/icons
But again, more for demo code than anything.
The most well-known one is font-awesome but I havem't used them for years.
im trying to figure out on your codepen how to get the bar on the rightside and only cover 50%, im guessing changing the translate from -100% to something else
and change the
left: 0;
to right: 0
ill try to implement your solution and combine it with mine, should function the same since i only add a logo on the left and a div with 2 buttons on the right. Thanks a lot Chris!
i've rewatched kevin's video and implemented some of your stuff and it works great!