Dropdown

Dropdown

Dropdown menus are hidden by default and can contain action lists with only a few items or more complicated filter or menu systems. Typically a button will show and hide them, though other components may also be used as a trigger.

Use them anywhere a set of links or controls do not need to be available on screen by default, when you need to show overflow controls, or when you have a complicated menu that does not rise to the level of a modal or drawer.

Basic dropdown

To create a dropdown, simply place both .hc-dropdown-toggle and .hc-dropdown-content elements inside of a parent .hc-dropdown.

The triggering element must currently be a <div> with class .hc-dropdown-toggle-button. You can turn this into a button by adding the same button classes as a regular button would get, but please note that the element itself has to be a <div>.


<div class="hc-dropdown">
  <div class="hc-dropdown-toggle">
    <div role="button" class="hc-button hc-button--primary hc-dropdown-toggle-button" tabindex="0">
      Dropdown toggle
    </div>
  </div>
  <div class="hc-dropdown-content" tabindex="0">
    <menu class="flex flex-col px-3 py-3 whitespace-nowrap">
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is an item</a>
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is another item</a>
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is a third item</a>
    </menu>
  </div>
</div>

Important note

The dropdown toggle must unfortunately be a <div> due to an ongoing bug in Safari that prevents a <button> element from receiving focus.

This is still accessible and compliant, just give it role="button" as well as tabindex="0". Both of these are necessary for the dropdown functionality.

JavaScript alternative handling

If you’d prefer to handle the dropdown show/hide yourself via JavaScript, append .hc-dropdown--js to the parent dropdown component and then manually add or remove the class .hc-dropdown--is-visible to this element.

Honeycomb handles the display and animation, but you will be responsible for any click handlers to add or remove this display class.


<div class="hc-dropdown hc-dropdown--js" id="ddjs">
  <div class="hc-dropdown-toggle">
    <div role="button" class="hc-button hc-button--primary" tabindex="0" onclick="document.getElementById('ddjs').classList.toggle('hc-dropdown--is-visible')">
      Dropdown toggle
    </div>
  </div>
  <div class="hc-dropdown-content" tabindex="0">
    <menu class="flex flex-col px-3 py-3 whitespace-nowrap">
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is an item</a>
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is another item</a>
      <a href="/" class="px-2 py-1 rounded hover:bg-gray-100">This is a third item</a>
    </menu>
  </div>
</div>

Interactions and states

Dropdowns have a subtle default fade-in and slide-up animation on reveal, with the reverse on hide. They have a default drop shadow as well. All of this is handled natively.

No javascript is required! As of v0.2.5 all dropdown interactions are now handled by CSS only. The parent .hc-dropdown element uses the :focus-within pseudo-class: when the triggering button gets focus, visibility and opacity styles are applied to the .hc-dropdown-content. Because it uses :focus-within, user actions inside of the dropdown itself do not cause it to close.

It’s important that the .hc-dropdown-toggle-button element is inside of an .hc-dropdown-toggle element. The later is used to maintain cursor: pointer; on the button when the dropdown is open.

The dropdown will close when the user clicks outside of it.

Dropdown button with caret

There is a special button variation specifically for dropdowns! This variation is used in the header for both the primary dropdown menus as well as the account menu dropdown.

Apply .hc-button--dropdown to get the basic effect. There are specific child elements and classes for content and the caret as well; content inside should have .hc-button--dropdown--content and the caret must be a <sub> element with class .hc-button--dropdown--caret.


<div class="hc-dropdown">
  <div class="hc-dropdown-toggle">
    <div role="button" class="hc-button hc-button--primary hc-dropdown-toggle-button" tabindex="0">
      Manage account
      <sub class="hc-button--dropdown--caret">toggle</sub>
    </div>
  </div>
  <menu class="hc-dropdown-content">
    <div class="hc-dropdown-list hc-dropdown-section--divider">
      <a href="/" class="hc-dropdown-list-link">
        <i class="hc-icon hc-icon--lock hc-icon--20"></i>
        Change password
      </a>
      <a href="/" class="hc-dropdown-list-link">
        <i class="hc-icon hc-icon--settings hc-icon--20"></i>
        Preferences
      </a>
      <a href="/" class="hc-dropdown-list-link">
        <i class="hc-icon hc-icon--language hc-icon--20"></i>
        Preferred language
      </a>
    </div>
  </menu>
</div>

Toggle direction

Dropdowns open centered to the toggle button by default. You can control this direction with utility classes; currently right-justified and left-justified are supported.

Left aligned toggle
This should be fixed to the left of the button.
Right aligned toggle
This should be fixed to the right of the button.

<div class="hc-dropdown">
  <div class="hc-dropdown-toggle">
    <div role="button" class="hc-button hc-button--primary hc-dropdown-toggle-button" tabindex="0">
      Left aligned
      <sub class="hc-button--dropdown--caret">toggle</sub>
    </div>
  </div>
  <menu class="hc-dropdown-content hc-dropdown-content--left w-48 p-4">
    This should be fixed to the left of the button.
  </menu>
</div>
<div class="hc-dropdown">
  <div class="hc-dropdown-toggle">
    <div role="button" class="hc-button hc-button--primary hc-dropdown-toggle-button" tabindex="0">
      Right aligned
      <sub class="hc-button--dropdown--caret">toggle</sub>
    </div>
  </div>
  <menu class="hc-dropdown-content hc-dropdown-content--right w-48 p-4">
    This should be fixed to the right of the button.
  </menu>
</div>