Skip to content

Chips

components specs/components/chips.kmd

Compact element representing an entity, attribute, or action — smaller than a button and used in groups. Material parity (`/components/chips`). Covers four canonical variants (assist, filter, input, suggestion) and their behaviors.

When this spec applies

Primary triggers

All triggers

Specification body

Spec — Chips

Facet Visual of Koder Design. Material parity: https://m3.material.io/components/chips.

4 variants

VariantPurposeSelectableRemovable
AssistTrigger contextual action tied to a noun ("Add to calendar")NoNo
FilterToggle inclusion in a filtered setYes (multi-select)No
InputRepresent user-entered value (email tag, applied filter)NoYes (× button)
SuggestionPredefined response or query optionOne-shot tapNo

Pick variant by question: "Does this represent a thing I typed?" → input. "Does this filter a list?" → filter. "Does this give me a shortcut to type something?" → suggestion. "Does this trigger an action attached to nearby content?" → assist.

Anatomy

   ┌──────────────────┐       ┌──────────────────┐
   │  ⚙   Settings    │       │   ●  Important × │
   └──────────────────┘       └──────────────────┘
       ↑     ↑                    ↑      ↑      ↑
     icon  label              leading  label  remove
                              (optional)     (input only)
  • Height: 32 px (default)
  • Padding: 12 px horizontal (label only) / 8 px (with icon)
  • Corner radius: 8 px (Material 3 default, see preset variation)
  • Label: label-large (14/20, weight 500)
  • Leading icon: 18 px, optional
  • Trailing: × icon (input variant) or check (selected filter)
  • Hit target: minimum 48 × 48 px (extends invisibly around chip)
  • Container bg: variant-specific (see R2)

R1 — Group layout

Chips appear in groups. Layout rules:

LayoutWhen
Horizontal scrollMobile / narrow surface, many chips
WrapDefault — chips wrap to next line when overflow
Single rowFew chips (≤ 5) that always fit

Spacing between chips: 8 px horizontal, 8 px vertical.

R2 — Visual by variant + state

VariantRest bgRest borderSelected bgSelected border
Assisttransparent1 px outlinen/an/a
Filter (unselected)transparent1 px outlinesecondary-containernone
Filter (selected)secondary-containernone(same)none
Inputsurface-container-low1 px outline-variantn/an/a
Suggestiontransparent1 px outline(one-shot tap, no selected state)n/a

Elevation: 0 dp at rest; rises to 2 dp on hover (Material 3 "elevated" chip is an opt-in variant — document explicitly if used).

R3 — Filter chip selection

ActionResult
Tap unselectedBecomes selected (add filter)
Tap selectedBecomes unselected (remove filter)
Long-press (touch)Show tooltip with full label

Filter chips are multi-select by default — multiple can be selected simultaneously. If single-select needed (mutually exclusive), use radio buttons or segmented buttons instead.

Selection state shows:

  • Leading check icon (✓) replaces optional leading icon
  • Background fills with secondary-container
  • Border removed (filled state)

R4 — Input chip removal

× icon on right side, 18 px, accessible via:

  • Tap × → remove chip + announce "Removed: [label]" to screen reader
  • Backspace when chip has keyboard focus → remove
  • Backspace in adjacent text field → focus last chip
  • Keyboard delete on focused chip → remove + move focus to previous

Animation: chip fade-out (motion-fast) + adjacent chips slide to fill.

R5 — States (all variants)

StateVisual change
RestBase style
HoverState layer 8% over base
Focused2 px focus ring outside chip border
PressedState layer 12%
Disabled38% opacity, no interaction

R6 — With icon

Leading icon slot accepts:

  • 18 px icon (default — matches text height)
  • 24 px avatar (input chip representing a person)

When icon is present:

  • Padding-left reduces from 12 px → 8 px
  • Icon-to-label gap: 4 px

Selected filter chip ALWAYS shows check leading; replaces optional icon (don't try to show both — order is check OR icon).

R7 — Accessibility

  • Assist: role="button" + accessible name from label
  • Filter: role="checkbox" (multi) OR role="radio" (single, rare) with aria-checked state
  • Input: role="button" for chip + nested role="button" for × remove; remove button has aria-label="Remove [label]"
  • Suggestion: role="button"
  • Group container: role="group" + aria-label describing the collection
  • Keyboard:
    • Tab: enters first chip in group, then Tab moves OUT
    • Arrow Left/Right: moves between chips within group
    • Space / Enter: toggles (filter) or activates (assist / suggestion)
    • Backspace / Delete: removes (input)

R8 — Density

DensityHeightPaddingIcon size
Compact28 px10 px16 px
Default32 px12 px18 px
Comfortable40 px16 px20 px

Inherits from customization.kmd.

R9 — Per-preset variation

PresetCornersSelected style
material38 px radiusFilled tonal container
material216 px pillSaturated accent, white text
ios_cupertino16 px pillFilled accent
gnome6 px radiusSolid accent border, tonal bg
windows_114 px radiusAccent color filled, subtle outline
brutalist0 px (sharp)Inverted colors, 2 px border
terminal_classicBracketed text [Filter] / [X]Asterisk prefix *[Filter]

R10 — Forbidden patterns

  • ❌ Chips taller than 48 px (becomes a button; use button instead)
  • ❌ Chips with multi-line labels (truncate or use card / list)
  • ❌ Mixing variants in a single group (a row of filter chips with one input chip in the middle is confusing)
  • ❌ Filter chip groups acting as single-select (use radio / segmented buttons)
  • ❌ Chip without label (icon-only — use icon button)
  • ❌ Long-press as the only way to remove an input chip (no discoverability)
  • ❌ Animating bg color on selection without a state layer (jarring flash)
  • ❌ Hit target < 48 × 48 px
  • interaction/selection.kmd — multi-select pattern
  • interaction/states.kmd — hover / pressed / focused layers
  • themes/color-roles.kmdsecondary-container for selected filter
  • themes/typography.kmdlabel-large
  • components/buttons.kmd — single primary action sibling
  • components/text-fields.kmd — input chip parent context
  • foundations/elements.kmd — Control + Marker families

References