Dropdown
The dropdown shows a list of possible actions.
The dropdown is used to show a list of options, such as links in a sub-menu or options in a data table, for example. It uses a balloon to display a navigation element and has to be attached to a target since it's position is relative to it.
The target is the element that, when interacted with, toggles the appearance of the dropdown.
We strongly advise that you use the Dropdown plugin since it makes things a lot easier by handling all the necessary attributes to toggle dropdowns and also set up all the required accessibility features, so you won't have to worry about keeping them in sync.
Building the Dropdown
The dropdown component requires a specific HTML structure in order to work correctly.
- Wrap the target element and the list of items with a
flix-dropdowncontainer; - Ideally the target should be a button;
- If the button doesn't have any text content (just an icon), add a meaningful
aria-labelto the button; - Add a unique
idtoflix-dropdown__items-containerelement; - Add the
hiddenattribute as well, if you wish to initialize the dropdown hidden by default; - If you want it to be active make sure the
hiddenattribute is removed fromflix-dropdown__items-containerandflix-dropdown--activeCSS class is present on theflix-dropdownelement; - Finally, connect the dropdown target to the list by passing the list
idas value to the target'sdata-dropdownattribute; - If you wish to change the default event trigger to hover, just add
data-event="hover"to the target;
To add a divider item, simply insert a <hr class="flix-divider"> in one of the list items, do not put it inside the "link" wrapper.
Voila! The plugin will automatically add the aria roles and attributes and will setup all te event handlers for you.
<div class="flix-dropdown">
<button type="button" class="flix-btn flix-btn--primary" data-dropdown="dropdown-menu">
Open dropdown
<flix-icon class="flix-btn__icon" name="arrow-down"></flix-icon>
</button>
<div id="dropdown-menu" hidden class="flix-dropdown__items-container">
<ul class="flix-dropdown__items">
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" aria-current="true" href="#">
<flix-icon name="edit" solid="true"></flix-icon>
Edit
</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">
<flix-icon name="share"></flix-icon>
Share
</a>
</li>
<li class="flix-dropdown__item">
<hr class="flix-divider" />
</li>
<li class="flix-dropdown__item">
<span class="flix-dropdown__link">
More options:
</span>
</li>
<li class="flix-dropdown__item">
<button class="flix-dropdown__link" type="button">
<flix-icon name="delete"></flix-icon>
Delete
</button>
</li>
</ul>
</div>
</div>Modifiers
By default, the dropdown positions itself in the center of the target element. Some modifiers are available to control the position of the dropdown:
flix-dropdown--top- positions the dropdown on top of the target
flix-dropdown--left- aligns the dropdown to the left of the target
flix-dropdown--right- aligns the dropdown to the right of the target
<div class="flix-box">
<div class="flix-grid">
<div class="flix-col">
<h3 class="flix-h3">Idea initiative</h3>
</div>
<div class="flix-col">
<section class="flix-has-text-right">
<div class="flix-dropdown flix-dropdown--top flix-dropdown--left">
<button
type="button"
aria-label="Options"
class="flix-btn flix-btn--square flix-btn--link"
data-dropdown="dropdown-idea-example"
>
<i class="flix-btn__icon flix-icon flix-icon--size-4 flix-icon-kebab" aria-hidden="true"></i>
</button>
<div id="dropdown-idea-example" hidden class="flix-dropdown__items-container">
<ul class="flix-dropdown__items">
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">Edit</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">Share</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">Delete</a>
</li>
</ul>
</div>
</div>
</section>
</div>
</div>
</div>Scrollable content
When there are too many items inside of dropdown it limits its height and shows visual scroll indicators on both sides. Those indicators indicate to the user that the content can be scrolled.
Default height limit is 315px and displays 7 items in full.
If needed you can adjust this limit with the max-height CSS property on the flix-dropdown__items element.
<div class="flix-dropdown">
<button type="button" class="flix-btn flix-btn--primary" data-dropdown="dropdown-menu-scrollable">
Open scrollable dropdown
<flix-icon class="flix-btn__icon" name="arrow-down"></flix-icon>
</button>
<div id="dropdown-menu-scrollable" hidden class="flix-dropdown__items-container">
<ul class="flix-dropdown__items">
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">
<flix-icon name="offer"></flix-icon>
Add
</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" aria-current="true" href="#">
<flix-icon name="edit" solid="true"></flix-icon>
Edit
</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">
<flix-icon name="copy"></flix-icon>
Copy
</a>
</li>
<li class="flix-dropdown__item">
<a class="flix-dropdown__link" href="#">
<flix-icon name="share"></flix-icon>
Share
</a>
</li>
<li class="flix-dropdown__item">
<hr class="flix-divider" />
</li>
<li class="flix-dropdown__item">
<span class="flix-dropdown__link">
More options:
</span>
</li>
<li class="flix-dropdown__item">
<button class="flix-dropdown__link" type="button">
<flix-icon name="delete"></flix-icon>
Delete
</button>
</li>
<li class="flix-dropdown__item">
<button class="flix-dropdown__link" type="button">
<flix-icon name="archive"></flix-icon>
Archive
</button>
</li>
</li>
<li class="flix-dropdown__item">
<button class="flix-dropdown__link" type="button">
<flix-icon name="reset"></flix-icon>
Reset
</button>
</li>
</ul>
</div>
</div>Making it work without the plugin
Before you continue we would really like to emphasize that you should use the plugin!
There are several steps you need to pay attention to make an accessible dropdown component:
- Wrap the target element and the list of items with a
flix-dropdowncontainer; - Add the
flix-dropdown__items-containerdiv and put the list of items (flix-dropdown__items) inside:- Add an
id(list_id) to theflix-dropdown__itemsto connect it to the target viaaria-controlsattribute; - Add the
hiddenattribute to the list to hide it from assistive technologies;
- Add an
- Add a button to be the target of the dropdown:
- Connect the target to the
flix-dropdown__itemslist by usingaria-controls="{list_id}>"; - Add
aria-haspopup="menu"to the target to inform assistive technologies that this is a dropdown component; - Add
aria-expanded="true"or"false"attribute to inform assistive technologies of the status of the target; - If the button doesn't have any text content, add a meaningful
aria-labelfor accessibility;
- Connect the target to the
- The dropdown should also implement the menu and menuitem roles:
- Add
role="menu"to the list element (the list that has the menu items); - Add
role="presentationon the list items, since they no longer represent a simple list but are part of a sub menu context; - Add
role="menuitem"to the link elements;
- Add
When the user interacts with the target you must toggle and keep in sync:
flix-dropdown--activemodifier class;- The
aria-expandedto be"true"or"false"on the target accordingly; - The
hiddenattribute onflix-dropdown__items-container.
You must also allow closing the dropdown by pressing ESC on the keyboard.
Check the related guides section for relevant documentation you can use as reference to implement an accessible dropdown menu.