Home / Snippets / UI Components /
Chip/tag
Compact chip/tag component with optional close button. Ideal for filters, categories, and selected items.
Quick implementation
/* HTML:
<span class="chip">Label</span>
<span class="chip chip--accent">
Label
<button type="button" class="chip-close" aria-label="Remove Label">×</button>
</span>
*/
.chip {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.3rem 0.75rem;
border-radius: 999px;
font-size: 0.8rem;
font-weight: 600;
line-height: 1;
background: oklch(0.25 0.02 260);
color: oklch(0.93 0.01 260);
border: 1px solid oklch(0.35 0.02 260);
}
.chip--accent {
background: oklch(0.28 0.08 265);
color: oklch(0.85 0.12 265);
border-color: oklch(0.42 0.14 265);
}
.chip--success {
background: oklch(0.26 0.07 145);
color: oklch(0.82 0.12 145);
border-color: oklch(0.40 0.12 145);
}
.chip--warning {
background: oklch(0.27 0.07 75);
color: oklch(0.85 0.13 75);
border-color: oklch(0.42 0.13 75);
}
.chip-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
border-radius: 50%;
border: none;
background: oklch(1 0 0 / 0.12);
color: inherit;
cursor: pointer;
font-size: 0.7rem;
padding: 0;
transition: background 0.15s ease;
}
.chip-close:hover {
background: oklch(1 0 0 / 0.25);
}
.chip-close:focus-visible {
outline: 2px solid oklch(0.72 0.19 265);
outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
.chip, .chip-close { transition: none; }
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building accessible UI components.
Goal: A chip/tag component with color variants and an optional dismiss button — pure CSS, no JavaScript for styling.
Technical constraints:
- Use border-radius: 999px for the pill shape.
- Color variants (default, accent, success, warning) use oklch() with matching background, text, and border at appropriate lightness levels.
- The close button must be a real <button> element with aria-label describing what it removes.
- Close button uses a circular background (oklch alpha) that darkens on hover.
- All transition properties must be wrapped in @media (prefers-reduced-motion: reduce).
- Use inline-flex with gap for label + close button alignment — no absolute positioning.
Framework variant (pick one):
A) Vanilla HTML + CSS — static markup with BEM-style modifier classes.
B) React component — accept label, variant (default | accent | success | warning), onRemove callback, and className props.
Edge cases to handle:
- Long labels: chip must truncate with ellipsis at a max-width, not overflow the container.
- No close button: chip renders as a plain <span> with no interactive element.
- Disabled state: lower opacity and suppress pointer events on the close button.
- Dense layouts: chips must wrap cleanly in a flex container with consistent gap.
Return HTML + CSS.
Why this matters in 2026
Chips are among the most overused yet under-engineered UI patterns. Most implementations reach for a library when the entire component is fewer than 30 lines of CSS. The pill shape, tinted variants, and dismissible close button all express meaning — status, category membership, removability — without text labels. Getting this right in pure CSS means zero JavaScript overhead and full server-render compatibility.
The logic
border-radius: 999px creates the pill regardless of content width without needing to know the element's height. Each color variant uses three coordinated oklch() values — background at low lightness, border a step higher, and text at high lightness — all on the same hue angle. This keeps variants visually consistent even as the hue shifts across the spectrum. The close button is a true <button> rather than a styled <span>, which gives free keyboard accessibility and fires click events without JavaScript listeners needing to detect which element was tapped.
Accessibility & performance
Each close button carries an aria-label that identifies what will be removed (e.g. "Remove Warning") rather than just saying "close", which is meaningless out of context for screen reader users. The :focus-visible ring on the close button uses outline-offset so it clears the circular background. Transitions on background are the only animated properties, which avoids layout or paint costs. The prefers-reduced-motion guard disables them entirely for users who opt out of motion.