August 28, 2018

A few months ago I had to add a dropdown menu to a project that did not use a frontend framework with dropdown menus built in. I decided to see if I could make a dropdown menu without JavaScript. My approach is a hybrid of that found in these posts:

Click to Open

The menu I made requires a click to open. To accomplish something similar, create a hidden checkbox with a visible label. Here, we'll use the logo for the label. When the label is clicked, the checkbox will be checked, even though it remains hidden.

This code uses the CSS general sibling combinator ~ to select the #collapse-menu that follows the input:not(:checked) and scale its height to 0. When the input is checked, that style no longer applies, so the scaleY value returns to its default value of 1 and the menu appears. The transition is set to 0.3 seconds so that the menu opens gradually instead of instantly, and the transform-origin property ensures that the menu appears from the top down instead of expanding from the center.

See the Pen CSS Dropdown (click) by Brian Kephart (@brian-kephart) on CodePen.

Hover to Open

If you prefer that your menu opens when you hover over the icon, then there is no need for <checkbox> or <label> tags. Instead, scale the #collapse-menu to 0 to hide it when it is not hovered (implying that it will return to full height when hovered). You will also need to scale the #collapse-menu to 1 when the icon is hovered. We will use the general sibling combinator ~ again to accomplish that. Last, you should introduce a delay to the transition. Otherwise when the user moves their pointer from the icon to the list, the menu will begin to collapse and then re-open. A tiny delay (0.2 seconds in this example) smooths things out.

See the Pen CSS Dropdown (hover) by Brian Kephart (@brian-kephart) on CodePen.

I have intentionally kept these examples simple for ease of learning, but don't forget to think about accessibility when using these elements! Don't rely on hover behavior alone unless you're sure all of your users can use that behavior. For example, the app I mentioned earlier adds the line &:focus-within { transform: scaleY(1); } to the CSS for the #collapse-menu, so users navigating the site with a keyboard will see the menu expand when they tab through to one of its options. For more info about making this approach accessible, go to