Dropdowns allow to toggle an element's visibility. They usually contain some sort of navigation, be it a bare list of links, or more complex elements. They can offer one to multiple nesting levels.
We do not call dropdowns simply "menu" as dropdowns can have a much wider field of application than menus of traditional applications.
Besides many other requirements, we want to stress out explicitly the following:
The meaning and usage of the dropdown must be clear.
The dropdown must be operable using both keyboard only and screen readers (with a reasonable interplay of default keys like Tab, Enter/Space, Esc, Arrow keys), as well as mobile screen readers.
Proper feedback must be given upon opening/closing a dropdown.
Each dropdown toggler has an aria-expanded="false" attribute; its value (true/false) and the visibility of the corresponding content is toggled using JavaScript. See Marking elements expandable using aria-expanded.
Dropdown togglers are implemented as <button> elements (in contrast to the links, see below for further explanations).
By using nested lists, screen readers can announce when entering (and leaving) lists, and the total number of elements of the current list.
Adding more sophisticated keyboard interaction features like closing a dropdown using Esc or navigating it using Arrow keys would be easy. For simplicity though, we refrained from doing this.
Multi-level dropdown
Some dropdowns offer more than a single nesting level. Simply add more nested lists to make this happen:
It is debatable how user friendly menus with deeply nested levels really are though. A good compromise is to keep the nested lists, but without the need of toggling their visibility.
Admittedly, this is already pretty close to a mega dropdown (see below).
Double-purpose dropdown
Another use case is dropdowns serving a double-purpose: offering both toggling a dropdown and navigating to an element.
There are implementations of this pattern that realise this with a single element:
When hovering it, the dropdown is opened.
When activating it, the browser navigates to an URL.
The problem with this is that the hover event is only available to pointing devices (like a mouse): whether keyboard only, nor screen reader, nor touch screen users would be able to use such an implementation (for further discussion about hover, see below).
The best bet for this requirement is to implement both an element for toggling the dropdown and for navigating to an element:
A mega dropdown can contain much more than a simple collection of links: it can contain (nearly) everything that is structured content, be it paragraphs, images, form elements, etc.
<button>Focusable element before</button><oldata-adg-dropdown=""><li><buttonaria-expanded="false">▾ Physical activities</button><ol><li><ahref="https://www.google.ch/search?q=soccer">Playing soccer
<p>
Soccer is a team sport played between two teams of eleven players with a spherical ball.
</p></a></li><li><span>Dancing
<p>
Dance is a performing art form consisting of purposefully selected sequences of human movement.
</p></span><ol><li><ahref="https://www.google.ch/search?q=salsa">Salsa
<p>
Salsa is a popular form of social dance that originated in the Caribbean.
</p></a></li><li><ahref="https://www.google.ch/search?q=rocknroll">Rock'n'Roll
<p>
Rock'n'Roll is a very athletic, competitive form of partner dance that originated from lindy hop.
</p></a></li></ol></li><li><ahref="https://www.google.ch/search?q=gardening">Gardening
<p>
Gardening is the practice of growing and cultivating plants as part of horticulture.
</p></a></li></ol></li><li><buttonaria-expanded="false">▾ Login</button><form><p>
Please fill out the form below with your credentials.
</p><fieldset><legend>Login</legend><div><labelfor="login">Name</label><inputid="login"type="text" /></div><div><labelfor="password">Password</label><inputid="password"type="password" /></div><div><inputtype="submit"value="Login" /></div></fieldset><p>
No credentials yet? Please do something of the following:
</p><ul><li>
Register your own account.
</li><li>
Hack another user's account.
</li><li>
Leave and never come back.
</li></ul></form></li><li><ahref="https://www.google.ch/search?q=about">About</a></li></ol><p><button>Focusable element after</button></p>
As explained above, mega dropdowns can contain structured content of various kind. Be sure not overuse this possibility though. For example, stuffing "big" structural elements like headings (<h1> to <h6>) or HTML 5 sectioning elements (like <article> or <header>) into these pretty basic structures of nested lists (<ol>) does not feel right.
This remains a valid technique up to the present day, and using <optgroup>, the dropdown can even be nested to a single level.
As these standard controls' styling capabilities are limited though, they are seldom used nowadays.
Toggle on hover?
There is a big debate whether dropdown menus should open on hover. First of all: unintentional hovering may cause flickering of elements. But there are also confusing (if not disrupting or even misleading) behaviours attached to dropdowns that open (or close) on hover.
Look at this scenario: a user hovers over a dropdown and clicks on it, but nothing seems to happen. This is due to the fact that the dropdown already was triggered to open by hover, and clicking on it closes it immediately again.
An even worse scenario is this: a user wants to click an element right below a closed dropdown. While moving the mouse over the dropdown (which is of no interest to the user at this time), the hover event opens the dropdown and overlaps the target element, causing the fast user to click on an element in the dropdown instead.
The worst are elements that toggle a dropdown on hover and navigate to a website by activation. This is extremely confusing for all sorts of users (be it with or without special needs), and pretty hard to implement in an accessible way.
There are a lot of tricks and workarounds to minimise the problems depicted above, like using timeouts or visual effects. But in general, the problems remain, and the workarounds potentially lead to new side effects (or even less intuitive behaviours).
In our opinion, hovering events should only be used for purely visual purposes, and toggling the visibility of content is by no means purely visual. So it is much better to only open (and close) dropdowns on dedicated activation by the user.
Links or buttons?
In our dropdown implementations, we use <button> elements to toggle dropdowns. In other implementations however, these are often implemented as <a href="#">, <a href="javascript:;">, or similar, which is clearly less appropriate.
While <button>s clearly indicate some interactivity, links suggest users to navigate somewhere. So changing an element's visibility is clearly a moment of interaction, not of navigation. And although in earlier days buttons could not be styled as well as links, this changed a lot recently, so there is no excuse anymore for mis-using links as buttons.