# Chip

A small selectable token — a filter, a choice, a person — that can carry an avatar and be removed.

Block: `smbk-chip`. Status: candidate. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|
| `tone` | `default`, `brand`, `outline`, `inverse` | `brand` | Which action family the chip draws from; default is a see-through gray that shows on every surface. |
| `size` | `md`, `sm` | `md` | The pill scale shared with the badge and the tag: 32 and 24 tall. |
| `selected` | on / off | off | The chip is currently chosen: pressed in, with a tick before its label. Given as true or false, the chip is a toggle and announces pressed or not pressed; left out, it is a plain button. |

Parts: `smbk-chip__tick`, `smbk-chip__avatar`, `smbk-chip__label`, `smbk-chip__remove`

## Markup

```html
<span class="smbk-chip smbk-chip--tone-brand smbk-chip--size-md">
  <span class="smbk-avatar smbk-avatar--size-xs smbk-avatar--tone-inverse smbk-avatar--type-initials smbk-chip__avatar">
    <span class="smbk-avatar__initials" aria-hidden="true">AO</span>
  </span>
  <span class="smbk-chip__label">Ada Okafor</span>
  <button type="button" class="smbk-chip__remove" aria-label="Remove Ada Okafor">
    <i class="ph ph-x-circle smbk-icon smbk-icon--size-md" aria-hidden="true"></i>
  </button>
</span>
```

## React

```tsx
import { Chip } from './design-system/components/chip/chip.js';

<Chip tone="brand" size="md" avatar={{ initials: "AO" }} onRemove={() => {}} removeLabel="Remove Ada Okafor">Ada Okafor</Chip>
```

## Stylesheet

```css
/* smbk-chip — Chip. Figma "Chip" 4253:1311.
 * A capsule with an optional avatar or tick, a label and an optional remove control, a gap between them.
 * The label's own frame carries a further inset on both sides, as Figma's label frame does. Figma draws
 * the edge inside the chip, so the padding gives the edge's width back; the default tone has no edge of
 * its own, and draws a clear one so it keeps the same size.
 * On is the toggle chip's aria-pressed, as the toggle button's is, so the look and what a screen reader hears
 * agree; the selected class draws the same, for markup that sets it. */

.smbk-chip {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: var(--smbk-space-inline-sm);
  height: var(--smbk-size-32);
  padding: 0 calc(var(--smbk-space-inset-xs) - var(--smbk-border-width-hairline));
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-action-brand-border);
  border-radius: var(--smbk-radius-full);
  background: var(--smbk-color-action-brand-background);
  color: var(--smbk-color-action-brand-foreground);
  font-family: var(--smbk-typography-label-md-font-family);
  font-size: var(--smbk-typography-label-md-font-size);
  font-weight: var(--smbk-typography-label-md-font-weight);
  line-height: var(--smbk-typography-label-md-line-height);
  letter-spacing: var(--smbk-typography-label-md-letter-spacing);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.smbk-chip:focus-visible {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
}

.smbk-chip:disabled,
.smbk-chip[aria-disabled="true"] {
  cursor: not-allowed;
  pointer-events: none;
}

.smbk-chip__label {
  display: block;
  padding: 0 var(--smbk-space-inset-sm);
}

.smbk-chip__avatar {
  flex-shrink: 0;
}

.smbk-chip:disabled .smbk-chip__avatar,
.smbk-chip[aria-disabled="true"] .smbk-chip__avatar {
  opacity: var(--smbk-opacity-disabled);
}

/* A selected chip shows a tick where the avatar would be, so the choice shows by more than its fill, and
   a little more room before it. */
.smbk-chip__tick {
  font-size: var(--smbk-size-icon-sm);
}

/* A toggle carries its tick off as well as on, so a page's script that sets aria-pressed shows it; it shows only while
   the chip is on (aria-pressed, or the selected class), and then hides the avatar. */
.smbk-chip:not([aria-pressed="true"], .smbk-chip--selected) > .smbk-chip__tick,
.smbk-chip:is([aria-pressed="true"], .smbk-chip--selected) > .smbk-chip__tick ~ .smbk-chip__avatar {
  display: none;
}

.smbk-chip:is([aria-pressed="true"], .smbk-chip--selected):has(> .smbk-chip__tick) {
  padding-inline-start: calc(var(--smbk-space-inset-md) - var(--smbk-border-width-hairline));
}

/* The cross is the chip's icon size, inside a 24 px box, the least a press needs; the box reaches past the
   cross into the gap and the padding, so the cross sits where Figma draws it. The focus ring is drawn on
   the cross's own edge. */
.smbk-chip__remove {
  box-sizing: border-box;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: var(--smbk-size-target-min);
  height: var(--smbk-size-target-min);
  margin: calc((var(--smbk-size-icon-sm) - var(--smbk-size-target-min)) / 2);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.smbk-chip__remove > .smbk-icon {
  font-size: var(--smbk-size-icon-sm);
  border-radius: var(--smbk-radius-full);
}

.smbk-chip__remove:focus-visible {
  outline: none;
}

.smbk-chip__remove:focus-visible > .smbk-icon {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: 0;
}

/* On the brand and inverse fills the focus color would not show, so the ring takes the chip's own text color. */
.smbk-chip--tone-brand .smbk-chip__remove:focus-visible > .smbk-icon,
.smbk-chip--tone-inverse .smbk-chip__remove:focus-visible > .smbk-icon {
  outline-color: currentColor;
}

/* ---- size sm ---- */

.smbk-chip--size-sm {
  height: var(--smbk-size-24);
  font-family: var(--smbk-typography-label-sm-font-family);
  font-size: var(--smbk-typography-label-sm-font-size);
  font-weight: var(--smbk-typography-label-sm-font-weight);
  line-height: var(--smbk-typography-label-sm-line-height);
  letter-spacing: var(--smbk-typography-label-sm-letter-spacing);
}

.smbk-chip--size-sm .smbk-chip__label {
  padding: 0 var(--smbk-space-inset-xs);
}

.smbk-chip--size-sm .smbk-chip__tick,
.smbk-chip--size-sm .smbk-chip__remove > .smbk-icon {
  font-size: var(--smbk-size-icon-xs);
}

.smbk-chip--size-sm:is([aria-pressed="true"], .smbk-chip--selected):has(> .smbk-chip__tick) {
  padding-inline-start: calc(var(--smbk-space-inset-sm) - var(--smbk-border-width-hairline));
}

.smbk-chip--size-sm .smbk-chip__remove {
  margin: calc((var(--smbk-size-icon-xs) - var(--smbk-size-target-min)) / 2);
}

/* ---- tone: brand (default) ---- */

@media (hover: hover) {
  .smbk-chip--tone-brand:hover {
    background: var(--smbk-color-action-brand-background-hover);
    border-color: var(--smbk-color-action-brand-border-hover);
    box-shadow: var(--smbk-elevation-raised);
  }
}

.smbk-chip--tone-brand:active,
.smbk-chip--tone-brand[aria-pressed="true"],
.smbk-chip--tone-brand.smbk-chip--selected {
  background: var(--smbk-color-action-brand-background-pressed);
  border-color: var(--smbk-color-action-brand-border-hover);
  box-shadow: var(--smbk-elevation-inset-strong);
}

.smbk-chip--tone-brand:disabled,
.smbk-chip--tone-brand[aria-disabled="true"] {
  background: var(--smbk-color-action-brand-background-disabled);
  border-color: var(--smbk-color-action-brand-border-disabled);
  color: var(--smbk-color-action-brand-foreground-disabled);
  box-shadow: none;
}

/* ---- tone: default, the see-through gray with no edge ---- */

.smbk-chip--tone-default {
  background: var(--smbk-color-surface-neutral-subtle);
  border-color: transparent;
  color: var(--smbk-color-action-default-foreground);
}

@media (hover: hover) {
  .smbk-chip--tone-default:hover {
    background: var(--smbk-color-surface-hover);
  }
}

.smbk-chip--tone-default:active,
.smbk-chip--tone-default[aria-pressed="true"],
.smbk-chip--tone-default.smbk-chip--selected {
  background: var(--smbk-color-action-default-background-pressed);
  box-shadow: var(--smbk-elevation-inset-strong);
}

.smbk-chip--tone-default:disabled,
.smbk-chip--tone-default[aria-disabled="true"] {
  background: var(--smbk-color-action-disabled-background);
  color: var(--smbk-color-action-disabled-foreground);
  box-shadow: none;
}

/* ---- tone: outline ---- */

.smbk-chip--tone-outline {
  background: transparent;
  border-color: var(--smbk-color-action-outline-border);
  color: var(--smbk-color-action-outline-foreground);
}

@media (hover: hover) {
  .smbk-chip--tone-outline:hover {
    background: var(--smbk-color-action-outline-background-hover);
    border-color: var(--smbk-color-action-outline-border-hover);
  }
}

.smbk-chip--tone-outline:active,
.smbk-chip--tone-outline[aria-pressed="true"],
.smbk-chip--tone-outline.smbk-chip--selected {
  background: var(--smbk-color-action-outline-background-pressed);
  border-color: var(--smbk-color-action-outline-border-hover);
  box-shadow: var(--smbk-elevation-inset-strong);
}

.smbk-chip--tone-outline:disabled,
.smbk-chip--tone-outline[aria-disabled="true"] {
  background: transparent;
  border-color: var(--smbk-color-action-disabled-border);
  color: var(--smbk-color-action-outline-foreground-disabled);
  box-shadow: none;
}

/* ---- tone: inverse ---- */

.smbk-chip--tone-inverse {
  background: var(--smbk-color-action-inverse-background);
  border-color: var(--smbk-color-action-inverse-border);
  color: var(--smbk-color-action-inverse-foreground);
}

@media (hover: hover) {
  .smbk-chip--tone-inverse:hover {
    background: var(--smbk-color-action-inverse-background-hover);
    border-color: var(--smbk-color-action-inverse-border-hover);
    box-shadow: var(--smbk-elevation-raised);
  }
}

.smbk-chip--tone-inverse:active,
.smbk-chip--tone-inverse[aria-pressed="true"],
.smbk-chip--tone-inverse.smbk-chip--selected {
  background: var(--smbk-color-action-inverse-background-pressed);
  border-color: var(--smbk-color-action-inverse-border-hover);
  box-shadow: var(--smbk-elevation-inset);
}

.smbk-chip--tone-inverse:disabled,
.smbk-chip--tone-inverse[aria-disabled="true"] {
  background: var(--smbk-color-action-disabled-background);
  border-color: var(--smbk-color-action-disabled-border);
  color: var(--smbk-color-action-disabled-foreground);
  box-shadow: none;
}

/* ---- touch: a chip and its remove cross take invisible press areas ----
   On a touch screen an invisible area, centred on a chip that is pressed and on a remove cross, takes the press out to
   the comfortable target in each direction it falls short of it; a chip that only carries a remove cross takes the
   press on the cross alone. The chip, its focus ring and its place stay as drawn. A component that sets chips closer
   together stops their areas halfway to the next one. */

@media (pointer: coarse) {
  :where(button, a[href]).smbk-chip {
    position: relative;
  }

  :where(button, a[href]).smbk-chip::after {
    content: '';
    position: absolute;
    inset: min(0%, (100% - var(--smbk-size-target-comfortable)) / 2);
  }

  .smbk-chip__remove {
    position: relative;
  }

  .smbk-chip__remove::after {
    content: '';
    position: absolute;
    inset: min(0%, (100% - var(--smbk-size-target-comfortable)) / 2);
  }
}

/* ---- high contrast (forced colors) ---- */
/* In Windows high-contrast mode the browser drops fills and shadows; this puts the meaning back with the
   user's own colors. Nothing here applies outside that mode. */

@media (forced-colors: active) {
  /* A toggle chip that is on (aria-pressed, or the selected class) is filled with Highlight. */
  .smbk-chip[aria-pressed="true"],
  .smbk-chip.smbk-chip--selected {
    forced-color-adjust: none;
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
    box-shadow: none;
  }

  .smbk-chip[aria-pressed="true"]:focus-visible,
  .smbk-chip.smbk-chip--selected:focus-visible {
    outline-color: CanvasText;
  }
}
```

## Tokens it reads

```json
{
  "space": {
    "inline": {
      "sm": {
        "$type": "dimension",
        "$value": "{{space.6}}",
        "$description": "Gap between things side by side, small."
      }
    },
    "inset": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Padding inside a component, extra small."
      },
      "sm": {
        "$type": "dimension",
        "$value": "{{space.6}}",
        "$description": "Padding inside a component, small."
      },
      "md": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Padding inside a component, medium."
      }
    }
  },
  "size": {
    "24": {
      "$type": "dimension",
      "$value": "24px",
      "$description": "Raw size step, 24 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here."
    },
    "32": {
      "$type": "dimension",
      "$value": "32px",
      "$description": "Raw size step, 32 px. Only for fixed sizes inside a component; semantic sizes (size/control, icon, mark) point here."
    },
    "icon": {
      "sm": {
        "$type": "dimension",
        "$value": "{{size.16}}",
        "$description": "Icon box, small."
      },
      "xs": {
        "$type": "dimension",
        "$value": "{{size.12}}",
        "$description": "Icon box, extra small."
      }
    },
    "target": {
      "min": {
        "$type": "dimension",
        "$value": "{{size.24}}",
        "$description": "Smallest tap area allowed (24, WCAG 2.2)."
      },
      "comfortable": {
        "$type": "dimension",
        "$value": "{{size.44}}",
        "$description": "Comfortable touch target (44)."
      }
    }
  },
  "border-width": {
    "hairline": {
      "$type": "dimension",
      "$value": "{{border-width.1}}",
      "$description": "Thin lines: dividers and almost every edge."
    }
  },
  "color": {
    "action": {
      "brand": {
        "border": {
          "$type": "color",
          "$value": "{{color.alpha.white.10}}",
          "$description": "Brand button and chip: edge at rest."
        },
        "background": {
          "$type": "color",
          "$value": "{{color.red.600}}",
          "$description": "Brand button and chip: fill at rest."
        },
        "foreground": {
          "$type": "color",
          "$value": "{{color.grey.50}}",
          "$description": "Brand button and chip: label and icon at rest."
        },
        "background-hover": {
          "$type": "color",
          "$value": "{{color.red.700}}",
          "$description": "Brand button and chip: fill on hover."
        },
        "border-hover": {
          "$type": "color",
          "$value": "{{color.alpha.black.5}}",
          "$description": "Brand button and chip: edge on hover."
        },
        "background-pressed": {
          "$type": "color",
          "$value": "{{color.red.800}}",
          "$description": "Brand button and chip: fill while pressed, one step past hover."
        },
        "background-disabled": {
          "$type": "color",
          "$value": "{{color.alpha.red.40}}",
          "$description": "Brand button and chip: fill when disabled."
        },
        "border-disabled": {
          "$type": "color",
          "$value": "{{color.alpha.black.5}}",
          "$description": "Brand button and chip: edge when disabled."
        },
        "foreground-disabled": {
          "$type": "color",
          "$value": "{{color.alpha.white.30}}",
          "$description": "Brand button and chip: label and icon when disabled."
        }
      },
      "default": {
        "foreground": {
          "$type": "color",
          "$value": "{{color.grey.850}}",
          "$description": "Neutral chip: label and icon at rest."
        },
        "background-pressed": {
          "$type": "color",
          "$value": "{{color.grey.300}}",
          "$description": "Neutral chip: fill while pressed or selected, one step past hover."
        }
      },
      "disabled": {
        "background": {
          "$type": "color",
          "$value": "{{color.alpha.grey-800.8}}",
          "$description": "Background of a disabled button, in every tone: a faint see-through grey, always fainter than an enabled button. Not for tracks: a disabled switch or slider part uses color/surface/track-subtle."
        },
        "foreground": {
          "$type": "color",
          "$value": "{{color.grey.500}}",
          "$description": "The label and icon of every disabled action, shared by every kind of button."
        },
        "border": {
          "$type": "color",
          "$value": "{{color.grey.300}}",
          "$description": "The edge of every disabled action, shared by every kind of button."
        }
      },
      "outline": {
        "border": {
          "$type": "color",
          "$value": "{{color.grey.300}}",
          "$description": "Outline button: edge at rest."
        },
        "foreground": {
          "$type": "color",
          "$value": "{{color.grey.850}}",
          "$description": "Outline button: label and icon at rest."
        },
        "background-hover": {
          "$type": "color",
          "$value": "{{color.alpha.grey-800.10}}",
          "$description": "Outline button: fill on hover."
        },
        "border-hover": {
          "$type": "color",
          "$value": "{{color.grey.400}}",
          "$description": "Outline button: edge on hover."
        },
        "background-pressed": {
          "$type": "color",
          "$value": "{{color.grey.300}}",
          "$description": "Outline button: fill while pressed, one step past hover."
        },
        "foreground-disabled": {
          "$type": "color",
          "$value": "{{color.grey.400}}",
          "$description": "Outline button: label and icon when disabled."
        }
      },
      "inverse": {
        "background": {
          "$type": "color",
          "$value": "{{color.grey.850}}",
          "$description": "Dark chip and radio: fill at rest."
        },
        "border": {
          "$type": "color",
          "$value": "{{color.grey.800}}",
          "$description": "Dark chip and radio: edge at rest."
        },
        "foreground": {
          "$type": "color",
          "$value": "{{color.grey.50}}",
          "$description": "Dark chip and radio: label and icon at rest."
        },
        "background-hover": {
          "$type": "color",
          "$value": "{{color.grey.900}}",
          "$description": "Dark chip and radio: fill on hover."
        },
        "border-hover": {
          "$type": "color",
          "$value": "{{color.grey.850}}",
          "$description": "Dark chip and radio: edge on hover."
        },
        "background-pressed": {
          "$type": "color",
          "$value": "{{color.grey.925}}",
          "$description": "Dark chip and radio: fill while pressed, one step past hover."
        }
      }
    },
    "border": {
      "focus": {
        "$type": "color",
        "$value": "{{color.red.600}}",
        "$description": "Keyboard focus ring on controls."
      }
    },
    "surface": {
      "neutral-subtle": {
        "$type": "color",
        "$value": "{{color.alpha.grey-800.10}}",
        "$description": "A quiet neutral fill for small marks and their resting state (default badge, tag, chip): translucent, so it shows by the same step on the default, raised and sunken surfaces. Hover steps up to color/surface/hover."
      },
      "hover": {
        "$type": "color",
        "$value": "{{color.alpha.grey-800.15}}",
        "$description": "A row or option under the pointer or the keyboard highlight: menu options, table rows. Translucent, so it works on any surface."
      }
    }
  },
  "radius": {
    "full": {
      "$type": "dimension",
      "$value": "{{radius.9999}}",
      "$description": "Capsule: pills, chips, switches."
    }
  },
  "typography": {
    "label-md": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "14px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label MD: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "label-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label SM: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    }
  },
  "focus": {
    "ring": {
      "width": {
        "$type": "dimension",
        "$value": "{{border-width.2}}",
        "$description": "Thickness of the focus ring."
      },
      "offset": {
        "$type": "dimension",
        "$value": "{{space.2}}",
        "$description": "Gap between a control and its focus ring."
      }
    }
  },
  "opacity": {
    "disabled": {
      "$type": "number",
      "$value": 0.5,
      "$description": "Fade for disabled pictures and media (50%)."
    }
  },
  "elevation": {
    "raised": {
      "$type": "shadow",
      "$value": {
        "light": "0px 2px 8px 1px #373d431a, 0px 1px 2px 0px #373d431a",
        "dark": "0px 2px 8px 1px #00000026, 0px 1px 2px 0px #00000026"
      }
    },
    "inset-strong": {
      "$type": "shadow",
      "$value": {
        "light": "inset -1px 2px 2px 0px #373d4333",
        "dark": "inset -1px 2px 2px 0px #0000004d"
      }
    },
    "inset": {
      "$type": "shadow",
      "$value": {
        "light": "inset 0px 0px 1px 0px #373d434d",
        "dark": "inset 0px 0px 1px 0px #00000066"
      }
    }
  }
}
```

## Purpose

A small capsule that stands for one choice in a set — a filter, a category, a person — and can be pressed to select it or removed from the set. It is interactive, which is what separates it from a badge, and it is one of many, which is what separates it from a button.

## Anatomy

- The block, a capsule of fixed height by size, on the same scale as the badge and the tag. The default tone is a see-through gray with no edge, so it shows on any surface; the others draw a hairline edge.
- The tick part, a check mark before the label of a selected toggle chip, in the avatar's place.
- The avatar part, an optional small avatar before the label, dimmed when the chip is disabled.
- The label part, the text, carrying its own horizontal inset.
- The remove part, an optional small control with a circled cross that removes the chip, inside a box large enough to press.

A toggle chip that is on is drawn from its pressed attribute, as the toggle button is; the selected modifier draws the same, for markup that sets it.

## When to use

- Filters a person switches on and off.
- People or items chosen into a field, each removable.
- A row of categories where one or several may be selected.

- A short row of related places, such as a site's services, drawn as chips: each chip is then a link.

## When not to use

- For a single action. Use a [button](button.md).
- For an inert status word. Use a [badge](badge.md) or a [tag](tag.md).

## Behavior

A selectable chip toggles between unselected and selected when pressed. Hovered, the brand and inverse tones lift with the first elevation level and the default tone darkens; pressed and selected, every tone sinks in and the selected chip shows a tick before its label, so the choice shows by more than color. A removable chip does not toggle; its remove control calls back and the page takes it out of the set.

A chip given an address is a link: pressing it goes there. It is never selected and never removable.

Whether a chip is a toggle is decided by the `selected` prop being given at all. A filter or choice chip is always given it, true when chosen and false when not. A chip that only acts, such as a suggestion, leaves it out.

A toggle chip carries its tick whether it is on or off, and shows it while it is pressed, so a page built ahead of time can press a chip with a script of its own, setting `aria-pressed` alone, and get the same tick as when React turns it on.

In markup, a link chip is an `a` element carrying the same classes, so it looks the same and has the same hover and focus. The React wrapper's types refuse `selected` and `onRemove` on a chip given an address.

On a touch screen a chip that is pressed, and a remove cross, keep their size and take an invisible press area round them, out to the comfortable touch target; a removable chip takes the press on its cross alone. Where chips stand closer, as in a filter bar or a combobox, each area stops halfway to the next.

## Accessibility

### What it does for you

- A selectable chip is a real button with a pressed state exposed to assistive technology. Given `selected` as true or false, the wrapper marks it pressed or not pressed, so a screen reader says it is a toggle and whether it is on even while it is off.
- The wrapper derives the pressed state from `selected`; a page rendered by React does not set it itself. A page's own script that presses a chip sets `aria-pressed`, and the tick follows it.
- A removable chip is plain text plus a real remove button, which the wrapper requires an accessible name for. The button is at least 24 by 24 pixels, the least a press needs, however small its cross.
- A chip given an address is a real link and is announced as one.
- The focus ring is the system rule on the chip. On the remove control it is drawn round the cross itself; on a brand or inverse chip it takes the chip's own text color, so it shows on the fill.

### What you must do

- Leave `selected` out for a chip that only acts: it then says neither pressed nor not pressed. Give it for a filter, which must say whether it is on.
- Give a removable chip's remove button an accessible name that says what is removed.
- Never make a chip both toggle and remove: that would need a button inside a button.
- Put a row of chips that are links in a navigation landmark or a named group, so the row says what its places are.

### How to test

- Tab to a chip: the focus ring shows in both themes and in a forced-color mode, round the cross on a remove button. Press Enter, then Space: each toggles or acts once.
- With a screen reader, a selectable chip is read as a toggle button, on or off, a link chip as a link, and a remove button by what it removes.
- On a touch screen, the remove cross is easy to hit.
- With text at 200% and the page 320 pixels wide, the label stays whole.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves focus to the chip, then to its remove button when it has one. |
| Enter | Presses the chip or its remove button, or follows the chip when it is a link. |
| Space | Presses the chip or its remove button. A chip that is a link is not followed by Space. |

## Usage rules

### Do

- Keep labels short; a chip that wraps is a card.
- Use the small size only where the row is dense and the chips are many.
- Give every chip in a filter row its selected state, on or off, so each one says it is a toggle.

### Don't

- Color chips by category with the tones. Tones are emphasis, not meaning.
- Put an icon-only chip on a page. A chip is text.
