Menu Button Component
NOTE: .
Default Menu Button
The default menu button opens a stateless menu. Each item has a role of menuitem .
<span class="menu-button">
<button class="btn" aria-expanded="false" aria-haspopup="true" type="button">
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitem">
<span> Menu Item 1 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 2 </span>
</div>
<div class="menu-button__item" role="menuitem" aria-disabled="true">
<span> Menu Item 3 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 4 </span>
</div>
</div>
</div>
</span>
For all menu buttons, the overlay becomes automatically scrollable when its height reaches 400px.
Single-Select Menu Button
For single-select state, use role menuitemradio on each menu item.
<span class="menu-button">
<button
class="btn btn--secondary"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitemradio" aria-checked="true">
<span> Menu Item 1 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<span> Menu Item 2 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<span> Menu Item 3 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
</div>
</div>
</span>
Multi-Select Menu Button
For multi-select state, use role menuitemcheckbox on each menu item.
<span class="menu-button">
<button
class="btn btn--secondary"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<span> Menu Item 1 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<span> Menu Item 2 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="false"
>
<span> Menu Item 3 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
</div>
</div>
</span>
Labelling a Menu Button
By default, the text of any button acts as its accessible label. The accessible label must at all times reflect the purpose of the button. If the text only conveys a transient value , then the criteria would not be satisfied.
Fixed Label
The simplest scenario in which to satisfy the criteria is a fixed label, i.e. the button text never changes. For example: "Menu", "Options", "Edit".
Compact Label
If a fixed label is not possible, the button's inner text can potentially be written as a key/value pair, where key denotes purpose and value repesents the current selection. This is most typical in a single select menu button . For example: "Sort: Price", "Color: Red". This technique is identical to the method used by Listbox Button .
Compound Label
Finally, we can also consider using aria-labelledby to stitch together an additional, external element - therefore creating a compound label.
Grouped Menu Button
Menu button items can be separated into groups, using the hr tag.
<span class="menu-button">
<button
class="btn btn-secondary"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitem">
<span> Menu Item A1 </span>
</div>
<hr class="menu-button__separator" role="separator" />
<div class="menu-button__item" role="menuitemradio" aria-checked="true">
<span> Menu Item B1 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<span> Menu Item B2 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<span> Menu Item B3 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<hr class="menu-button__separator" role="separator" />
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<span> Menu Item C1 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<span> Menu Item C2 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</div>
</div>
</div>
</span>
Fake Menu Button
At first glance, a fake menu button appears to be a normal menu button component, but it contains a list of hyperlinks and thus behaves more like a navigational component.
Use the aria-current attribute to denote the link that matches the current page URL (if applicable).
A valid href attribute is required for all anchor tags (a value of "javascript" is not valid!) The button tag is also supported (as demonstrated in the following example) if JavaScript behaviour is required alongside items with navigation behaviour.
<span class="fake-menu-button">
<button
class="btn btn--secondary"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<ul class="fake-menu-button__menu">
<li>
<a
class="fake-menu-button__item"
href="https://www.ebay.com"
aria-current="page"
>
<span> Link 1 </span>
<svg class="icon icon--16" height="10" width="14" aria-hidden="true">
<use href="#icon-tick-16" />
</svg>
</a>
</li>
<li>
<a href="https://www.ebay.com" class="fake-menu-button__item">
<span> Link 2 </span>
</a>
</li>
<li>
<button class="fake-menu-button__item" type="button">
<span> Button 3 </span>
</button>
</li>
<li>
<button class="fake-menu-button__item" type="button">
<span> Button 4 </span>
</button>
</li>
</ul>
</span>
Fixed Width Menu Button
Use the menu-button__menu--fix-width or fake-menu-button__menu--fix-width element modifier to fix the width of any menu items to the button width. This is useful in cases where the menu overlay needs to be constrained to the button width, usually to accomodate spacing and layout.
NOTE: Fixed width is currently only available on menu buttons that use a span root tag.
<span class="menu-button">
<button
class="btn btn--secondary"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu menu-button__menu--fix-width">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitem">
<span> Menu Item 1 with a long string </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 2 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 3 </span>
</div>
</div>
</div>
</span>
Form-Themed Menu Button
If placing a menu-button alongside a form control (e.g. textbox), you may wish to apply the btn--form modifier, which better matches the look-and-feel of forms.
NOTE : a menu-button is a good candidate for a dropdown of actions that make changes to a form, but it should not be used as a dropdown for selecting and storing form data . Please use select or listbox-button for that purpose instead.
<span class="menu-button">
<button
class="btn btn--form"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitem">
<span> Menu Item 1 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 2 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 3 </span>
</div>
</div>
</div>
</span>
Borderless Menu Button
Use the btn--borderless modifier to create a minimal borderless button.
<span class="menu-button">
<button
class="btn btn--borderless"
aria-expanded="false"
aria-haspopup="true"
type="button"
>
<span class="btn__cell">
<span class="btn__text"> Button </span>
<svg class="icon icon--12" height="10" width="14" aria-hidden="true">
<use href="#icon-chevron-down-12" />
</svg>
</span>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitem">
<span> Menu Item 1 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 2 </span>
</div>
<div class="menu-button__item" role="menuitem">
<span> Menu Item 3 </span>
</div>
</div>
</div>
</span>
Filter menu button - checkbox
To use a filter menu button checkbox, use filter-chip as the button and have icon--checked and icon--unchecked elements inside each menuitemcheckbox
<span class="menu-button menu-button--filter">
<button
class="filter-chip"
aria-pressed="false"
aria-haspopup="true"
aria-expanded="false"
>
<span class="filter-chip__text btn__text"> Sport: (+2) </span>
<svg
aria-hidden="true"
class="filter-chip__trailing icon icon--12"
width="12"
height="12"
>
<use href="#icon-chevron-down-16" />
</svg>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 1 </span>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 2 </span>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="false"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 3 </span>
</div>
</div>
</div>
</span>
Filter menu button - radio
To use a filter menu button with radios, use filter-chip as the button and have icon--checked and icon--unchecked elements inside each menuitemradio
<span class="menu-button menu-button--filter">
<button
class="filter-chip"
aria-pressed="false"
aria-haspopup="true"
aria-expanded="false"
>
<span class="filter-chip__text"> Sport: (+2) </span>
<svg
aria-hidden="true"
class="filter-chip__trailing icon icon--12"
width="12"
height="12"
>
<use href="#icon-chevron-down-16" />
</svg>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-radio-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-radio-checked-18" />
</svg>
<span> Menu Item 1 </span>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="true">
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-radio-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-radio-checked-18" />
</svg>
<span> Menu Item 2 </span>
</div>
<div class="menu-button__item" role="menuitemradio" aria-checked="false">
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-radio-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-radio-checked-18" />
</svg>
<span> Menu Item 3 </span>
</div>
</div>
</div>
</span>
Filter menu button - with footer
To add a filter menu button with a footer, include .menu-button__footer container
<span class="menu-button menu-button--filter">
<button
class="filter-chip"
aria-pressed="false"
aria-haspopup="true"
aria-expanded="false"
>
<span class="filter-chip__text"> Sport: (+2) </span>
<svg class="filter-chip__trailing icon icon--12" width="12" height="12">
<use href="#icon-chevron-down-16" />
</svg>
</button>
<div class="menu-button__menu">
<div class="menu-button__items" role="menu">
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 1 </span>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="true"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 2 </span>
</div>
<div
class="menu-button__item"
role="menuitemcheckbox"
aria-checked="false"
>
<svg
aria-hidden="true"
class="icon icon--18 icon--unchecked"
height="18"
width="18"
>
<use href="#icon-checkbox-unchecked-18" />
</svg>
<svg
aria-hidden="true"
class="icon icon--18 icon--checked"
height="18"
width="18"
>
<use href="#icon-checkbox-checked-18" />
</svg>
<span> Menu Item 3 </span>
</div>
</div>
<div class="menu-button__footer">
<button class="btn btn--tertiary" type="submit">Apply</button>
</div>
</div>
</span>