I put together this short tutorial on how to make a hamburger menu with no js in response to the feedback on my original Twitter post.
Enjoy π!
:target
Have you heard of the CSS pseudo-class on :target
?
It styles the element with an anchor id that that has been called by a link.
For example, a p
with an id of home
and an a
link with href=#home
:
<p id="home">Home</p> <a href="#home">Go to Home</a>
p:target { color: red; }
When we click on the a
link, the text of the targeted p
changes to red.
By clicking on another link, the :target
style gets hidden.
<p id="home">Home</p> <a href="#home">Go to Home</a> <a href="#">Go somewhere else</a>
Here's the whole html code.
I'm using material icons by adding their cdn in the head of the html file.
<head> <!-- ... --> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> </head>
<ul class="menu" id="menu"> <li><a href="#">Home</a></li> <li><a href="#">Profile</a></li> <li><a href="#">About</a></li> <li><a href="#">Contacts</a></li> <a class="close" href="#"> <span class="material-icons"> close </span> </a> </ul> <a class="hamburger" href="#menu"> <span class="material-icons"> menu </span> </a>
Material icons work by defining a span with material-icons
class and adding a keyword between the tags:
<span class="material-icons"> close </span>
The
ul
has an id ofmenu
. It holds the menu and the close icon link.The
a
with a class ofhamburger
has a href#menu
, clicking on it will show the on:target
style for theul
menu.Clicking on other links (Home, Profile, About, Contacts) and the
close
link will remove the on:target
style of theul
.
Now we just need to add a sprinkle of CSS β¨.
The hamburger link has a position fixed
to get it out of the flow of the page.
The menu has a position fixed
too and a bigger z-index
than the hamburger link to put the menu above the link.
For consistency, I've put the hamburger and close links on the same corner.
css .hamburger { position: fixed; /* a large z-index puts the ham button above the rest of the page*/ z-index: 99; background: white; border: none; cursor: pointer; top: 1rem; right: 1rem; } .menu { position: fixed; /* give the menu a larger z-index than the ham link to put the menu above it */ z-index: 100; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100vh; /* basic menu styling*/ list-style: none; background: black; display: flex; flex-direction: column; /* animate slide up/down */ transform: translateY(-100%); transition: transform 0.2s ease; } .close { position: absolute; border: none; color: white; cursor: pointer; top: 1rem; right: 1rem; }
The menu is hidden by default with transform: translateY(-100%);
. Translating -100% on the Y axis moves it 100% up above the screen.
By adding a transition transition: transform 0.2s;
on transform we get a small slide in and out animation when the value of transform translateY changes.
And we reset the translation Y to 0 and show the menu on :target
.
css .menu:target { /* show menu */ transform: translateY(0); }
Thanks for reading π!
- Thanks Martin for telling me to animate transform instead of height to get GPU support.
Top comments (7)
You will see a slightly smoother transform.
Also my issue with this technique is backwards navigation will continually open and close the menu if I clicked it a few times, it's in my history π¬.
Lastly you can embed codepen here on dev, you can even share it from codepen via their sharing mechanisms.
True π . Thanks for the precious feedback! That IS a drawback. And I don't think it can be avoided because it's using links so the url is always going to get changed π€.
Will try "will-change" thx, haven't heard of it before.
Didn't see the last part π , thanks for the tip!! Didn't know that was possible. Will try for sure next time π. Btw, are there shortcuts for emojis here? I'm copying and pasting from emojipedia π .
If you are on windows 10 just press
win +.
. It will open a built in emoji keyboardIf on a Mac with a touch bar you can say "so that's what this thing is good for" - "glad I didn't buy this machine" and use that.
Lol π€£π€£ .
Thx Akhil π! I'm using win.
I blog on my phone 99% of the time so I couldn't say, no markdown shortcuts but you should check the guide when you post. Lots of nice tips.