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.
.chip-container has no design specifications for now, please be aware the chip list display and behavior could evolve in the future.
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 textual information to explain what it represents.
If no visible list title is present, a hidden text on the first chip's .chip-interactive element is the best way to achieve this as it is the most widely compatible solution. For chips lists based on radio buttons, an aria-label on the containing ul is better suited as the selected element will be vocalized first instead of the first element in the list.
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.
<ul class="chip-container">
<li class="chip chip-filter">
<input type="checkbox" id="appleCheck" checked />
<label class="chip-interactive" for="appleCheck">
<span class="visually-hidden">Filter by</span>
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> 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">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
<span class="visually-hidden">Filter by</span>
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">
<li class="chip chip-filter">
<input type="checkbox" id="filterWithIcon" />
<label class="chip-interactive" for="filterWithIcon">
<span class="visually-hidden">Filter by</span>
Filter with icon
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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">
<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="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</svg>
<span class="visually-hidden">Filter by 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">
<li class="chip chip-filter">
<input type="checkbox" id="disabledFilter" checked disabled />
<label class="chip-interactive" for="disabledFilter">
<span class="visually-hidden">Filter by</span>
Disabled checked filter
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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.
<ul class="chip-container">
<li class="chip chip-suggestion">
<button class="chip-interactive">
<span class="visually-hidden">Answer with</span>
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">
<li class="chip chip-suggestion">
<button class="chip-interactive">
<span class="visually-hidden">Answer with</span>
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</svg>
Suggestion with icon 1
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive">
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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">
<li class="chip chip-suggestion">
<button class="chip-interactive chip-icon">
<span class="visually-hidden">Answer with</span>
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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">
<li class="chip chip-suggestion">
<button class="chip-interactive" disabled>
<span class="visually-hidden">Answer with</span>
Thanks.
</button>
</li>
<li class="chip chip-suggestion">
<button class="chip-interactive" disabled>
<svg aria-hidden="true">
<use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
</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">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
<span class="visually-hidden">Filter by</span>
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">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
<span class="visually-hidden">Filter by</span>
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.
This part is experimental and could change in the future.
<ul class="chip-container flex-wrap" style="max-height: 115px;">
<li class="chip chip-filter">
<button class="chip-interactive" data-bs-toggle="button">
<span class="visually-hidden">Filter by</span>
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>