On this page
Represent a selected or applied value that can be removed.
- Overview
- Rules and guidance
- Properties
- Styles
- Accessibility
When to use
- To display a selected value from a multi-select input, such as a chosen filter or a tag applied by the user, alongside a way to remove it
- To show applied filters in a filter row where each item can be dismissed individually
When not to use
- For read-only labels or status tags - use Badge instead. Chip always includes a remove button; if the value cannot be removed, it is not a Chip.
- For selectable options in a form - use Checkbox for multi-select or Radio for single-select. Chip is for representing values that have already been chosen, not for making the choice.
- For primary actions or navigation - use CTA Button or Text Link instead.
Anatomy

- Label
- Remove button
- Tooltip (appears automatically when the label is truncated, or when a custom tooltip is provided)
Basic usage
Edit live code
<Chip>Removable chip</Chip>
Variants and features
Removable
Every Chip includes a remove button. The onRemove callback fires when the button is clicked or when the user presses Enter or Space on it.
Edit live code
() => { // ignore - for live code example only. const Example = () => { const [filters, setFilters] = useState(['Electricity', 'Gas', 'EV owner']); return ( <Cluster spaceBetween={2}> {filters.map(filter => ( <ClusterItem key={filter}> <Chip onRemove={() => setFilters(filters.filter(f => f !== filter))}> {filter} </Chip> </ClusterItem> ))} </Cluster> ); } return <Example />; }
Truncation and tooltip
Chip has a maximum width of 20rem. Labels that exceed this width are truncated with an ellipsis. When truncation occurs, hovering or focusing the remove button shows the full label text in a tooltip automatically. No additional configuration is needed.
Edit live code
<Chip>This chip has a very long label so it will be truncated</Chip>
If you want to show custom tooltip content regardless of truncation, use the tooltip prop. This is useful when the label is an acronym or abbreviated form.
Edit live code
<Chip tooltip='Meter Serial Number'>MSN</Chip>
Content
Keep chip labels short, ideally one to three words. Write them in sentence case. If using an acronym, provide the expanded form in the tooltip prop so screen reader users and users unfamiliar with the acronym can understand the full meaning.
usage
- Chip must only be used when the represented value can be removed by the userChip always renders a remove button. If the value is read-only and cannot be removed, the button is a misleading affordance. Use Badge for non-removable labels.Copy rule ID for chip.removable-only
- Chip must not be used to trigger primary page actions or navigate between pagesChip's visual design and accessible role communicate "this is a removable value", not "this is a primary action". Using it for actions creates a mismatch between appearance and behaviour.Copy rule ID for chip.not-for-actions
content
- If the label is an acronym or abbreviationChip tooltip must contain the full expanded form of the acronym when the label is an acronym or abbreviationScreen reader users hear the remove button's accessible name, which defaults to the label text. An unexpanded acronym is meaningless as a standalone accessible name. The tooltip content becomes part of the screen reader announcement.Copy rule ID for chip.acronym-tooltip
- Chip label should be written in sentence caseCopy rule ID for chip.label-sentence-case
- Chip label should be one to three wordsChips are compact by design. Long labels cause truncation, which hides information and relies on the tooltip to convey meaning. If the value requires more than three words to be understood, consider displaying it differently.Copy rule ID for chip.label-concise
interaction
- Chip will show a tooltip with the full label text when the label is truncated due to the 20rem max-width constraintThe component detects truncation via scrollWidth comparison and shows a tooltip automatically. No consumer implementation is needed.Copy rule ID for chip.will-truncation-tooltip
- Chip should have an onRemove callback that removes or deselects the value it representsThe remove button is always rendered. Without an onRemove handler, clicking it does nothing, which is a broken affordance. The only valid case for omitting onRemove is when the Chip is temporarily non-interactive and this state is communicated visually.Copy rule ID for chip.onremove-wired
composition
- Chip ref must be used with the understanding that the forwarded ref points to the remove button element, not the outer chip spanChip forwards its ref to the StyledButton (the remove button). Code that relies on the ref to access the outer chip container will get the wrong element.Copy rule ID for chip.ref-targets-button
Chip
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
children | ReactNode | — | Yes | Label shown inside the chip. Truncated with an ellipsis beyond 20rem, in which case it is shown in a tooltip on hover or focus. |
tooltip | ReactNode | — | No | Content for a tooltip shown when the chip is hovered or its remove button is focused. Replaces the automatic tooltip for truncated labels, and is read out as the remove button's label. |
onRemove | () => void | — | No | Called when the remove button is clicked or activated by keyboard. |
onKeyDown | (e: KeyboardEvent<HTMLButtonElement>) => void | — | No | Called on key presses while the remove button has focus, for example to implement arrow key navigation between chips. |
tabIndex | number | — | No | Tab index of the remove button, which is the chip's only focusable element. Use `-1` to manage focus yourself, for example in a roving tabindex group. |
Styles
span
display: inline-flex;
align-items: center;
height: ${space[6]};
line-height: 1.9rem;
max-width: 20rem;
overflow: hidden;
border-radius: ${radii.standard};
border: ${borderWidths.standard} solid ${grey[400]};
background: ${grey[200]};
padding-top: ${space[1]};
padding-bottom: ${space[1]};
padding-left: ${space[2]};
gap: ${space[1]};
color: ${colors.body};
&:has(button:focus-visible) {
${focusRing}
}
text
font-family: ${fonts.body};
font-weight: ${fontWeights.medium};
font-size: ${responsiveFontSizes.body[1]};
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
button
border: none;
display: flex;
justify-content: center;
align-items: center;
border-radius: 0 ${radii.standard} ${radii.standard} 0;
width: ${space[6]};
height: ${space[6]};
background: ${grey[200]};
&:hover {
background: ${grey[300]};
cursor: pointer;
}
&:focus-visible {
background: ${grey[300]};
outline: none;
}
& > svg {
color: ${colors.body};
flex-shrink: 0;
width: ${space[4]};
height: ${space[4]};
}
In brief
Chip is a text label with a native remove button. A screen reader reads the label as text, then a button named with the label and "press to remove".
What Nebula provides
- The remove button is a native button and the chip's only tab stop. The cross icon is hidden from screen readers.
- The button is named with the label, or the tooltip when one is set, followed by the hidden text "press to remove".
- A focus ring around the whole chip when the remove button has keyboard focus.
- A tooltip shows the tooltip text, or the full label if it is cut off, while the remove button has focus or the chip is hovered.
Keyboard behaviour
The chip is reached through its remove button with Tab, and removed with Enter or Space.
Interactions
- Tab - Moves focus to the remove button
- Enter or Space - Calls onRemove
Accessible design
If you set a tooltip, write it so it makes sense without the label
The tooltip text replaces the label in the remove button's name, so a screen reader user hears only the tooltip when they reach the button. "Meter Serial Number" works for a chip labelled "MSN"; "Billing" does not for a chip labelled "General enquiry".
WCAG: 2.4.6 Headings and Labels
Accessible development
After a chip is removed, move focus somewhere sensible
The remove button leaves the page with its chip, so focus is lost. Move it to the next chip, or to the control that added the chips when none are left. The chip's ref is its remove button.
WCAG: 2.4.3 Focus Order
Put what a user needs in the label, not only in the tooltip
A tooltip only appears on hover or on keyboard focus of the remove button, so a user on a touch screen is unlikely to see it.
WCAG: 1.4.13 Content on Hover or Focus
Accessibility testing status
Reviewed on 9 October 2026 against v17.0.1.
| Test | Status | Tested with |
|---|---|---|
| Default state | Tested | axe-core via the Storybook test runner (CI) |
| Advanced states | Partially tested | axe-core via the Storybook test runner (CI) |
| Keyboard navigation | Partially tested | keyboard (reported by the owner) |
| Screen reader | Partially tested | VoiceOver with Chrome (reported by the owner) |
What these tests and statuses mean
The table records which checks were run on this component on its own. It is not a statement of WCAG conformance, and it does not cover how the component is used.
The tests
- Default state: The component as it first appears, before anything is clicked or changed.
- Advanced states: Every other state and variant: error, open, selected, each size and style, and hovering.
- Keyboard navigation: Whether every function can be reached and used with the keyboard alone, with a visible focus ring.
- Screen reader: Whether a screen reader announces what is on screen correctly: the name, the role and any state.
The statuses
- Tested: Every check in this row passed in an automated run that repeats on every pull request.
- Manually tested: Every check in this row was run once, by a person or with a tool they started, and all of them passed. It is not re-run on every change.
- Partially tested: Some checks in this row were run once and passed; the rest are still to do.
- Issue found: A check in this row failed. The ticket is shown beside the status.
- Not tested: No check in this row has been run yet.
- Not applicable: This row does not apply to the component, for the reason given beside it.