CSS Dropdowns

A dropdown is a hidden panel of links or content that appears when the user hovers over or focuses a trigger element.

Dropdowns are built from two parts: a trigger the user interacts with and a menu that stays hidden until it is needed. CSS handles the show and hide entirely, so no JavaScript is required for a basic hover menu.

The Basic Structure

Wrap the trigger and the menu in a container. The container is set to <position: relative> so the menu can be positioned against it, and the menu itself starts hidden with <display: none>.

Hide the menu, position the wrapper

<!DOCTYPE html>
<html>
<head>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 180px;
  background: #ffffff;
  border: 1px solid #ddd;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body>

<div class="dropdown">
  <button>Account</button>
  <div class="dropdown-menu">
    <a href="#">Profile</a>
    <a href="#">Settings</a>
    <a href="#">Log out</a>
  </div>
</div>

</body>
</html>

Revealing on Hover

When the wrapper is hovered, switch the menu back to a visible display value. Because the menu sits inside the wrapper, moving from the trigger down to the menu keeps the hover active.

Show on hover and focus

<!DOCTYPE html>
<html>
<head>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background: #ffffff;
  border: 1px solid #ddd;
}

.dropdown:hover .dropdown-menu,
.dropdown:focus-within .dropdown-menu {
  display: block;
}

.dropdown-menu a {
  display: block;
  padding: 10px 16px;
  color: #333;
  text-decoration: none;
}

.dropdown-menu a:hover {
  background: #f2f2f2;
}
</style>
</head>
<body>

<div class="dropdown">
  <button>Account</button>
  <div class="dropdown-menu">
    <a href="#">Profile</a>
    <a href="#">Log out</a>
  </div>
</div>

</body>
</html>
Note: Adding :focus-within alongside :hover lets keyboard users open the menu by tabbing into it, which makes the dropdown far more accessible.
  • Navigation menus that group related pages under one heading
  • Account or profile menus in the corner of an app
  • A list of actions attached to a button, sometimes called a menu button
  • Language or currency pickers
Note: Pure CSS hover dropdowns are hard to use on touch screens, where there is no hover state. For production menus, pair the CSS with a little JavaScript that toggles a class on tap.

Exercise: CSS Dropdowns

In a typical CSS-only dropdown menu, how is the dropdown content initially hidden before the user interacts with it?