Eunomia v1.1.0
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Chip

Chip represents a small, removable piece of information, such as a selected filter, an invited guest, or an uploaded file. Its label can be paired with an optional leading visual, such as an icon, an avatar photo, an image thumbnail, or a colored initials badge. It's always about one discrete piece of data, which the user can be allowed to remove.

Dependencies

eun-icon · if using an icon, or removable eun-button · if removable
Overview API Examples Accessibility
Design Featured Alice Doe

When to use

Reach for a chip whenever the user is looking at a discrete, removable piece of data they added themselves, such as an applied filter, a recipient in a "to" field, or a file staged for upload. Each chip should read on its own, independent of the others around it. See Alternatives below if what you need instead is a static label with no removal behavior.

Install & usage

Pick a framework in the toolbar above and these snippets adapt.

npm install @eunomia/elements
import "@eunomia/elements/chip.js";
<eun-chip rounded removable avatar-initials="AD">Alice Doe</eun-chip>
document.querySelector("eun-chip").addEventListener("eunclose", (event) => {
  event.target.remove();
});

Importing the file registers <eun-chip> as a custom element, with no further setup needed. It works with any framework, or none, since it's a standard web component.

Alternatives

You want… Prefers
A static label with no removal behavior eun-tag

Guidance

  • Keep the label short and specific, such as a name, a filename, or a filter value, since it's the only reliably-perceived carrier of what the chip actually represents
  • Pick one leading visual per chip: avatarSrc for a real photo, avatarInitials for a person with no photo, icon for a category/type, or none at all for a plain label
  • Give removeLabel a translated verb ("Retirer", "Entfernen"...) rather than leaving the English default in a localized UI. See the Accessibility tab
  • Move focus somewhere deliberate after removing a chip in response to eunclose. See the Accessibility tab
  • Using eun-chip for a static status or count that's never removed. See Alternatives above
  • Setting both avatarSrc/avatarInitials and expecting icon to still show. Only one leading visual ever renders, see the API tab for the precedence order
  • Relying on a generic, un-translated "Remove" across a whole list of chips in a non-English UI. See the Accessibility tab
  • Overriding colors with inline styles instead of the --chip-* CSS variables

Live testing

Properties

Chip <eun-chip>

Attributes

NameTypeDefaultDescription
fixed-colorbooleanfalseKeeps a light or dark chip white or black in every theme. Without it, they follow the grey scale, which flips with the active theme. Has no effect on the other colors or on severity
hide-iconbooleanfalseWhether the leading icon is hidden from the chip, once resolved. The avatar and initials are unaffected
avatar-srcstring—The URL of a leading avatar or image. Takes priority over avatar initials and icon
avatar-altstring''The alt text for the avatar image. Left empty by default, since the slotted label already carries the identity. Set it only when the image conveys information the label doesn't
avatar-shape'circle' | 'square''circle'The shape of the leading avatar, initials, or image. Circle suits a person's photo, square a generic image thumbnail
avatar-initialsstring—One or two characters shown in a colored badge in place of an image. Ignored once an avatar image is set, and takes priority over icon
remove-labelstringRemoveA prefix combined with the chip's own slotted text to build the delete button's accessible name, such as "Remove Alice Doe", so multiple chips on the same page stay distinguishable to assistive technology. Defaults to the localized string for the current locale (English: "Remove")
color'primary' | 'secondary' | 'light' | 'medium' | 'dark''medium'The color to apply to the chip
severity'info' | 'success' | 'warning' | 'critical' | 'neutral'—The severity of the chip, matching the nature of the information conveyed. Takes priority over color when both are set
appearance'default' | 'fill' | 'outline' | 'flat''default'The surface style of the chip. Flat renders the same muted, low emphasis surface regardless of color or severity, except for the light and dark colors, which keep their own white or black
size's' | 'm' | 'l''m'The size of the chip
iconEunomiaIconName—The leading icon to display. Ignored once an avatar image or initials are set. When severity is set and icon isn't, the icon is set according to the chip's severity
roundedbooleanfalseWhether the chip is fully rounded, as a pill
removablebooleanfalseShows the delete button. Clicking it fires the close event without changing the chip's own rendering
disabledbooleanfalseDisables the delete button, preventing removal

Import the exact TypeScript type behind any property above, see Types.

Properties

JS-only — no matching HTML attribute, set these from a script or a template binding.

NameTypeDefaultDescription
localestring—The locale used to resolve the default accessible label of the delete button. Defaults to the runtime's own
resolvedLocale—This instance's own `locale` when set, the shared default locale otherwise. Used for `Intl` formatting, so dates and numbers follow the same locale as dictionary.
dictionary—This instance's locale-resolved string dictionary — see the class doc for the resolution order.

Slots

NameDescription
(default)The chip's label
iconReplaces the leading icon entirely with any content, not just an icon element. Falls back to the resolved icon or severity glyph when empty. Ignored once an avatar image or initials are set

Events

NameTypeDescription
euncloseCloseEventFired when the delete button is activated. The chip has no visibility state of its own, so removing or hiding it in response is the consumer's own responsibility

Every event above follows the same naming convention, covered in Events.

CSS custom properties

NameDescription
--chip-background-colorSets the background color of the chip, for every appearance, color and severity
--chip-border-colorSets the border color of the chip, for every appearance, color and severity
--chip-border-widthSets the border width of the chip, for every appearance. The border takes room out of the padding, so the chip keeps its size
--chip-box-shadowSets a box shadow on the chip, none by default
--chip-colorSets the text color of the chip, for every appearance, color and severity
--chip-icon-colorSets the color of the leading icon only, not the avatar, initials, or delete button icon. Defaults to matching the chip's own text color
--chip-border-radiusSets the corner radius of the chip, also over rounded
--chip-gapSets the gap between the chip's leading visual, label, and delete button
--chip-avatar-backgroundSets the background color of the initials badge
--chip-avatar-colorSets the text color of the initials badge
--chip-avatar-sizeSets the diameter of the leading avatar, initials, or image
--chip-delete-focus-outline-colorSets the focus outline color of the delete button

CSS shadow parts

NameDescription
chipThe outer box wrapping the leading visual, label, and delete button. Exposed for effects the chip's CSS custom properties don't cover, such as an accent

Content

Label only

The minimal chip has no leading visual, just a slotted label and the default delete button. With nothing to fill the leading edge, the chip widens its own start padding a little so the label doesn't read as cramped against it. See "Icon and label" below for the other case that gets the same treatment, and "Avatar and label" for why an avatar/initials badge doesn't.

Design
<eun-chip rounded removable>Design</eun-chip>

Icon and label

A plain icon gets the same wider start padding as a label-only chip, since it's small enough on its own that the default padding would otherwise look uneven next to the label.

Featured Project files
<eun-chip rounded removable icon="star">Featured</eun-chip>
<eun-chip rounded removable icon="folder" color="primary"
  >Project files</eun-chip
>

Need something other than a eun-icon, or a different icon library entirely? Slot your own content into icon instead. It replaces the prop-driven icon entirely (ignored, same as icon itself, once avatarSrc/avatarInitials is set).

Featured
<eun-chip rounded removable>
  <svg
    slot="icon"
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    stroke-width="2"
  >
    <path
      d="m12 2 2.9 6.9L22 10l-5.5 4.8L18 22l-6-3.7L6 22l1.5-7.2L2 10l7.1-1.1L12 2Z"
    ></path>
  </svg>
  Featured
</eun-chip>

Avatar and label

Set avatarSrc to a photo URL. It renders as a circle by default, inset with the same padding as the label and delete button on every side (unlike icon/label-only, an avatar already carries enough visual weight against the edge on its own), e.g. a form's list of invited guests.

Alice Doe Bob Smith
<eun-chip rounded removable avatar-src="https://example.com/alice.jpg"
  >Alice Doe</eun-chip
>
<eun-chip rounded removable avatar-src="https://example.com/bob.jpg"
  >Bob Smith</eun-chip
>

Image and label

Set avatarShape="square" alongside avatarSrc for a generic image thumbnail instead of a person's photo, such as a file preview or a small logo.

report.pdf
<eun-chip
  rounded
  removable
  avatar-src="https://example.com/thumb.png"
  avatar-shape="square"
  >report.pdf</eun-chip
>

Initials and label

Set avatarInitials for a person chip with no photo available: one or two characters in a colored badge, matching color.

Alice Doe Bob Smith
<eun-chip rounded removable avatar-initials="AD">Alice Doe</eun-chip>
<eun-chip rounded removable avatar-initials="BS" color="primary"
  >Bob Smith</eun-chip
>

Leading visual precedence

avatarSrc wins over avatarInitials, which wins over icon (itself resolved from the explicit prop or, failing that, severity's own default icon). Only one leading visual ever renders.

All three set
<eun-chip
  rounded
  removable
  avatar-src="https://example.com/alice.jpg"
  avatar-initials="AD"
  icon="star"
  >All three set</eun-chip
>

Hiding the icon

Set hideIcon to drop the leading icon entirely, whether it came from an explicit icon or a severity default. The avatar/initials leading visual is unaffected, since hideIcon only ever governs the icon.

Overdue
<eun-chip rounded removable severity="critical" hide-icon>Overdue</eun-chip>

Variants

Color

Primary Secondary Light Medium Dark
<eun-chip rounded removable color="primary">Primary</eun-chip>
<eun-chip rounded removable color="secondary">Secondary</eun-chip>
<eun-chip rounded removable color="light">Light</eun-chip>
<eun-chip rounded removable color="medium">Medium</eun-chip>
<eun-chip rounded removable color="dark">Dark</eun-chip>

light and dark are absolute colors: white and black, whatever the appearance. fill is solid white with black text (solid black with white text for dark), and outline is a white border with white text (black for dark). default is as solid as fill, since white and black have no pale wash, and flat is a faint wash of the color itself. Pick them for a background of the opposite tone.

Default Fill Outline Flat
Default Fill Outline Flat
<eun-chip rounded removable color="light" fixed-color appearance="outline"
  >Outline</eun-chip
>
<eun-chip rounded removable color="dark" fixed-color appearance="fill"
  >Fill</eun-chip
>

Keeping light and dark in every theme

By default, light and dark follow the grey scale, which flips with the active theme: a light chip is white in the light theme and dark in the dark theme. Set fixed-color to pin it to white (or black) in every theme, without overriding any CSS variable. Toggle the theme in the toolbar above to compare: the left column follows the theme, the right one does not. fixed-color has no effect on the other colors or variants.

Follows the theme Fill Outline
Fixed Fill Outline
<eun-chip rounded removable color="light" fixed-color>Light</eun-chip>
<eun-chip rounded removable color="dark" fixed-color appearance="outline"
  >Dark</eun-chip
>

Part of the shared vocabulary, alongside every other component that reuses it.

Severity

Set severity for a state that maps to a semantic meaning (info/success/warning/critical/neutral). Like eun-tag, it also picks a matching default icon automatically, and takes precedence over color when both are set.

Info Success Warning Critical Neutral
<eun-chip rounded removable severity="info">Info</eun-chip>
<eun-chip rounded removable severity="success">Success</eun-chip>
<eun-chip rounded removable severity="warning">Warning</eun-chip>
<eun-chip rounded removable severity="critical">Critical</eun-chip>
<eun-chip rounded removable severity="neutral">Neutral</eun-chip>

Unlike eun-tag, an explicit icon set alongside severity still wins over the severity's own default icon. severity only drives the color here, so a caller that needs its own icon per state (a status icon, for instance) keeps full control of it.

Pending Confirmed
<eun-chip rounded removable severity="warning" icon="hourglass_empty"
  >Pending</eun-chip
>
<eun-chip rounded removable severity="success" icon="check_circle"
  >Confirmed</eun-chip
>

Display appearance

Default Fill Outline Flat
<eun-chip rounded removable color="primary" appearance="default"
  >Default</eun-chip
>
<eun-chip rounded removable color="primary" appearance="fill">Fill</eun-chip>
<eun-chip rounded removable color="primary" appearance="outline"
  >Outline</eun-chip
>
<eun-chip rounded removable color="primary" appearance="flat">Flat</eun-chip>

flat always renders the same muted, low-emphasis surface regardless of color, matching eun-tag's own flat type.

Sizes

Small Medium Large
<eun-chip rounded removable avatar-initials="AD" size="s">Small</eun-chip>
<eun-chip rounded removable avatar-initials="AD">Medium</eun-chip>
<eun-chip rounded removable avatar-initials="AD" size="l">Large</eun-chip>

Rounded

Set rounded for a full pill instead of the small corner radius (matching eun-tag's own default shape).

Alice Doe Alice Doe
<eun-chip avatar-initials="AD">Alice Doe</eun-chip>
<eun-chip rounded avatar-initials="AD">Alice Doe</eun-chip>

Behavior

Removable

Set removable to add a delete button. Without it, the chip carries the same visual language but isn't meant to be dismissed.

Alice Doe Alice Doe
<eun-chip rounded avatar-initials="AD">Alice Doe</eun-chip>
<eun-chip rounded removable avatar-initials="AD">Alice Doe</eun-chip>

Removing a chip

eun-chip dispatches eunclose and stops there. It never removes or hides itself. The consumer decides what "removed" means, typically deleting the element (or the underlying data item, in a framework-rendered list).

Alice Doe Bob Smith Carla Jones
<div id="chip-list">
  <eun-chip rounded removable avatar-initials="AD">Alice Doe</eun-chip>
  <eun-chip rounded removable avatar-initials="BS">Bob Smith</eun-chip>
  <eun-chip rounded removable avatar-initials="CJ">Carla Jones</eun-chip>
</div>
<script>
  document.getElementById("chip-list").addEventListener("eunclose", (event) => {
    event.target.remove();
  });
</script>

Disabled

Disables the delete button, preventing removal, and mutes the chip slightly.

Alice Doe
<eun-chip rounded removable avatar-initials="AD" disabled>Alice Doe</eun-chip>

Server-side rendering

Before the chip upgrades, its label is plain inline text. Link chip-ssr.css in the page's <head> to draw the final chip from the first paint:

<link
  rel="stylesheet"
  href="node_modules/@eunomia/elements/dist/ssr/chip-ssr.css"
/>

A bundler that resolves package exports can reach it as @eunomia/elements/chip-ssr.css.

It covers every size, color, severity and appearance, fixed-color, disabled, the avatar initials and the --chip-* properties, draws the delete button's cross, and keeps room for the leading icon, which appears with the upgrade. It also follows rounded and removable.

Custom colors

Override the --chip-* CSS variables, listed in full in the API tab. They apply to every color, severity and appearance, and always win over them, so a custom value never depends on which combination the chip uses. Every appearance has the same border box, transparent unless drawn, taken out of the padding: setting a border color (or --chip-border-width: 0 to remove the outline's) never changes the size of the chip.

Custom Pending review
<eun-chip rounded removable class="custom-chip" avatar-initials="ZK"
  >Custom</eun-chip
>
<eun-chip
  rounded
  removable
  appearance="outline"
  icon="warning"
  class="custom-icon-chip"
  >Pending review</eun-chip
>
.custom-chip {
  --chip-background-color: #fdf2f8;
  --chip-color: #be185d;
  --chip-avatar-background: #be185d;
  --chip-border-width: 2px;
  --chip-border-color: #be185d;
  --chip-box-shadow: 0 2px 8px rgba(190, 24, 93, 0.25);
}

.custom-icon-chip {
  --chip-icon-color: #c85207;
}

The custom properties that change colors, borders, shadows and corners, at a glance. The API tab lists every property of the component.

Variable Sets
--chip-background-color Sets the background color of the chip, for every appearance, color and severity
--chip-border-color Sets the border color of the chip, for every appearance, color and severity
--chip-border-width Sets the border width of the chip, for every appearance. The border takes room out of the padding, so the chip keeps its size
--chip-box-shadow Sets a box shadow on the chip, none by default
--chip-color Sets the text color of the chip, for every appearance, color and severity
--chip-icon-color Sets the color of the leading icon only, not the avatar, initials, or delete button icon. Defaults to matching the chip's own text color
--chip-border-radius Sets the corner radius of the chip, also over rounded
--chip-avatar-background Sets the background color of the initials badge
--chip-avatar-color Sets the text color of the initials badge
--chip-delete-focus-outline-color Sets the focus outline color of the delete button

Keyboard and focus

Keyboard interactions

Key Action
Tab / Shift+Tab Moves focus to/from the delete button, when removable is set
Space / Enter Activates the focused delete button, native <button> behavior

eun-chip itself is never focusable and carries no tabindex. It isn't a single interactive control, it's a label with an interactive delete affordance inside it. When removable is unset there is nothing in it to reach with the keyboard at all. It reads exactly like a eun-tag would.

Focus management on removal is your responsibility

eun-chip dispatches eunclose and stops there. It never removes or hides itself (see "Removing a chip" in the Examples tab). If your eunclose handler removes the element from the DOM while focus was still on its delete button, the browser drops focus to <body>, and a keyboard user loses their place per WCAG 2.4.3 Focus Order. This is especially easy to hit with a list of chips, since removing one usually shifts every chip after it. Move focus somewhere deliberate right after removal: the next remaining chip's own delete button, the field that lets the user add a new one, or the nearest heading/landmark, rather than leaving it to land wherever the browser defaults to.

Semantics and screen readers

Delete button semantics

The delete button is a real eun-button (ghost rounded size="xs", an icon-only eun-icon child), so it inherits a native, fully accessible <button> under the hood with no extra work here. See eun-button's own Accessibility tab for the underlying details. Its accessible name is removeLabel (default "Remove") combined with the chip's own slotted text (e.g. "Remove Alice Doe"), computed automatically off the default slot's content. This matters more here than it does for eun-alert's single close button. A page can easily show a whole row of chips at once, and several identical unlabeled "Remove, button" announcements in a row give a screen reader user no way to tell which one they're about to activate. Set a translated removeLabel ("Retirer", "Entfernen"...) for a localized UI. Leaving the English default in place while the label text itself is localized produces a mixed-language accessible name.

Leading visual is decorative

The leading icon renders via eun-icon, which always sets aria-hidden="true" on itself (see its own Accessibility tab). The initials badge (avatarInitials) is likewise aria-hidden="true" on the chip's own markup. Neither is ever announced, and neither is a substitute for the label text. The identity or category they represent should already be spelled out in the slotted label itself (a chip reading "Alice Doe" next to her initials, not initials alone).

Avatar image alt text

The avatarSrc image defaults to alt="" (decorative) for the same reason: the slotted label already names who or what the avatar represents, so a redundant alt text would just have a screen reader announce the same name twice in a row. Set avatarAlt explicitly only when the image conveys something the label text genuinely doesn't, such as a photo used as the sole identifier with no accompanying name, per WCAG 1.1.1 Non-text Content.

Visual

Don't rely on color alone

color changes the chip's visual appearance only. WCAG 1.4.1 Use of Color requires that information conveyed by color also be available another way. Keep the slotted label descriptive on its own ("Design" or "Alice Doe", not just a colored dot) rather than relying on the reader inferring meaning from color alone.

Color contrast

The default and fill types are built from this design system's own color tokens, already chosen to meet contrast minimums against their paired background. A custom --chip-background-color/--chip-color combination (or a custom brand color) must still be checked against WCAG 1.4.3 Contrast (Minimum) (4.5:1 for this size of text). See Color for the tokens that already meet it. The initials badge defaults to white text over the chip's own solid --_backgroundFilled color specifically so it stays legible regardless of the active appearance. A custom --chip-avatar-background / --chip-avatar-color pair needs the same contrast check independently, since it's a separate foreground/background pair from the label text.

Reference links

WCAG 1.4.1: Use of Color
WCAG 1.1.1: Non-text Content
WCAG 1.4.3: Contrast (Minimum)
WCAG 2.4.3: Focus Order