CSS KP 09 — Nav

Greem
5 min readOct 9, 2024

--

turn horizontal menu to vertical menu for responsiveness — — — hamburger menu / closed / open

Let’s build a hamburger menu button for mobile responsiveness so users can open and close the navigation. We will also learn how to add assistive technology features.

  1. First, we will hide the span menu, making it only available for screen readers.
<button><span class="sr-only">Menu</span></button> //<--------------

<nav>
<ul>
<li>Home</li> <li>Portfolio</li> <li>About</li>
</ul>
</nav>

2. Next, add the class class=”mobile-nav-toggle” so we can select it.

<button  class="mobile-nav-toggle" > //<--------------
<span class="sr-only">Menu</span>
</button>

<nav>
<ul>
<li>Home</li> <li>Portfolio</li> <li>About</li>
</ul>
</nav>

3. Then, add aria-controls=”primary-navigation”

<button  class="mobile-nav-toggle" 
aria-controls="primary-navigation"> //<--------------
<span class="sr-only">Menu</span>
</button>

<nav>
<ul>
<li>Home</li> <li>Portfolio</li> <li>About</li>
</ul>
</nav>

4. Finally, match the aria-controls using an id for the <ul> , (because it doesn’t look at class, only id) so that when the menu is clicked, the entire navigation will open and close.

<button  class="mobile-nav-toggle" 
aria-controls="primary-navigation">
<span class="sr-only" >Menu</span>
</button>

<nav>
<ul id="primary-navigation" > //<--------------
<li>Home</li> <li>Portfolio</li> <li>About</li>
</ul>
</nav>

5. add aria-expanded attribute. The menu is closed when it’s false, when it’s clicked, it will open. We will used javascript to change the value to true or false .

<button  class="mobile-nav-toggle" 
aria-controls="primary-navigation">
<span class="sr-only"
aria-expanded="false">Menu</span> //<--------------
</button>

<nav>
<ul id="primary-navigation" >
<li>Home</li> <li>Portfolio</li> <li>About</li>
</ul>
</nav>

Let’s turn the horizontal navigation to a vertical navigation.

  1. look for the navigation classes in CSS because we already wrote some.
.
.
.
.primary-navigation {
--gap: 8rem;
--underline-gap: 2rem;
list-style: none;
padding: 0;
margin: 0;
}
.
.
.

2. Delete --gap

.primary-navigation {
--underline-gap: 2rem;
list-style: none;
padding: 0;
margin: 0;
}
flex-direction: column;

3. add flex-direction: column;

.primary-navigation {
--underline-gap: 2rem;
list-style: none;
padding: 0;
margin: 0;
flex-direction: column; //<--------------
}

4. add position:.... so the navigation isn’t creating new unnecessary space.

.primary-navigation {
--underline-gap: 2rem;
position: fixed; //<--------------
list-style: none;
padding: 0;
margin: 0;
flex-direction: column;
}

5. add background so we can see the menu

    backdrop-filter: blur(2em);

6. inset: top, right, bottom, left for position.

.primary-navigation {  
--underline-gap: 2rem;

position: fixed;
inset: 0 0 0 20%; //<--------------top, right, bottom, left
//similar to ------ /* left: 7em; */

list-style: none;
padding: 3em;
margin: 0;
flex-direction: column;
backdrop-filter: blur(2em);
right: 0em;


}

problem: the button is on top of the menu

solution: z-index

how to place the menu on top of the button?
.primary-navigation {  
--underline-gap: 2rem;
position: fixed;
z-index: 1000000; //<--------- high number
inset: 0 0 0 20%;
/* left: 7em; */
list-style: none;
padding: 3em;
margin: 0;
flex-direction: column;
backdrop-filter: blur(2em);
right: 0em;
}

add padding: min(20rem, 20vh) , whichever value is smaller, we will go with that.

    padding: min(20rem, 20vh) 2rem;
  • Adding Media Queries for hamburger menu:

For the hamburger menu, we are using max-width instead of min-width (mobile-first approach) to avoid overwriting the intricately crafted navigation code.

  • Considerations for Complexity:
  • Larger Screens:

Often, use min-width (mobile first approach) to add complexity for larger sizes.

  • Navigation Elements:

For navigation and hamburger menus, we introduce more complexity for smaller screens, hence we use max-width.

.primary-navigation {
--underline-gap: 2rem;
list-style: none;
padding: 0;
margin: 0;
}

@media (max-width: 35rem) {
.primary-navigation {
--underline-gap: 2rem;
position: fixed;
z-index: 1000;
inset: 0 0 0 30%;
background: black;
list-style: none;
padding: min(20rem, 15vh) 2rem;
margin: 0;
flex-direction: column;
}
}

@supports

//use this 
.primary-navigation {
backdrop-filter: blur(2em);
}

//if this attribute and value are supported then use this
@supports(backdrop-filter: blur(2em)){
.primary-navigation {
backdrop-filter: blur(2em);
}
}

🍔

  1. hide the toggle on the desktop side, which is in the global scope.
.mobile-nav-toggle {
display: none;
}

2. in the media query scope, style the hamburger button using the background-image attribute.

.mobile-nav-toggle {
display: none;
}

@media (max-width: 45rem){
.....

.mobile-nav-toggle {
border: 0;
display: block;
position: absolute;
z-index:20000000000;
right: 2em;
top: 2em;
background-color: transparent;
background-image: url(./assets/shared/icon-hamburger.svg);
background-size: 100%;
width: 3em;
background-repeat: no-repeat;
aspect-ratio: 1/1;
}
}

yay we get the burger button!

problem: need to make the hamburger button a toggle switch.

solution: let’s solve it with Javascript to close the menu

html
<script src="index.js" defer></script>

html .primary-navigation tag, add new custom attribute called, burger-on and set it as false.

  <ul id="primary-navigation" burger-on="false" class="primary-navigation underline-indicators flex">

js

// javascript

const toggle = document.querySelector(".mobile-nav-toggle")
const navi = document.querySelector(".primary-navigation")

toggle.addEventListener("click", () => {

let burgerOn = navi.getAttribute("burger-on")
console.log(burgerOn)
if(burgerOn==="false"){
// toggle.style.background-image="./shared/icon-close.svg"
navi.setAttribute("burger-on", true)
}
else {
navi.setAttribute("burger-on", false)
}
})

so now we get the toggle going

@media (max-width: 45rem){
.primary-navigation {
...
}

.primary-navigation[burger-on="true"]{
display: none;
}

reference: Kevin Powell’s — — https://v2.scrimba.com/build-a-space-travel-website-c014/~016

--

--

No responses yet