Chips
Provides a compact UI element used either to represent a filter or to recommend an option.
On this page
You can find here the OUDS chip design guidelines.
Overview
Component types
- Filter chip is a filter option that can be selected or deselected by the user.
- Suggestion chip is a recommended or predictive option based on user input or context.
Approach
Chip components are always displayed in a containing list with a ul.chip-container
class as they are always displayed as a group. This can be adapted to your needs and context of use.
.chip-container
manages the overall chip list layout.
.chip
is the main class defining the chip component. It controls the placement inside the container and the click area.
.chip-interactive
is the element that carries the interactive part of the component.
Accessibility
Visually impaired and blind users will lack the visual context that permits to understand the chips list purpose on the page especially if chips' labels are not self-explanatory. Thus it's mandatory to add a semantically informative title to describe the chips' list purpose if possible, otherwise an aria-label
on the containing ul
must be added. To improve accessibility and denote the chips' list uniqueness of purpose, it's possible to add role=group
on a parent container (but not the ul
as it would not work).
Several examples are provided below but they will need to be adapted for actual use cases.
Pseudo elements
Here is a table summarizing the pseudo elements that are used by the different variants of the chip.
chip variant | .chip-interactive::before | .chip-interactive::after |
---|---|---|
Filter chip | Used | Used |
Suggestion chip | – | Used |
Filter chip
Filter chips allow users to filter content by selecting or deselecting specific categories or attributes while keeping the element on the page. They are based on checkbox inputs, but we also have button based or radio button based filter chips. Thus, there is a selected state on this variant of the component.
To create a filter chip, add .chip-filter
to the .chip
.
If possible, display a semantically informative title to describe the chips' list purpose like in the following example, otherwise an aria-label
must be added to the .chip-container
to explain the function of the chips, more information here.
Filter by brands
<h4 id="filtersHeader">Filter by brands</h4>
<div role="group" aria-labelledby="filtersHeader">
<ul class="chip-container">
<li class="chip chip-filter">
<input type="checkbox" id="appleCheck" checked />
<label class="chip-interactive" for="appleCheck">
Apple
</label>
</li>
<li class="chip chip-filter">
<input type="checkbox" id="samsungCheck" />
<label class="chip-interactive" for="samsungCheck">
Samsung
</label>
</li>
<li class="chip chip-filter">
<input type="checkbox" id="xiaomiCheck" />
<label class="chip-interactive" for="xiaomiCheck">
Xiaomi
</label>
</li>
</ul>
</div>
Technical implementation
Using radio buttons
To have only one active filter chip at a time, use the radio button version. All the rules explained in this page about filter chips apply on this variant as well.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<input type="radio" id="radioCheck" name="radio" />
<label class="chip-interactive" for="radioCheck">
Filter with radio 1
</label>
</li>
<li class="chip chip-filter">
<input type="radio" id="radioCheck2" name="radio" />
<label class="chip-interactive" for="radioCheck2">
Filter with radio 2
</label>
</li>
<li class="chip chip-filter">
<input type="radio" id="radioCheck3" name="radio" checked />
<label class="chip-interactive" for="radioCheck3">
Filter with radio 3
</label>
</li>
</ul>
Using buttons
If you need to trigger a dynamic interaction directly on the page, <button>
markup is also supported. All the rules explained in this page about filter chips apply on this variant as well.
The style is applied on [aria-pressed="true"]
to enforce a good level of accessibility.
Make use of our button JS plugin or handle interactivity on your side, but make sure to use aria-pressed
.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Filter label using button 1
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Filter label using button 2
</button>
</li>
</ul>
Button plugin
The button plugin allows you to create simple on/off toggle buttons.
Toggle states
Add data-bs-toggle="button"
to toggle a button’s active
state. If you’re pre-toggling a button, you must manually add the .active
class and aria-pressed="true"
to ensure that it is conveyed appropriately to assistive technologies.
Methods
You can create a button instance with the button constructor, for example:
const bsButton = new oudsWeb.Button('#myButton')
Method | Description |
---|---|
dispose | Destroys an element’s button. (Removes stored data on the DOM element) |
getInstance | Static method which allows you to get the button instance associated with a DOM element, you can use it like this: oudsWeb.Button.getInstance(element) . |
getOrCreateInstance | Static method which returns a button instance associated with a DOM element or creates a new one in case it wasn’t initialized. You can use it like this: oudsWeb.Button.getOrCreateInstance(element) . |
toggle | Toggles push state. Gives the button the appearance that it has been activated. |
For example, to toggle all chips:
document.querySelectorAll('.chip-suggestion').forEach(chipElement => {
const chip = oudsWeb.Button.getOrCreateInstance(chipElement)
chip.toggle()
})
Variants
Text and icon
To display an icon add the icon as the last child of the .chip-interactive
.
The recommended way to use icons is to fill an SVG sprite file, and use currentColor
for styling. If really necessary, for example when you have a lot of icons, you can use an icon font. Find out more about using icons.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<input type="checkbox" id="filterWithIcon" />
<label class="chip-interactive" for="filterWithIcon">
Filter with icon
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
</label>
</li>
<li class="chip chip-filter">
<input type="checkbox" id="filterWithIcon2" checked />
<label class="chip-interactive" for="filterWithIcon2">
Another filter with icon
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
</label>
</li>
</ul>
Icon only
To display a chip with only an icon, add .chip-icon
to the interactive part of the component.
The recommended way to use icons is to fill an SVG sprite file, and use currentColor
for styling. If really necessary, for example when you have a lot of icons, you can use an icon font. Find out more about using icons.
Make sure to provide an accessible text for each chip.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<input type="checkbox" id="filterIconOnly1" />
<label class="chip-interactive chip-icon" for="filterIconOnly1">
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
<span class="visually-hidden">Favorites</span>
</label>
</li>
<li class="chip chip-filter">
<input type="checkbox" id="filterIconOnly2" checked />
<label class="chip-interactive chip-icon" for="filterIconOnly2">
<span class="icon si si-settings" aria-hidden="true"></span>
<span class="visually-hidden">Technical</span>
</label>
</li>
</ul>
States
Disabled state
Add disabled
attribute either on the input or on the button element to disable the chip.
The following example shows every possible renderings depending on the filter chip type but it is not recommended to mix different types in a real use case.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<input type="checkbox" id="disabledFilter" checked disabled />
<label class="chip-interactive" for="disabledFilter">
Disabled checked filter
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
</label>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button" disabled>
Disabled unchecked filter
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
</button>
</li>
</ul>
Suggestion chip
Suggestion chips show relevant options based on user input or context. They help users quickly choose from dynamic or recommended items. Since this implies a dynamic behavior, these should be implemented using buttons.
To create a suggestion chip, add .chip-suggestion
to the .chip
.
If possible, display a semantically informative title to describe the chips' list purpose, otherwise an aria-label
must be added to the .chip-container
to explain the function of the chips, like in the following example. More information here.
<ul class="chip-container" aria-label="Answer with">
<li class="chip chip-suggestion">
<button class="chip-interactive">
Thanks.
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive">
Looks good to me.
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive">
Can we talk about it later ?
</button>
</li>
</ul>
Variants
Text and icon
To display an icon, add the icon as the first child of the .chip-interactive
.
The recommended way to use icons is to fill an SVG sprite file, and use currentColor
for styling. If really necessary, for example when you have a lot of icons, you can use an icon font. Find out more about using icons.
<ul class="chip-container" aria-label="Answer with">
<li class="chip chip-suggestion">
<button class="chip-interactive">
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
Suggestion with icon 1
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive">
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
Suggestion with icon 2
</button>
</li>
</ul>
Icon only
To display a chip with only an icon, add .chip-icon
to the <button>
.
The recommended way to use icons is to fill an SVG sprite file, and use currentColor
for styling. If really necessary, for example when you have a lot of icons, you can use an icon font. Find out more about using icons.
Make sure to provide an accessible text for each chip.
<ul class="chip-container" aria-label="Answer with">
<li class="chip chip-suggestion">
<button class="chip-interactive chip-icon">
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
<span class="visually-hidden">I love it.</span>
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive chip-icon">
<span class="icon si si-settings" aria-hidden="true"></span>
<span class="visually-hidden">Go to parameters.</span>
</button>
</li>
</ul>
States
Disabled state
Add disabled
attribute on the button element to disable the chip.
The following example shows every possible renderings depending on the suggestion chip type but it is not recommended to mix different types in a real use case.
<ul class="chip-container" aria-label="Answer with">
<li class="chip chip-suggestion">
<button class="chip-interactive" disabled>
Thanks.
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive" disabled>
<svg aria-hidden="true">
<use xlink:href="/sosh/docs/0.5/assets/img/ouds-web-sprite.svg#heart-empty" />
</svg>
Suggestion with icon 1
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive chip-icon" disabled>
<span class="icon si si-settings" aria-hidden="true"></span>
<span class="visually-hidden">Send "Go to parameters."</span>
</button>
</li>
</ul>
Layout
This part explains global truth among all the chip variants.
Overflowing
By default when using .chip-container
the chip list will scroll horizontally on one line.
<ul class="chip-container" aria-label="Filter by">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
</ul>
Wrapping
Add .flex-wrap
on the .chip-container
element to display a wrapping list of chips. Beware with this option as it could take too much vertical space on mobile viewports, as a rule there should not be more than 2 or 3 lines of chips displayed.
<ul class="chip-container flex-wrap" aria-label="Filter by">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
</ul>
Mix of both
For some use cases, mixing wrapping and overflowing can lead to a better UX.
This layout combines wrapping and vertical scrolling, please note that a style="max-height: 115px;"
is added since we don’t want to display more than 2 or 3 lines, and still show part of the following line as a visual clue when the scrollbar is not displayed.
<ul class="chip-container flex-wrap" style="max-height: 115px;" aria-label="Filter by">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive active" aria-pressed="true" data-bs-toggle="button">
Quite long label
</button>
</li>
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
Quite long label
</button>
</li>
</ul>