How to Build a Dropdown Menu with Pure CSS (No JavaScript)
By Purely CSS · Published October 9, 2026
A pure CSS dropdown menu hides a list of links and reveals it with :hover, :focus-within or a hidden checkbox, all without JavaScript. The two patterns below cover the common cases: a hover menu that also works with the keyboard, and a click-to-open menu that works on touch screens.
1. A hover dropdown that works with the keyboard
Wrap the button and the list in a positioned container. Hide the list with opacity and visibility, then show it when the container is hovered or contains the focused element.
Using :focus-within as well as :hover means someone tabbing through the page can open the menu too. Fading with opacity and a small translate looks smoother than toggling display.
<div class="item">
<button class="top">Products</button>
<ul class="menu">
<li><a href="#">Buttons</a></li>
<li><a href="#">Loaders</a></li>
<li><a href="#">Cards</a></li>
</ul>
</div>2. A click-to-open menu with a checkbox
Touch screens have no hover, so use a visually hidden checkbox as the on and off switch. The label is the button people click, and the sibling selector input:checked ~ ul shows the list.
<div class="dd">
<input type="checkbox" id="dd-toggle">
<label for="dd-toggle">Menu</label>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>Tips
- Keep the menu attached to its button with no gap, or add a small padding bridge, so it does not close when the pointer crosses the space.
- Use real links inside the list so the menu still works if the styles fail.
- For large site navigation, consider a plain list of links on mobile. Dropdowns are hard to use with a thumb.
Common questions
Can I make a dropdown menu without JavaScript?
Yes. Show the submenu with :hover and :focus-within on the parent, or use a hidden checkbox as a click toggle.
How do I make a CSS dropdown work on mobile?
Use the checkbox technique, because touch screens have no hover. The label becomes the tap target and input:checked reveals the menu.
Why does my dropdown close before I can click it?
There is probably a gap between the button and the menu. Remove the gap or bridge it with padding so the hover state continues.
Want more examples?
Browse the full collection of pure CSS menus, or try your own code in the playground.