Skip to content
Indiana University Logo
Rivet Design System
  • Components Add-ons Content guide Migration guide
  • What is Rivet? Blog Changelog
  1. May 4, 2022

    Rivet 2.0.0-beta.4 release

    The fourth Rivet 2 beta release introduces design updates to several components and a new responsive table wrapper element.

  2. March 30, 2022

    Rivet 2.0.0-beta.3 release

    The third Rivet 2 beta release updates accordion, badge, and button styles.

  3. February 9, 2022

    Rivet 2.0.0-beta.2 release

    The latest Rivet 2 beta release introduces the link hub component, adds new utility classes, and refactors component JavaScript.

More posts Get updates in your inbox
Install via NPM Download CSS & JS Hosted assets
Navigation
    • Components
    • Add-ons
    • Content guide
    • What is Rivet?
    • Blog
    • Roadmap
    • Changelog
  • Use Rivet
Resources
  • User Experience Office
  • Accessibility Evaluations
  • Rivet Software Design System
  • IU Framework for WCMS
Rivet 1 is deprecated. Please use Rivet 2 instead.
Version 1.8.3
  • Information
    • Changelog
    • Component status
    • Contributing
  • Getting started
    • Install with NPM
    • Rivet Sass
  • Layout
    • Box
    • Grid
    • Panels
    • Spacing
    • Typography
  • Page content
    • Badges
    • Links
    • Lists
    • Media Object
    • Step Indicator
    • Tables
    • Tabs This component requires JS
    • Timeline
  • Forms
    • Buttons
    • Segmented Buttons
    • Checkboxes
    • File input This component requires JS
    • Input group
    • Radio buttons
    • Select element
    • Text inputs
  • Navigation
    • Breadcrumb
    • Dropdown This component requires JS
    • Footer
    • Header This component requires JS
    • Menu
    • Pagination
  • Overlays & Feedback
    • Alerts This component requires JS
    • Loading indicator
    • Modals This component requires JS
  • Utilities
    • Border
    • Display
    • Flex
    • Text
    • Visibility
    • Width
    • z-index
Ready Added in 1.0.0

Dropdown

Use the dropdown component to create a list of menu options that can be toggled with a button element.

Migrating to Rivet 2

This version of Rivet is deprecated. View the dropdown documentation on the Rivet 2 website.

Dropdown example

Item one Item two Item three Item four
Related item three Related item four
<div class="rvt-dropdown">
    <button
         type="button"
        class="rvt-button"
        data-dropdown-toggle="dropdown-navigation"
        aria-haspopup="true"
        aria-expanded="false"
    >
        <span>Navigation menu</span>
        <svg aria-hidden="true" class="rvt-m-left-xs" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
            <path fill="currentColor" d="M8,12.46a2,2,0,0,1-1.52-.7L1.24,5.65a1,1,0,1,1,1.52-1.3L8,10.46l5.24-6.11a1,1,0,0,1,1.52,1.3L9.52,11.76A2,2,0,0,1,8,12.46Z"/>
        </svg>
    </button>
    <div
        class="rvt-dropdown__menu"
        id="dropdown-navigation"
        aria-hidden="true"
        role="menu"
    >
        <a href="#">Item one</a>
        <a href="#">Item two</a>
        <a href="#" aria-current="page">Item three</a>
        <a href="#">Item four</a>
        <div role="group" aria-label="Related">
            <a href="#">Related item three</a>
            <a href="#">Related item four</a>
        </div>
    </div>
</div>

When to use

Use a dropdown menu when you need to give users a list of actions or links to choose from.

When to consider something else

Although similar to a native HTML <select> element, the dropdown component should not be used as a replacement inside forms. Use the select element instead when you need to give users a list of mutually exclusive choices while filling out a form.

Accessibility requirements

If you need to create the Dropdown functionality in another framework/library like React, Angular, etc., please ensure that it meets the following accessibility requirements.

Focus

  • Dropdown button and Menu options should have a visible keyboard :focus state
  • When escape key Escape is pressed and the menu is active/open, focus should be returned to the Dropdown Button associated with that menu.
  • (Optional) When focused on the last menu item, the down arrow key ↓ should move focus to the first menu item.
  • (Optional) When focused on the first menu item, the up arrow key ↑ should move focus to the last menu item.

Labeling

  • Dropdown button has aria-haspopup set to true.
  • Menu has role menu.
  • When menu is visible, button has aria-expanded set to true. When menu is hidden, it is set to false.
  • (Optional) Dropdown button has aria-controls attribute that refers to the Menu
  • Menu visibility should be toggled using the aria-hidden attribute.
  • Menu items should use the appropriate roles, states, and properties depending their functionality. More on that here.

Keyboard navigation

  • Enter or Space = Open Menu
  • Escape = Close Active Menu
  • ↓ = Open Menu (when button focused)
  • ↑↓ = Moves focus to previous/next menu option

Implementation notes

To use the dropdown component, add a data attribute of data-dropdown-toggle to the button element you want to use to show/hide the menu, then add an id with a matching value to the .rvt-dropdown__menu element.

Right-align modifier

To align the dropdown menu with the right side of the dropdown button, add the .rvt-dropdown__menu--right class to the .rvt-dropdown__menu element.

Item one Item two Item three Item four
<div class="rvt-dropdown">
    <button
        type="button"
        class="rvt-button rvt-button--secondary"
        data-dropdown-toggle="dropdown-right"
        aria-haspopup="true"
        aria-expanded="false"
    >
        <span>Right menu</span>
        <svg aria-hidden="true" class="rvt-m-left-xs" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
            <path fill="currentColor" d="M8,12.46a2,2,0,0,1-1.52-.7L1.24,5.65a1,1,0,1,1,1.52-1.3L8,10.46l5.24-6.11a1,1,0,0,1,1.52,1.3L9.52,11.76A2,2,0,0,1,8,12.46Z"/>
        </svg>
    </button>
    <div
        class="rvt-dropdown__menu rvt-dropdown__menu--right"
        id="dropdown-right"
        aria-hidden="true"
        role="menu"
    >
        <a href="#">Item one</a>
        <a href="#">Item two</a>
        <a href="#" aria-current="page">Item three</a>
        <a href="#">Item four</a>
    </div>
</div>

Elements inside the dropdown menu

The dropdown menu will work with either links (<a> tags) or buttons (<button> tags). The keyboard navigation implementation accounts for any focusable elements, so it will work with form controls like text inputs, textareas, and select elements as well.

Additional dropdown elements

We’ve also included a couple of extra layout elements here for when you may need to add some visual hierarchy to your dropdowns:

  • Use the .rvt-dropdown__menu-heading element to provide help and to label a related group of menu items. This should be a generic <div> and should have an aria-hidden="true" attribute applied to it so that the label for the grouped items will not be announced to screen readers twice. E.g. the .rvt-dropdown__menu-heading content and then the value of the aria-label applied to the group (see next bullet point).
  • The dropdown heading should generally be used to group related options. Wrap related options in a <div> with a role=“group”. Using role="group will apply a top border to the related options. Additionally, you will need to add an aria-label attribute with a value that describes the group. This label will be announced to screen reader users.
  • To mark a dropdown menu item as selected, add the aria attribute aria-checked="true" (for js-driven/application menus), or aria-current="page" (for navigation/link menus) to the menu item.

The following example shows how to implement these additional dropdown elements.

Personal settings
<div class="rvt-dropdown">
    <button type="button" class="rvt-button" data-dropdown-toggle="dropdown-1" aria-haspopup="true" aria-expanded="false">
        <span>Application menu</span>
        <svg aria-hidden="true" class="rvt-m-left-xs" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
            <path fill="currentColor" d="M8,12.46a2,2,0,0,1-1.52-.7L1.24,5.65a1,1,0,1,1,1.52-1.3L8,10.46l5.24-6.11a1,1,0,0,1,1.52,1.3L9.52,11.76A2,2,0,0,1,8,12.46Z"/>
        </svg>
    </button>
    <div class="rvt-dropdown__menu" id="dropdown-1" role="menu" aria-hidden="true">
        <button type="button" role="menuitemradio">Notify all</button>
        <button type="button" role="menuitemradio" aria-checked="true">Notify admins</button>
        <button type="button" role="menuitemradio">Notify contributors</button>
        <div class="rvt-dropdown__menu-heading" aria-hidden="true">Personal settings</div>
        <div role="group" aria-label="Personal settings">
            <button type="button" role="menuitem">Profile Settings</button>
            <button type="button" role="menuitem">Logout</button>
        </div>
    </div>
</div>

A note about buttons

While it is possible to use any element as a toggle for the dropdown menu, you should always use an HTML <button> element. The button element was made for triggering new content within the current context or performing in-page actions. Plus, its appearance is completely styleable using CSS (so dropdown toggles don’t always need to look like the default Rivet button). Buttons are the best and most accessible choice for toggling the dropdown menu.

Navigation menus vs. application menus

The Rivet dropdown is flexible enough to be used with lists of navigation links, or buttons that can be used for in-app JavaScript-driven behavior. There are some subtle differences in the way these two types of menus should be implemented.

Navigation menus

  • Navigation menus are a set of links used to navigate to pages/URLs in an application.
  • Use the aria-current="page" attribute to indicate in the menu, both to screen readers and visually, if the user is on the current page.
  • Use a generic div element with the role="group" attribute applied to it to group related links. This will also apply a top border to help visually separate groups of menu items.
  • NOTE: Do not use the role="menuitem" attribute on links in a navigation menu. It will override the way screen readers announce items as "Links".

Application menus

  • Application menus generally contain lists of buttons that are used for JavaScript-driven/in-page behavior.
  • Application menu items (buttons) should use the role="menuitemradio" when they are used to toggle JavaScript-driven functionality. Otherwise, buttons should use the role="menuitem" attribute.
  • To indicate the current state of an application menu item, use the aria-checked="true" attribute.

JavaScript API

The Dropdown JavaScript exposes a couple of methods to use in your own scripts. The init() method is called by the main rivet.js file the first time the script is loaded. It will initialize the dropdown component and attach the event listeners that handle interaction.

Available methods

Here’s a breakdown of the available Dropdown methods you can use in your scripts.

Dropdown JavaScript methods
Method Description
Dropdown.init(context)
  • Initializes the Dropdown component
  • Accepts an optional DOM element. If no element is provided in the argument it defaults to the document element.
  • NOTE: the init() method is called automatically when rivet.js is loaded.
Dropdown.destroy(context)
  • Destroys any currently initialized dropdowns and removes their event listeners.
  • Accepts a optional DOM element. If no element is provided in the argument it defaults to the document element. NOTE: the optional context argument only needs to be passed into .destroy() if a DOM element was passed into the .init() method. If so, it must be the DOM element that was passed into .init() when the Dropdown was initialized.
Dropdown.open(id, callback)
  • id - The unique id of the dropdown. This corresponds to the value data-dropdown-toggle/id attributes of the dropdown you want to open.
  • callback - An optional callback function that is executed after the dropdown is opened.
Dropdown.close(id, callback)
  • id - The unique id of the dropdown. This corresponds to the value data-dropdown-toggle/id attributes of the dropdown you want to close.
  • callback - An optional callback function that is executed after the dropdown is closed.
Dropdown.toggle(id, callback)
  • Sets the Dropdown to the opposite of its current state. For example, if it is open/visible, calling the Dropdown.toggle(id) method will close the dropdown it’s called on and vice versa.
  • id the unique id of the dropdown you want to toggle
  • callback an optional callback function that is executed after the Dropdown is toggled.
Dropdown.closeAll() Deprecated
  • NOTE: This method is deprecated and should be replaced with the newer Dropdown.open() and Dropdown.close() methods.
  • Closes all open dropdowns.

Custom Events

The Rivet Dropdown also emits various custom events that you can listen for in your own scripts.

Dropdown JavaScript custom events
Event Description
dropdownOpen Emitted when the Dropdown is opened (using the Dropdown.open() method, or the data-dropdown-toggle attribute). The value of the Dropdown toggle’s data-dropdown-toggle attribute is also passed along (if it exists) via the custom event’s detail property and is available to use in your scripts as event.detail.name()
dropdownClose Emitted when the Dropdown is closed (using the Dropdown.close() method, or the data-dropdown-toggle attribute). The value of the Dropdown toggle’s data-dropdown-toggle attribute is also passed along via the custom event’s detail property and is available to use in your scripts as event.detail.name()

Custom event example

Note here that the event.detail.name() property of the customEvent object is a function that returns a String. Read more about custom events on the MDN web docs.

// Listen for a custom "dropdownOpen" event
document.addEventListener('dropdownOpen', event => {
  if (event.detail.name() === 'my-dropdown') {
    alert('Hey, you opened the dropdown!')
  }
  // Maybe send some data via an AJAX request, etc...
}, false);

On this page

    • Dropdown example
    • When to use
    • When to consider something else
    • Accessibility requirements
    • Implementation notes
      • Right-align modifier
      • Elements inside the dropdown menu
      • Additional dropdown elements
      • A note about buttons
    • Navigation menus vs. application menus
    • JavaScript API
      • Available methods
      • Custom Events
        • Custom event example
  • Accessibility
  • Privacy Notice
  • Copyright © The Trustees of Indiana University