Chips
Interactive, compact components for tags, filters and selections with support for avatars, icons, and removal actions.
Introduction
Chips are compact, interactive components that represent discrete information, such as filters, tags, or selections. Chassis CSS implements chips with a consistent design system that aligns with your Figma tokens, ensuring visual coherence across your interface while maintaining interactive functionality.
Foundation class
The .chip class establishes the foundational structure, typography, and interactive states for all chip variants. It provides consistent padding, border-radius, and focus handling while supporting multiple contextual variants.
<span class="chip">Foundation class</span>
<span class="chip default">Default chip</span>
<span class="chip primary">Primary chip</span> The .chip foundation class can be extended with contextual classes or serve as a base for custom styling through your design token system.
Element compatibility
While chips are typically rendered as <span> elements, the .chip class works seamlessly with various HTML elements to support different interaction patterns:
Accessibility: When using chips as interactive elements with <a> tags for in-page functionality, add role="button" to ensure proper semantics for assistive technologies.
<span class="chip primary">Span</span>
<div class="chip primary">Div</div>
<button class="chip primary" type="button">Button</button>
<a class="chip primary" href="#" role="button">Link</a> Color variants
Chassis CSS provides a range of semantically meaningful color variants for chips through its contextual color system. Each variant communicates a distinct purpose while maintaining design consistency.
<span class="chip default">Default</span>
<span class="chip alternate">Alternate</span>
<span class="chip primary">Primary</span>
<span class="chip secondary">Secondary</span>
<span class="chip neutral">Neutral</span>
<span class="chip danger">Danger</span>
<span class="chip success">Success</span>
<span class="chip warning">Warning</span>
<span class="chip info">Info</span>
<span class="chip black">Black</span>
<span class="chip white">White</span> Accessibility tip: Color alone shouldn't convey meaning as it's not perceived by assistive technology users. Ensure clarity through text with adequate contrast, ARIA attributes where needed, and consider using .visually-hidden for screen reader content.
Outline style
For interfaces requiring more subtle or secondary chip patterns, the .outline modifier creates a transparent background with a colored border while preserving the semantic color context.
<span class="chip default outline">Default</span>
<span class="chip alternate outline">Alternate</span>
<span class="chip primary outline">Primary</span>
<span class="chip secondary outline">Secondary</span>
<span class="chip neutral outline">Neutral</span>
<span class="chip danger outline">Danger</span>
<span class="chip success outline">Success</span>
<span class="chip warning outline">Warning</span>
<span class="chip info outline">Info</span>
<span class="chip black outline">Black</span>
<span class="chip white outline">White</span> Some chip variants use lighter foreground colors optimized for dark backgrounds to maintain proper contrast ratios.
Smooth style
The .smooth modifier applies a subdued background to chips, creating a softer visual presence while maintaining the contextual color relationship. This style is ideal for less prominent tags or filters.
<span class="chip default smooth">Default</span>
<span class="chip alternate smooth">Alternate</span>
<span class="chip primary smooth">Primary</span>
<span class="chip secondary smooth">Secondary</span>
<span class="chip neutral smooth">Neutral</span>
<span class="chip danger smooth">Danger</span>
<span class="chip success smooth">Success</span>
<span class="chip warning smooth">Warning</span>
<span class="chip info smooth">Info</span>
<span class="chip black smooth">Black</span>
<span class="chip white smooth">White</span> Icon integration
Enhance chips with icons to provide additional visual meaning or action affordances. Both SVG icons and icon fonts can be used within chips.
<span class="chip default">
<svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
<span>Default</span>
</span>
<span class="chip primary">
<svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
<span>Primary</span>
</span>
<span class="chip default">
<span>Default</span>
<span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</span>
<span class="chip primary">
<span>Primary</span>
<span class="icon icon-info-circle-solid" aria-hidden="true"></span>
</span> Icon spacing is automatically applied using :first-child and :last-child pseudo selectors. To ensure proper spacing, wrap the chip text in a <span> element.
Dismissible chips
Add a removal action to chips with the .close-button component, which automatically adapts to the chip's context color. The removal button is positioned consistently and includes proper accessibility attributes for screen reader users.
<span class="chip default">
Default
<button type="button" class="close-button" data-cx-dismiss="chip" aria-label="Remove"></button>
</span>
<span class="chip primary">
Primary
<button type="button" class="close-button" data-cx-dismiss="chip" aria-label="Remove"></button>
</span>
Size variants
Chassis provides three size variants for chips: default (medium), large, and small. Use the .large or .small modifier classes to adjust chip dimensions based on context and available space.
<span class="chip default">
Medium
</span>
<span class="chip default">
<svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
<span>Medium</span>
</span>
<span class="chip default large">
Large
</span>
<span class="chip default large">
<svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
<span>Large</span>
</span>
<span class="chip default small">
Small
</span>
<span class="chip default small">
<svg class="icon" aria-hidden="true" role="img"><use xlink:href="#info-circle-solid"/></svg>
<span>Small</span>
</span> Avatar integration
Enhance chips with user avatars by incorporating the .avatar component. The avatar automatically adapts to the chip size and maintains proper spacing with text content. Both image and text-based avatars are supported.
<span class="chip default">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Medium
<button type="button" class="close-button" aria-label="Remove"></button>
</span>
<span class="chip large default">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Large
<button type="button" class="close-button" aria-label="Remove"></button>
</span>
<span class="chip small default">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Small
<button type="button" class="close-button" aria-label="Remove"></button>
</span> Disabled chips
Make chips appear inactive by adding the disabled attribute to <button> elements or the .disabled class to other elements. Disabled chips have pointer-events: none applied, preventing hover and active states from triggering.
<span class="chip default disabled">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Medium
<button type="button" class="close-button" aria-label="Remove"></button>
</span>
<span class="chip large default disabled">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Large
<button type="button" class="close-button" aria-label="Remove"></button>
</span>
<span class="chip small default disabled">
<span class="avatar">
<span class="avatar-image"><img src="https://i.pravatar.cc/256" alt="Profile picture" /></span>
</span>
Small
<button type="button" class="close-button" aria-label="Remove"></button>
</span> Toggle functionality
Chips support toggle functionality similar to buttons, enabling them to function as selection controls. Add the data-cx-toggle="chip" attribute to enable automatic state management. For pre-toggled chips, include both the .active class and aria-pressed="true" attribute to ensure proper visual styling and accessibility states.
<!-- Buttons -->
<p class="d-inline-flex gap-xsmall">
<button type="button" class="chip default" data-cx-toggle="chip" aria-pressed="false">Toggle button</button>
<button type="button" class="chip default active" data-cx-toggle="chip" aria-pressed="true">Active toggle</button>
<button type="button" class="chip default" disabled data-cx-toggle="chip" aria-pressed="false">Disabled toggle</button>
<button type="button" class="chip default active" disabled data-cx-toggle="chip" aria-pressed="true">Disabled active</button>
</p>
<!-- Links -->
<p class="d-inline-flex gap-xsmall">
<a href="#" class="chip primary" role="button" data-cx-toggle="chip" aria-pressed="false">Toggle link</a>
<a href="#" class="chip primary active" role="button" data-cx-toggle="chip" aria-pressed="true">Active toggle</a>
<a href="#" class="chip primary disabled" aria-disabled="true" role="button" data-cx-toggle="chip" aria-pressed="false">Disabled toggle</a>
<a href="#" class="chip primary active disabled" aria-disabled="true" role="button" data-cx-toggle="chip" aria-pressed="true">Disabled active</a>
</p> CSS
This component can be customized using CSS variables, allowing for styles to be modified dynamically on the page. These CSS variables are part of Chassis CSS's design token system, giving design teams control over component appearance. See the design tokens page for more details.
Custom properties
These CSS variables control the component's appearance and can be modified dynamically on the page. Components use cascading variables, allowing seamless variations in size, color, and style without redundant style declarations through component inheritance and the context class system.
--#{$prefix}border-width: var(--#{$prefix}chip-border-width, #{$chip-border-width});
--#{$prefix}box-shadow: var(--#{$prefix}chip-box-shadow, #{$button-box-shadow});
--#{$prefix}focus-box-shadow: var(--#{$prefix}chip-focus-box-shadow, #{$button-focus-box-shadow});
// Sizing
--#{$prefix}min-size: var(--#{$prefix}chip-min-size, #{$chip-medium-min-size});
--#{$prefix}padding-y: var(--#{$prefix}chip-padding-y, #{$chip-medium-padding-y});
--#{$prefix}padding-x: var(--#{$prefix}chip-padding-x, #{$chip-medium-padding-x + $chip-medium-gap});
--#{$prefix}gap: var(--#{$prefix}chip-gap, #{$chip-medium-gap});
--#{$prefix}nudge: var(--#{$prefix}chip-nudge, #{$chip-medium-nudge});
--#{$prefix}border-radius: var(--#{$prefix}chip-border-radius, #{$chip-medium-border-radius});
--#{$prefix}close-button-icon: var(--#{$prefix}chip-remove-icon, #{$chip-remove-icon});
--#{$prefix}close-button-fg-color: var(--#{$prefix}chip-remove-color, var(--#{$prefix}fg-color));
--#{$prefix}close-button-fg-hover: var(--#{$prefix}chip-remove-hover, var(--#{$prefix}fg-color));
--#{$prefix}close-button-idle-opacity: var(--#{$prefix}chip-remove-idle-opacity, 1);
--#{$prefix}close-button-hover-opacity: var(--#{$prefix}chip-remove-hover-opacity, 1);
--#{$prefix}icon-size: var(--#{$prefix}chip-icons-size, #{$chip-medium-icon-size});
--#{$prefix}avatar-size: var(--#{$prefix}chip-avatar-size, #{$chip-medium-avatar-size});
--#{$prefix}close-button-size: var(--#{$prefix}icon-size);
@include map-font($chip-medium-font, button);
Chip variants leverage the same mixins and color map system as buttons. See buttons documentation for the underlying mixins and maps.
Design tokens
These design tokens with $cx prefixes are managed by design teams in Figma using the Tokens
Studio plugin. See the design tokens page for more details.
$chip-medium-font: $cx-font-chip-medium;
$chip-large-font: $cx-font-chip-large;
$chip-small-font: $cx-font-chip-small;
$chip-medium-min-size: $cx-size-chip-medium-main;
$chip-medium-padding-y: $cx-space-chip-medium-padding-y;
$chip-medium-padding-x: $cx-space-chip-medium-padding-x;
$chip-medium-gap: $cx-space-chip-medium-gap;
$chip-medium-nudge: $cx-space-chip-medium-nudge;
$chip-large-min-size: $cx-size-chip-large-main;
$chip-large-padding-y: $cx-space-chip-large-padding-y;
$chip-large-padding-x: $cx-space-chip-large-padding-x;
$chip-large-gap: $cx-space-chip-large-gap;
$chip-large-nudge: $cx-space-chip-large-nudge;
$chip-small-min-size: $cx-size-chip-small-main;
$chip-small-padding-y: $cx-space-chip-small-padding-y;
$chip-small-padding-x: $cx-space-chip-small-padding-x;
$chip-small-gap: $cx-space-chip-small-gap;
$chip-small-nudge: $cx-space-chip-small-nudge;
$chip-medium-icon-size: $cx-size-chip-medium-icon;
$chip-large-icon-size: $cx-size-chip-large-icon;
$chip-small-icon-size: $cx-size-chip-small-icon;
$chip-medium-avatar-size: $cx-size-chip-medium-avatar;
$chip-large-avatar-size: $cx-size-chip-large-avatar;
$chip-small-avatar-size: $cx-size-chip-small-avatar;
$chip-border-width: $cx-border-width-chip-main;
$chip-medium-border-radius: $cx-border-radius-chip-medium;
$chip-large-border-radius: $cx-border-radius-chip-medium;
$chip-small-border-radius: $cx-border-radius-chip-small;
$chip-remove-icon: svg-icon($cx-icon-chip-remove);
JavaScript API
Chips have toggling and dismissal features, providing functionality for both selection and removal. The chip component's JavaScript API offers programmatic control over these behaviors.
Initialization
Initialize elements as chips:
const chipList = document.querySelectorAll('.chip')
const chips = [...chipList].map(element => new chassis.Chip(element))
For basic toggle or dismissal functionality, explicit initialization is not required when using data attributes. The plugin will automatically initialize when using data-cx-toggle="chip" or when a child element has data-cx-dismiss="chip".
Toggle functionality
Toggle behavior is automatically enabled on chips with the data-cx-toggle="chip" attribute:
// Example of programmatically toggling a chip
const chip = chassis.Chip.getOrCreateInstance('#myToggleChip')
chip.toggle()
Dismissal triggers
Enable dismissal with the data-cx-dismiss attribute on a button within the chip:
<button type="button" class="close-button" data-cx-dismiss="chip" aria-label="Dismiss"></button>
Or on a button outside the chip using the additional data-cx-target attribute:
<button type="button" class="close-button" data-cx-dismiss="chip" data-cx-target="#my-chip" aria-label="Dismiss chip"></button> closed.cx.chip event to set focus to an appropriate
element.
Methods
The chip plugin provides methods for both toggle and dismissal functionality:
| Method | Description |
|---|---|
toggle | Toggles the chip's active state (for selectable chips) |
close | Removes the chip from the DOM (for dismissible chips) |
dispose | Destroys a chip instance and removes associated DOM data |
getInstance | Static method that retrieves the chip instance associated with a DOM element: chassis.Chip.getInstance(element) |
getOrCreateInstance | Static method that returns an existing chip instance or creates one if none exists: chassis.Chip.getOrCreateInstance(element) |
Example of batch operations on chips:
// Toggle all selected chips in a group
document.querySelectorAll('.chip.selected').forEach(chipElement => {
const chip = chassis.Chip.getOrCreateInstance(chipElement)
chip.toggle()
})
// Remove all chips with a specific tag
document.querySelectorAll('.chip[data-tag="outdated"]').forEach(chipElement => {
const chip = chassis.Chip.getOrCreateInstance(chipElement)
chip.close()
})
Events
The chip plugin exposes events for both toggle and dismissal states:
| Event | Description |
|---|---|
toggle.cx.chip | Fires when the chip's toggle state changes |
close.cx.chip | Fires immediately when the close instance method is called |
closed.cx.chip | Fired when the chip has been removed and CSS transitions have completed |
const myChip = document.getElementById('myChip')
// Handle toggle events
myChip.addEventListener('toggle.cx.chip', event => {
const isActive = event.target.classList.contains('active')
console.log(`Chip toggled to ${isActive ? 'active' : 'inactive'} state`)
})
// Handle dismissal events
myChip.addEventListener('closed.cx.chip', event => {
// Focus an appropriate element after chip is removed
document.getElementById('chipContainer').focus()
})