Dropdowns

Use a dropdown to put multiple options or items in a single menu. Although they aren’t always the most intuitive design pattern, they can be useful when space is limited.

Basic Dropdown

Check out this example dropdown:

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">Item 3</a></li>
  </ul>
</div>

Using Button Tags

You can also use <button> tags if you don’t wish to use <a> tags in the menu itself.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li><button>Button tag is used</button></li>
    <li><button>It looks identical!</button></li>
    <li><button>Semantics matter, choose wisely</button></li>
  </ul>
</div>

Disable Dropdown Menu Arrow

If you don’t want to include the little arrow pointing toward your dropdown button, you can flip it off using the variable $dropdown-arrow-enabled. It is set to true by default.

Alternatively, you can force the arrow to hide using the has-no-arrow class on the dropdown-menu element

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu has-no-arrow">
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><a href="#">Item 3</a></li>
  </ul>
</div>

Using Custom Buttons

You can use any button style with a dropdown. Just add the appropriate class to the dropdown button.

Alignment

All dropdowns, by default, are aligned inline-start, as shown in previous examples.

You can let it align inline-end using is-aligned-inline-end, or from block-end using is-aligned-block-end on the dropdown-menu element. Note that this only works for viewports above a specific width, as defined using the variable $dropdown-direction-breakpoint (sorry mobile viewers). Set this var to 'xsmall' to remove the breakpoint.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Right-Aligned Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-aligned-inline-end">
    <li><h6 class="dropdown-header">Aligned Block-End</h6></li>
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
  </ul>
</div>

Direction

All dropdowns, by default, drop block-end, as shown in previous examples.

You can let it drop block-start, inline-start, and inline-end using is-drop-block-start, is-drop-inline-start, and is-drop-inline-end, respectively. Note that this only works for viewports above a specific width, as defined using the variable $dropdown-direction-breakpoint (sorry mobile viewers). Again, set this var to 'xsmall' to remove the breakpoint.

<!-- drop block-start -->
<div data-dropdown="dropdown-id1" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id1" data-target="dropdown-menu-id">
    Drop Block-Start
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-block-start">
    ...
  </ul>
</div>
<!-- drop inline-end -->
<div data-dropdown="dropdown-id2" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id2" data-target="dropdown-menu-id">
    Drop Inline-End
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-inline-end">
    ...
  </ul>
</div>
<!-- drop inline-start -->
<div data-dropdown="dropdown-id3" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id3" data-target="dropdown-menu-id">
    Drop Inline-Start
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-inline-start">
    ...
  </ul>
</div>

You can also combine direction with alignment to get even more customization!

<!-- drop block-start & aligned inline-3nd -->
<div data-dropdown="dropdown-id1" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id1" data-target="dropdown-menu-id">
    Drop Block-Start, Aligned Inline-End
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-block-start is-aligned-inline-end">
    ...
  </ul>
</div>
<!-- drop inline-end & aligned block-end -->
<div data-dropdown="dropdown-id2" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id2" data-target="dropdown-menu-id">
    Drop Inline-End, Aligned Block-End
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-inline-end is-aligned-block-end">
    ...
  </ul>
</div>
<!-- drop inline-start & aligned block-end -->
<div data-dropdown="dropdown-id3" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id3" data-target="dropdown-menu-id">
    Drop Inline-Start, Aligned Block-End
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu is-drop-inline-start is-aligned-block-end">
    ...
  </ul>
</div>

Add an <hr/> to a dropdown list item to create a visual separator between buttons.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li><a href="#">Item 1</a></li>
    <li>
      <a href="#">Item 2</a>
      <hr />
    </li>
    <li><a href="#">Item 3</a></li>
  </ul>
</div>

Add headers and paragraph text to your dropdown for added context.

Headers

You can add any level of header to a dropdown menu.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li><h3 class="dropdown-header">Menu Header (h3)</h3></li>
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a></li>
    <li><h5 class="dropdown-header">Menu Header (h5)</h5></li>
    <li><a href="#">Item 3</a></li>
  </ul>
</div>

Paragraph Text

Paragraph text will wrap like it does everywhere else. Use spacing utilities to help it look organized.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li class="has-p-sm has-gray800-text-color">
      Would you like to receive newsletters from Cool Company, Inc?
    </li>
    <li><a href="#">Sure!</a></li>
    <li><a href="#">Nope</a></li>
  </ul>
</div>

Learn more about Spacing and Color helpers.

Requirements

Two main pieces are required: a single line of JS and correct HTML markup.

HTML

Container Attributes

The dropdown container has both the button and the menu.

<div data-dropdown="dropdown-id" class="dropdown">...</div>
  • data-dropdown: an attribute containing a unique id for the dropdown container.

Trigger Attributes

The button needs a few key attributes as well.

<div data-dropdown="dropdown-id" class="dropdown">
  <button id="dropdown-button-id" data-parent="dropdown-id" data-target="dropdown-menu-id">
    Open Dropdown
  </button>
  ...
</div>
  • id: a unique id describing the button.
  • data-parent: an attribute containing the value of the container element’s data-dropdown attribute.
  • data-target: an attribute containing the value of the dropdown menu’s id attribute.

The menu itself only needs one attribute.

<div data-dropdown="dropdown1" class="dropdown">
  ...
  <ul id="dropdown-menu-id" class="dropdown-menu">
    <li><a href="#0">Item 1</a></li>
    <li><a href="#0">Item 2</a></li>
    <li><a href="#0">Item 3</a></li>
  </ul>
</div>
  • id: a unique id containing the value of the dropdown button’s data-target attribute.

Accessibility

A few key attributes are added for you when the dropdown is instantiated. These help assistive technologies know how to treat and navigate through the component.

  • aria-expanded: added to the button element, describing if the dropdown menu is visible or not.
  • aria-haspopup: added to the button element, an attribute equal to true, it will tell assistive technologies this button has a menu associated with it.
  • aria-controls: added to the button element, an attribute given to the dropdown button with matching value to the dropdown menu’s id.
  • aria-labelledby: added to the menu, an attribute that is assigned a value equal to the id from the dropdown button, telling assistive technologies the element that triggered the menu.

See WAI-ARIA documentation on best-practices for the menu button UI pattern.

Helper Classes

Required:

  • dropdown: the container class providing inline and relative positioning of the component.
  • dropdown-menu: the menu class that provides positioning relative to the button.

Optional:

  • is-aligned-inline-end: aligns the menu to inline-end of the dropdown button.
  • is-aligned-block-end: aligns the menu to block-end of the dropdown button.
  • is-drop-inline-start: positions the menu to inline-start when open.
  • is-drop-inline-end: positions the menu to inline-end when open.
  • is-drop-block-start: positions the menu to block-start when open.

API

See Download documentation to see how to add the JS to your site, and JavaScript documentation to see general API details.

Call one of the following scripts from Undernet's JavaScript (not both!). This should happen only once on page load.

Undernet.start()
Undernet.Dropdowns.start()

Alternatively, if you wish to initialize only a single component instance, you can pass a string denoting the id used in your data-dropdown attribute:

Undernet.Dropdowns.start("my-id-123")

Is there information missing? Edit this page on Github!