Creating a fold out navigation with CSS only

Cyd on December 29, 2019

While using JavaScript to open a mobile navigation is a solid option, it's also possible to do it with CSS only. Even submenus don't necessarily ne... [Read Full]
markdown guide
Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

yo stupid, she speaks dutch and english. stop this spanish bs in the comment sections of english websites.

Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

just doesnt make sense why theyre speaking spanish.

btw great article

Maybe he doesn't know english, there's no need to be rude.

Great article =)

Great article.
BTW this website isn't restricted about languages. Any one can speak their own language.

Actually it is, I've read it somewhere

DEV doesn't have any restrictions on languages, and we are working to actively support them.

@imcanada comments and replies should be constructive, respectful, and show a level of empathy toward others. Please take some time and review our Code of Conduct.

Sloan, the sloth mascot Comment marked as low quality/non-constructive by the community View code of conduct

ok æðislegt það er fullkomlega eðlilegt að ég sé að svara ummælum á ensku á íslensku.

doesnt help anyone though does it?

Take the feedback, Canada.


Hey Cyd,

First off, very nice work. I really like the CSS only approach you took. My only concern was as you pointed out at the end that your example is not semantic. As a result, using the wrong element can trigger the wrong browse mode in assistive tech which can be a bit confusing. But in this case, using the checkbox as a toggle might be ok. I need to do some more digging.

Aside from that, I tested your example using NVDA with Firefox and Chrome. Things worked great when I wasn't using my screen reader. However, I found that when using my screen reader and the hamburger menu was in focus, the checkbox was not clickable (Chrome). I also noticed that when in focus, NVDA didn't announce the purpose of the element(chrome and Firefox). So I took a look at the code to see what was going on and I found a few things that fixed the issues in both Chrome and Firefox.

Removing the height, width and appearance from .nav__trigger-input allowed for the checkbox to be clicked via the keyboard when the hamburger menu was in focus(Chrome). And by placing the aria-label on the input element, when in focus, NVDA announced, "open the navigation. not checked" (Chrome). Placing an aria-labeledby="trigger" and changing the for="trigger" on the label to id="trigger" allowed for the aria-label to be correctly announced by NVDA in both Chrome and Firefox.

_submenu-trigger-input {
opacity: 0;
position: fixed;

< input
aria-label="click to open the navigation"
< label class="nav
_trigger-finger" id="trigger">

I hope my suggestion helps.

Again, great work!!


Thank you!!! This is exactly what I was looking for. We might have to add border: none and background: none because for some weird reason checkboxes are really hard to make invisible in all browsers. I’m going to add this code en reference you in a bit!


No prob :)

I made an update. I noticed the explicit label while associated with the labeled by was not triggering the mouse click. So I tied the label to the input using hamburger as the id and for. Also added cursor: pointer; to .nav__trigger-finger.

< nav class="nav">
< input
aria-label="click to open the navigation"
< label class="nav
_trigger-finger" id="trigger" for="hamburger">
< span>


Hmmm I can actually use the keyboard to open the navigation in chrome, using tab and space to open. You also shouldn't use the same ID twice as they should be unique so Im going to call it something different. Still thanks for your help!


Yeah, I noticed that too! facepalm

I made a codepen with the updates


Hahaha looks great, I think the problem is that not the entire hamburger is clickable, I usually just use a svg to animate between states, but that seemed a bit too complicated for this article.

Great work!


Just a few findings from me:

1) The animation on a 27 inch display is a little bit to much. I personally find it not very pleasant after the second time
2) On mobile I can see the "C" from "contact"
3) On Firefox I have 2 scroll bars.
4) The Hamburger menu does not animate from 1 line to 3 lines. It just jumps to 3 lines.

In general I see this screen filing menus more and more. This to me only makes sense on Mobile where the space is limited but on a laptop or even on a 27 inch monitor it is for me not a very good user experience.

Besides that good article.


Hahaha you think I would actually use this in production? This is just to showcase what you can do with pseudo classes, don't take things too seriously.


I'm not taking it too serious :)

Maybe some (junior) devs will think that this should be used in production.

Like people use the codedrops examples in production and then the complete UI is super laggy ;)


Great article! Thank you! May I make a suggestion for future articles? Can you please show the browser window after you show the code snippets? It makes following along easier, and also makes it easier to know if there's an error. I went through your article and have something wrong. Unfortunately I don't know where in the code I made the error. Still a great article! keep it up


Oops, there was a mistake in the code; the li tags weren't closed, that might have thrown you off, here is the simple version of the navigation as shown in the article:



I understand the goal of this, but Wich value I need to modify to use only 50%,30%, etc, of screen after translate the ul? Thank you


I get it, the "left" attribute of ul. Thank you, is an interesting escenario


That’s a great option, you could also not set the left property and give it a width of 30vw (I would add a min width in pixels as well to keep it all readable) for example 🙂


This is dope...Cyd
Love it ❤🤗


Great article! I saved it to my reading list for later review!!


My big take away here is using a custom checkbox input to maintain the menu state. Perfect. Oh, and your fancy menu is amazing 😁


Would you be able to link a button element to the input?
I may play around with the idea later but to be semantic seems like we could wrap the input in a button parent element


Unfortunately no, the for attribute only works on the label element and that’s how we link the input and label. Also if you wrap the input in an element you can no longer use sibling selectors to show and hide the navigation 😔.


Very cool, thanks!

Just something I noticed. I played with this on a basic one page site with anchors. When clicking a link, the menu stays open. So you need to close it to view the content.


Oh damn, you found the loophole, this might actually take some JavaScript

code of conduct - report abuse