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 of 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-dropdown
container; - Ideally the target should be a button;
- If the button doesn't have any text content (just an icon), add a meaningful
aria-label
to the button; - Add an unique
id
and the classflix-dropdown__items
to the list of items that should be displayed; - Add the
hidden
attribute to the list of items if you wish to initialize it hidden by default; - If you want it to be active make sure the
hidden
attribute is removed andflix-dropdown--active
CSS class is there; - Finally, connect the dropdown target to the list by passing the list
id
as value to the target'sdata-dropdown
attribute; - 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>
<ul id="dropdown-menu" hidden="" 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>
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>
<ul id="dropdown-idea-example" hidden="" 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>
</section>
</div>
</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-dropdown
container; - Add the
flix-dropdown__items
to the list of items that should be rendered in the dropdown balloon:- Add an
id
to the list of items to connect it to the target; - Add the
hidden
attribute 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 list by using
aria-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-label
for accessibility;
- Connect the target to the list by using
- The dropdown should also implement the menu and menuitem roles:
- Add
role="menu"
to the dropdown element (the list that has an id); - Add
role="presentation
on 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--active
modifier class;- The
aria-expanded
to be"true"
or"false"
on the target accordingly; - The
hidden
attribute on the dropdown list.
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.