245 lines
7.2 KiB
Markdown
245 lines
7.2 KiB
Markdown
---
|
|
title: "Developing a mobile-friendly navigation menu for your website"
|
|
date: 2023-02-13T11:13:34-05:00
|
|
toc: true
|
|
topics: ["web design", "css", "javascript"]
|
|
---
|
|
|
|
I personally am a big fan of navbars as they are a clean way to navigate any website.
|
|
The classic navbar, that you are likely seeing on this site if you are viewing this on a desktop browser, is extremely simple to make and you can easily find guides to develop these.
|
|
The one I personally used is [here](https://www.w3schools.com/howto/howto_css_dropdown_navbar.asp).
|
|
What was not as simple for me was creating a decent navbar for mobile.
|
|
I had to develop it for a site that I was working on for my church that never concluded development.
|
|
I copied it over to my personal site and learned a lot in the process of developing it so all was not wasted.
|
|
It did however end up taking me way more time than it should have and in the hopes of saving some other poor soul some time, I decided to write an article about how I did it on my site.
|
|
|
|
**If you want to check out how it looks like on my site before we get started, just shrink the width of your browser!**
|
|
|
|
|
|
## Fundamental approach
|
|
|
|
I decided that the simplest way to do what I wanted, was to design two completely separate navigation bars.
|
|
One is used for larger screen widths while the other is used for smaller screen widths.
|
|
This might not be the most elegant method but it certainly is simple.
|
|
The `<nav class="primary">`, which is the default navigation bar, is therefore styled using the following code (excluding all actual styling code):
|
|
|
|
```
|
|
nav.primary{
|
|
display: flex;
|
|
}
|
|
|
|
@media screen and (max-width: 768px){
|
|
nav.primary{
|
|
display: none;
|
|
}
|
|
}
|
|
```
|
|
|
|
Now that we have briefly touched the primary navigation bar, let's move on to styling the mobile navigation bar.
|
|
|
|
## Designing a mobile navigation bar
|
|
|
|
The mobile navigation menu that I am using is simple.
|
|
What I wanted was a menu with items that would reveal itself after the user clicks the hamburger menu icon.
|
|
To start, we need to style a menu that is hidden.
|
|
The CSS for this menu is:
|
|
|
|
```
|
|
nav.mobile{
|
|
transition: left 0.4s ease;
|
|
position: fixed;
|
|
top: 0;
|
|
left: -50%;
|
|
width: 50%;
|
|
height: 100%;
|
|
background: #665c54;
|
|
z-index: 9999;
|
|
}
|
|
```
|
|
|
|
The `z-index`, `height`, `top`, `width`, and `background` properties create a rectangular block that is laid over the site.
|
|
The `transition` property allows for smooth sliding when we move this element around when we open the menu.
|
|
The final important property here is that we set `left:-50%` to hide the menu.
|
|
We can then easily add items to this menu using a list, or just an item div (which is what I prefer) i.e.
|
|
|
|
```
|
|
nav.mobile .mobile-item{
|
|
margin: 20px 10px;
|
|
}
|
|
```
|
|
|
|
## Creating a hamburger menu icon to open our menu
|
|
|
|
Now we need an icon that we can click to open our menu.
|
|
It turns out that it is possible to create a hamburger menu just using html and CSS.
|
|
We won't need Font Awesome for this.
|
|
The html code for the hamburger menu is:
|
|
|
|
```
|
|
<div class="hamburger" id="Ham">
|
|
<div class = "bars" >
|
|
<span class="bar"></span>
|
|
<span class="bar"></span>
|
|
<span class="bar"></span>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
We put our `<span class='bar'>` inside of a `<div class = "hamburger">`.
|
|
By default we have `<div class="hamburger"` hidden while the `<span class="bar">` is what actually forms the icon.
|
|
The CSS code for this is:
|
|
|
|
```
|
|
.hamburger {
|
|
display: none;
|
|
}
|
|
|
|
.bar {
|
|
display: block;
|
|
width: 25px;
|
|
height: 3px;
|
|
margin: 5px auto;
|
|
-webkit-transition: all 0.3s ease-in-out;
|
|
transition: all 0.3s ease-in-out;
|
|
background-color: #FFF;
|
|
}
|
|
|
|
.bars{
|
|
display : block;
|
|
position: absolute;
|
|
top: 20%;
|
|
left: 20%;
|
|
}
|
|
```
|
|
|
|
I was not able to create a close symbol that looked nice so I ended up using Font Awesome as shown below:
|
|
|
|
```
|
|
html:
|
|
<div class = "hamburger">
|
|
....
|
|
<div class = "close">
|
|
<i class="fa-solid fa-xmark fa-2x"></i>
|
|
</div>
|
|
</div>
|
|
|
|
CSS:
|
|
close{
|
|
display: none;
|
|
}
|
|
```
|
|
|
|
It should be noted that `<div class="hamburger">`, contains both `<div class="bars">` and `<div class="close">`.
|
|
This icon is activated at smaller screen sizes, i.e.
|
|
|
|
```
|
|
@media screen and (max-width: 768px) {
|
|
.hamburger{
|
|
display: block;
|
|
margin: 20px 0;
|
|
position: fixed;
|
|
top: 15px;
|
|
left: 45px;
|
|
height: 45px;
|
|
width: 45px;
|
|
text-align: center;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
transition: left 0.4s ease;
|
|
background-color: #696969;
|
|
z-index: 9999;
|
|
}
|
|
```
|
|
|
|
## Opening the menu using javascript
|
|
|
|
Now that we have a hidden menu and the hamburger icon to open it, we need to add a javascript function that activates on click.
|
|
I won't describe how to link .js files, this is a pretty simple thing to look up.
|
|
To enable our responsive menu, we need one javascript function described below.
|
|
|
|
```
|
|
/* Toggle between adding and removing the "responsive" class to
|
|
the nav when the user clicks on the icon */
|
|
|
|
function myFunction() {
|
|
var x = document.getElementById("Nav");
|
|
if (x.className === "primary") {
|
|
x.className += " responsive";
|
|
} else {
|
|
x.className = "primary";
|
|
}
|
|
var x = document.getElementById("Ham");
|
|
if (x.className === "hamburger") {
|
|
x.className += " responsive";
|
|
} else {
|
|
x.className = "hamburger";
|
|
}
|
|
|
|
var children = x.children;
|
|
if (children[0].className === "bars") {
|
|
children[0].className += " responsive";
|
|
} else {
|
|
children[0].className = "bars";
|
|
}
|
|
if (children[1].className === "close") {
|
|
children[1].className += " responsive";
|
|
} else {
|
|
children[1].className = "close";
|
|
}
|
|
|
|
var x = document.getElementById("Navmobile");
|
|
if (x.className === "mobile") {
|
|
x.className += " responsive";
|
|
} else {
|
|
x.className = "mobile";
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
This function simply toggles the class of the divs that comprise our mobile navigation menu.
|
|
By default, these divs start out with just a `mobile` class.
|
|
This function then adds the `responsive` class when called.
|
|
If the class already has the `responsive` class, it removes it.
|
|
We can then define additional styling for the `responsive` elements.
|
|
The most obvious step of opening the menu can be done simply by setting the left margin to 0, i.e:
|
|
|
|
|
|
```
|
|
nav.mobile.responsive {
|
|
left: 0;
|
|
}
|
|
|
|
```
|
|
|
|
As a note we also want to adjust the hamburger menu to a red close symbol by changing the position and color of the menu and also setting display none to the bars which make up the original hamburger menu.
|
|
|
|
```
|
|
.hamburger.responsive{
|
|
left: 55%;
|
|
cursor: pointer;
|
|
background-color: #ff6347;
|
|
}
|
|
|
|
.bars.responsive{
|
|
display: none;
|
|
}
|
|
|
|
.close.responsive{
|
|
display: block;
|
|
color: #FFF;
|
|
position: absolute;
|
|
top: 4px;
|
|
left: 10px;
|
|
}
|
|
```
|
|
|
|
I am certainly not an expert in javascript and am self-taught in html and css so this code might not be optimized, but it gets the job done and makes me happy!
|
|
|
|
## Conclusion
|
|
|
|
Hopefully this is helpful to someone.
|
|
I figure I'm probably just tossing this into the void but maybe it will end up being useful to someone.
|
|
If you have any comments or find any errors shoot me an email!
|
|
Would love to know if anyone actually is using this stuff.
|