Take the 2-minute tour ×

So, I decided to start really learning CSS more in-depth, and I began by attempting to implement a pure-CSS drop-down menu/select-box. I started by studying the code available in some online tutorials.

Ultimately, I came up with this, which I think is pretty decent. However, I've come to the conclusion that CSS menus might never be a suitable replacement for Javascript menus in all cases, because there are subtle problems that come up when you ditch Javascript.

If the items in your drop-down menu are simply <a href links, everything should be fine. BUT if you want each link to fire a Javascript event, you run into the following issues:

  • When the user clicks an item in the drop-down box, you want the drop-down box to disappear, obviously. This happens automatically if the items in your drop-down box are <a> elements. If they're NOT <a> elements, the drop-down box won't disappear on-click - which leaves you with two options: (A) wire up some Javascript that listens for onclick and then make the drop-down box disappear, or (B) use the css :active selector to set the drop-down box's display property to none. (A) is stupid, because you're basically back to Javascript menus at that point, and (B) doesn't work out because it prevents Javascript events from firing when you click an item in the menu.

  • So, you have to use <a> tags. That means if you want to associate an event with a menu-item selection, you need to use an inline onclick in your <a> tag. That's fine, except if you do that, it prevents the drop-down menu from disappearing (as demonstrated in my jsfiddle link). So, really, CSS-only drop-down menus only seem to be workable if all you want to do when the user selects a menu item is navigate to another page via an <a> link. I can't find any way to get a Javascript function to fire that doesn't come with some gotcha.

Question: So, is what I've said accurate? Or is there a way to create a CSS-only drop-down menu that (A) disappears when the user clicks it, and (B) triggers a Javascript function?

share|improve this question
If Javascript gets the job done better / at all, why not use Javascript? –  millimoose May 29 '12 at 22:59
@Inerdial, using Javascript is fine. The point of my question is to determine if CSS alone can meet my requirements for this menu. Based on the answers I've got so far, it seems I will probably need to go back to a Javascript menu. –  Channel72 May 29 '12 at 23:01
You can use a menu like Demo: Pure CSS3 Gradient Dropdown Menu (No Image Used) and JavaScript to make the dropdown disappear (.style.display='none';) –  uınbɐɥs May 30 '12 at 0:32
@Channel72 All CSS-only menus I've seen have a bunch of glaring usability issues. One is that you can't stray from the menu by even one pixel or it closes – even yours has that. Another is that if the menu is hierarchical, you can't move in a straight line from an item to a sub-item; you have to move to the right – while staying in a band 20px (!) wide the whole time – then down. The menu in Shaquin's link illustrates this very well: try to select My Projects > N.Design Studio > Illustrator Tutorials –  millimoose May 30 '12 at 0:36
These are issues that menus in native apps try very hard to avoid. Same goes for well-behaving Javascript menus. This makes using a menu that isn't "well-behaved" very frustrating. While it's certainly possible to make a JS menu that has the same problems, I don't believe it's really possible to solve them with CSS alone. (At least not the second one, which requires you to distinguish whether a mouse is moving over an item or if it stopped there.) –  millimoose May 30 '12 at 0:42
add comment

5 Answers

up vote 5 down vote accepted

I think that you're a bit confused. You seem to think that there is a binary that exists: either all CSS or all JS. This is a silly way to think. You should use CSS when it makes sense to use CSS and use JS to do things that CSS wasn't made for. In most cases, using CSS to do the heavy lifting for you (hide/showing of menus, etc) and then enhancing said menu with additional functionality that CSS can't provide is the way that most professional front end devs build menus.

share|improve this answer
+1 for this, just because you want to slightly alter the behaviour of a CSS menu, doesn't mean you have to delete all the CSS and re-bind the hovers using JS (aka a traditional JS menu). –  Christian Varga May 29 '12 at 23:44
add comment

I really don't follow you. Why do you "obviously" want the dropdown to disappear?

If you do, then you should make it disappear, it's not clear to me that this is an "obvious" thing you want to have happen.

The menu doesn't disappear because the mouse is still over the hover area, which is exactly what css is supposed to do. If you want other behavior, then you do need to use javascript. In most cases, it just doesn't matter because you're either redirecting to another page or changing the current state (such as with a popup dialog, or something else.

CSS menus are fine for most of the uses i've used them for. It's pretty rare i'm using a css menu to do something that doesn't either redirect or cause some kind of radical state change that would close the menu anyways.

So I guess my answer is, just because you have a specific use case that makes pure css menus hard to use, doesn't mean they're not useful for most other uses.

Having said that, just because you're using javascript doesn't mean you have to revert to a full-blown javascript menu either. You can simply use javascript to subtly change the standard behavior, without the complexities of a full js menu.

share|improve this answer
I would argue that expected behavior is for the menu to disappear when you click it - indicating you've selected an item. I mean, the drop-down menus in just about every GUI in every OS that has ever been made disappear onclick, because you're indicating you've made your selection. –  Channel72 May 29 '12 at 22:56
You say in most cases it just doesn't matter because you're either redirecting to another page or changing the current state. Yeah, if you're redirecting to another page it doesn't matter. But if you're changing the current state - such as via a Javascript function - wouldn't you want the menu to disappear when you click it? –  Channel72 May 29 '12 at 23:01
@Channel72 - if you're changing the current state, then you can change the menu as part of that state change. Also, CSS menus aren't real menus.. so they cannot be expected to act like real menus by themselves. You're using CSS for something it wasn't designed for (but still does a pretty good job with). The behavior your using to "pretend" to be a menu would break other things if it automatically hid itself when you clicked on it. –  Erik Funkenbusch May 29 '12 at 23:06
If you are using javascript to STAY on the page, then javascript can't be bad to fix what it "caused"? –  mowgli May 29 '12 at 23:15
+1 for using javascript to improve a CSS menu rather than doing a full replacement. Javascript menus can have their own drawbacks if not coded properly, such as reduced accessibility and non-usability for users not running javascript. –  sscirrus May 29 '12 at 23:16
add comment

Your question demonstrates some research and is very well explained. However I find some confusion: at the end you want to use javascript because you want to trigger something (an event, a function..).

So my answer is:

css are great for dropdown menus, and if you want ti use javascript when the users click on the menu, just do something like this

<a href="javascript:my_function()" >Item 1</a>

The my_function() function can then execute the code you want, and maybe also hide the selected element.

I made an example in this jfiddle just using a traditional window.alert function that you cn replace with your preferred javascript.

A last remark about your concerns of making the menu disappear: are you sure you dramatically need it? When the function is executed probably the attention of the user is focused on something else and he'll move from the dropdown... but I don't know exactly as you didn't explain why you wanted it to disappear.

share|improve this answer
add comment

I feel that the goal of not using JS in a dropdown like this is misleading. If you're using the dropdown for navigation (whether external or on-page using # references), manually hiding the menu becomes unnecessary. If you're using it for any other functionality, it's only reasonable to expect it has to be wired with JS, meaning there's no shame in "manually" manipulating the rendered element.

Granted, there is another possible use here. Your jsfiddle example looks a lot like a stylish <select> element - if that's in fact your intent, you could quite simply replace individual links with something along the lines of

<label><input type="radio" name="test-select" value="1" />Item 1</label>

Which could then be submitted natively - such minimal form functionality is probably the most you can get without javascript

share|improve this answer
add comment

CSS Menus are way beyond just "workable". I can't remember the last time i used JS for a menu. Not to brag but i get a ton of visits for this menu i built using only CSS. Its got dropdowns with icons.


share|improve this answer
add comment

Your Answer


