Skip to main content

Tag

A compact label representing a metadata value, category, or filter applied to content. Use to display user-applied or system-assigned classifications that can be removed. Don't use for read-only status values — use Badge or Pill instead.

OverviewStyleAccessibility

Description

Anatomy

PartRequired?Notes
Container Required Rounded pill or chip shape housing all tag content. Uses --op-radius-pill or --op-radius-md depending on variant.
Label text Required Short plain-language string identifying the classification. Truncates with ellipsis at a max-width; full value shown on hover via tooltip.
Remove button Optional An icon button (close icon) that dismisses the tag. Required when tags are user-removable. Must be keyboard-accessible and have a visually hidden descriptive label.
Leading icon Optional A small decorative or semantic icon preceding the label text. Use only when it adds meaningful context (e.g. a category icon).

Variants

States

State Behaviour
Default Tag is visible and static. Remove button (if present) is visible but not active.
Hover Remove button background transitions to --op-color-interactive-hover. Cursor changes to pointer over the remove button.
Focus Focus ring (3px solid --op-color-interactive-focus) appears on the remove button. Focus is not placed on the tag container itself unless the tag is also clickable.
Disabled Tag and remove button are non-interactive. Opacity reduced to 40%. Remove button is not focusable. Use sparingly — prefer hiding tags that cannot be acted on.
Loading/pending removal After remove button is activated, tag can briefly show a spinner in place of the close icon to indicate async removal before disappearing.

Usage guidelines

Do / Don't

Do

Keep tag labels short (1–3 words). Use sentence case.

Don't

Don't use full sentences or punctuation inside a tag label.

Do

Provide a descriptive accessible label on the remove button, e.g. 'Remove Transport tag'.

Don't

Don't use a bare times character as the only accessible label for the remove action.

Do

Group related tags in a horizontal wrapping row with consistent spacing (--op-space-8 gap).

Don't

Don't mix Tag and Badge in the same row to represent the same type of information — pick one.

Do

Announce tag removal to screen readers using an ARIA live region.

Don't

Don't silently remove a tag without any feedback to assistive technology users.

Layout & Spacing

Tag container: padding --op-space-4 (4px) vertical, --op-space-8 (8px) horizontal. Gap between label and remove button: --op-space-4 (4px). Gap between tags in a tag group: --op-space-8 (8px). Minimum height: 28px (desktop); 44px touch targets apply to the remove button, not the container. Max-width: 200px with text-overflow: ellipsis.

Tokens

PartTokenValue
Container background (default) --op-color-bg-subtle Light neutral fill; adapts to light/dark themes.
Container background (outlined) transparent Border only; no fill.
Container border --op-color-border-default 1px solid border on outlined variant; none on default.
Label text --op-color-text-primary High-contrast label text; --op-text-sm size.
Label font size --op-text-sm Approximately 14px.
Remove button icon --op-color-text-secondary Slightly muted to avoid competing with label text.
Remove button hover background --op-color-interactive-hover Applied to the button element, not the tag container.
Focus ring --op-color-interactive-focus 3px solid outline on remove button focus.
Disabled opacity 0.4 Applied to the entire tag container when disabled.
Border radius --op-radius-pill Use --op-radius-md for a more rectangular chip style if required by product.

Engineering notes

  • Use the `wa-tag` Web Awesome component where available. Set `removable` attribute to render the remove button.
  • The remove button must fire a custom event (e.g. `wa-remove`) that the parent component listens to. Never remove the tag from the DOM directly inside the component.
  • Wrap a set of tags in a `<div role='list'>` with each tag as `<div role='listitem'>` to provide list semantics for screen readers.
  • Maintain an ARIA live region (`aria-live='polite'`) adjacent to the tag group. When a tag is removed, announce e.g. 'Transport tag removed. 3 tags remaining.'
  • When tags represent active filters, the tag group should be labelled with `aria-label='Active filters'` or associated with a visible heading via `aria-labelledby`.
  • For async removal (e.g. API call on remove), replace the close icon with `wa-spinner` and set `aria-busy='true'` on the tag until the operation resolves.
  • Avoid hardcoded max-widths in component styles; let consuming layouts constrain width via a wrapping container.

Keyboard interaction

KeyAction
Tab Moves focus to the remove button within a tag (the tag container itself is not focusable unless also used as a button).
Enter Activates the focused remove button, triggering tag removal.
Space Activates the focused remove button (same as Enter for button elements).
Shift+Tab Moves focus to the previous interactive element (prior tag's remove button or the element before the tag group).

Why it matters

Government platforms serve users who rely on keyboard navigation and screen readers, including users with motor impairments and visual impairments. Tags used as active filters directly affect what data a user sees — inaccessible removal controls can prevent users from modifying their own search or filter state, which is a significant barrier in administrative tools.

Focus

Focus is placed on the remove button element within each tag, not on the tag container. Focus ring: 3px solid --op-color-interactive-focus, with a 2px offset to prevent clipping by the container border. When a tag is removed via keyboard, focus should move to the next tag's remove button, or to the preceding tag if the removed tag was last, or to the filter input if no tags remain. prefers-reduced-motion: transition animations on removal should be suppressed.

ARIA

Role or attributeWhen to useExample
role='list' / role='listitem' Applied to the tag group container and each tag respectively, to communicate group semantics. <div role="list" aria-label="Active filters"><div role="listitem">...</div></div>
aria-label on remove button Provides a descriptive label that includes the tag value, since the visible icon alone is insufficient. <button aria-label="Remove Transport tag"><wa-icon name="xmark"></wa-icon></button>
aria-live Announces tag removal to screen readers without moving focus unexpectedly. <div aria-live="polite" aria-atomic="true" class="sr-only"></div>
aria-disabled Used on the tag container when the tag is in a disabled state. Do not use the HTML disabled attribute on non-form elements. <div role="listitem" aria-disabled="true">...</div>
aria-busy Set on the tag during async removal to indicate a pending operation. <div role="listitem" aria-busy="true">...</div>

Contrast

Label text (--op-color-text-primary) on tag background (--op-color-bg-subtle): must meet 4.5:1 for --op-text-sm. Remove icon (--op-color-text-secondary) on tag background: must meet 3:1 as a UI component (WCAG 1.4.11). Outlined variant: border (--op-color-border-default) against surrounding background must meet 3:1. Focus ring (--op-color-interactive-focus) against adjacent background: must meet 3:1. Disabled state at 40% opacity will fail contrast — this is an accepted pattern for disabled controls, but avoid disabling tags unless strictly necessary.

Touch targets

The tag container does not require a 44x44px touch target. The remove button does. Ensure the remove button has a minimum tap target of 44x44px using padding or a transparent hit-area pseudoelement, even if the visual icon is smaller (e.g. 16x16px).

Things to avoid

  • Do not rely on colour alone to distinguish tag types or states — always pair with a text label or icon.
  • Do not place focus on the tag container if it is not interactive; only the remove button should receive focus.
  • Do not suppress focus styles for any interactive element within the tag, including the remove button.
  • Do not remove a tag from the DOM without announcing the change via an ARIA live region.
  • Do not use title attributes as a substitute for aria-label on the remove button.

Was this page helpful?

Updated 5 October 2026