Skip to content

Chip

Variants

The Chip has two variants: tonal (default) and outlined.

Tonal
Outlined
html
<div class="chip tonal">
  <span class="text">Tonal</span>
</div>

<div class="chip outlined">
  <span class="text">Outlined</span>
</div>

Icon

The icon can be placed before or after the text.
Make sure the text is wrapped in a .text wrapper.

Tonal
Outlined
html
<div class="chip">
  <svg></svg>
  <span class="text">Text</span>
</div>

<div class="chip">
  <span class="text">Text</span>
  <svg></svg>
</div>

Button

html
<button class="chip">
  <span class="text">Without icon</span>
</button>

<button class="chip">
  <svg></svg>
  <span class="text">With icon</span>
</button>
html
<a href="#" class="chip">
  <span class="text">Without icon</span>
</a href="#">

<a href="#" class="chip">
  <span class="text">With icon</span>
  <svg></svg>
</a href="#">

Disabled

Disabled class
Disabled attribute
html
<div class="chip disabled">
  <span class="text">Disabled class</span>
</div>

<div class="chip" disabled>
  <span class="text">Disabled attribute</span>
</div>

<button class="chip outlined" disabled>
  <svg></svg>
  <span class="text">Disabled w/ icon</span>
</button>

Sizes

Small
Default
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sodales.
html
<div class="chip small">
  <span class="text">Small</span>
</div>

<div class="chip">
  <span class="text">Default</span>
</div>

<div class="chip multiline">
  <span class="text"
    >Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
    sodales.</span
  >
</div>

INFO

.multiline simply sets block-size: auto on the Chip.

Anatomy

  1. Container: div, a or button
  2. Text
  3. Icon (optional): <svg> element
Chip example
html
<div class="chip">
  <svg></svg>
  <span class="text">Text</span>
</div>

API

TypeModifiersDefaultDescription
Containerdiv.chip, a.chip, button.chip-Container element type.
Children& > .text, & > svg-Optional child content.
Disabled.disabled,[disabled]-If applied, the chip is disabled .
Sizes.small, default, .multilinedefaultThe size to use.
Variants.tonal,.outlined.tonalThe variant to use.

Browser compatibility

Installation

css
:where(.chip) {
  --_bg-color: var(--surface-tonal);
  --_border-color: var(--border-color);
  --_color: var(--text-color-1);

  align-items: center;
  background: var(--_bg-color) var(--ripple, none);
  border: 1px solid var(--_border-color);
  border-radius: var(--radius-2, 0.5rem);
  color: var(--_color);
  display: inline-flex;
  font-size: var(--font-size-0, 0.75rem);
  gap: var(--size-1);
  block-size: var(--size-7, 2rem);
  padding-inline: var(--size-2);
  text-decoration: none;

  /* Variants */
  &.tonal {
    --_bg-color: var(--surface-tonal);
    --_color: var(--text-color-1);
  }

  &.outlined {
    --_bg-color: var(--surface-default);
    --_color: var(--text-color-1);
  }

  /* TODO: should this be out of the box? */
  /* Colors */
  /* &:hover {
    --_bg-color: var(--color-11);
    --_border-color: var(--color-11);
    --_color: var(--text-color-1);
  } */
  /* &.danger,
  &.info,
  &.success,
  &.warning,
  &.primary {
    --_bg-color: var(--color-5);
    --_border-color: var(--color-7);
    --_color: var(--text-color-1-contrast);

    &:hover {
      --_bg-color: var(--color-7);
      --_border-color: var(--color-7);
      --_color: var(--text-color-1-contrast);

      &:active {
        --_bg-color: var(--color-8);
        --_border-color: var(--color-8);
      }
    }

    &.outlined {
      --_bg-color: var(--surface-tonal);
      --_color: var(--text-color-1);
      --_border-color: var(--color-9);

      &:hover {
        --_bg-color: var(--color-9);
        --_border-color: var(--color-9);
        --_color: var(--text-color-1);

        &:active {
          --_bg-color: var(--color-11);
          --_border-color: var(--color-11);
        }
      }
    }
  } */

  &:where(button, a):where(:not(.disabled, [disabled])) {
    &:where(:not(:active)):hover {
      --_bg-color: light-dark(
        color-mix(in oklch, var(--surface-tonal) 98%, black),
        color-mix(in oklch, var(--surface-tonal) 90%, white)
      );
    }
  }

  /* Icon */
  &:has(svg:first-child) {
    padding-inline: var(--size-1) var(--size-2);
  }
  &:has(svg:last-child) {
    padding-inline: var(--size-2) var(--size-1);
  }

  &:has(svg) {
    svg {
      flex-shrink: 0;
      inline-size: var(--size-3);
    }
  }

  /* Sizes */
  &.small {
    block-size: var(--size-5);
  }
  &.multiline {
    block-size: auto;
  }

  /* Ripple effect */
  background-position: center;
  transition: background 0.8s;

  &:where(:not(.disabled, [disabled])) {
    &:where(:not(:active):hover) {
      --ripple: radial-gradient(circle, transparent 1%, var(--_bg-color) 1%)
        center/15000%;
    }

    &:where(:hover:active) {
      background-size: var(--button-ripple-size);
      transition: background 0s;
    }
  }

  /* Disabled */
  &:where(.disabled, [disabled]) {
    opacity: 0.64;
    --_text-color: color-mix(
      in oklch,
      var(--text-color-2) 50%,
      var(--surface-default)
    );
    cursor: not-allowed;
  }
}