Skip to main content

Tag Group

A container for displaying and managing multiple tags together. Use when content can carry multiple simultaneous tag values. Don't use when only one tag value is possible.

OverviewStyleAccessibility

Description

Anatomy

PartRequired?Notes
Group container Required A wrapping flex container that holds all tag items. Controls gap, wrap behaviour, and provides the ARIA group role with an accessible label.
Tag item Required Individual wa-tag elements inside the group. Each carries a visible label and an optional icon or avatar prefix.
Remove button (per tag) Optional A dismiss icon inside each tag. Present when the group is editable and the user can remove individual values. Must have its own accessible label.
Overflow indicator Optional A +N badge or truncated count shown when the full set of tags exceeds the available horizontal space. Expands the group on activation.
Add trigger Optional An inline button or combobox at the end of the group for adding new tag values. Used in editable contexts such as tagging a stakeholder record.

Variants

States

State Behaviour
Default Tags render at rest with their configured colour and label. Group container has no visible border.
Tag hovered The individual tag under the pointer receives a subtle background shift using --op-color-interactive-hover. Cursor changes to pointer for interactive variants.
Tag focused 3px focus ring in --op-color-interactive-focus appears on the focused tag item or its remove button. No other visual change. Focus is managed sequentially through items using Tab.
Tag removed (transition) On remove button activation the tag collapses with a short fade-out (150ms). If prefers-reduced-motion is set, the tag disappears instantly. Group reflows remaining tags.
Overflow (collapsed) When the group is constrained in width and tags exceed available space, tags beyond the fold are hidden and an overflow indicator (+N) is shown.
Overflow (expanded) User activates the overflow indicator; all tags are revealed in a wrapped layout. The indicator changes to a 'Show less' control.
Empty When all tags have been removed, the group container either disappears or shows a placeholder message depending on the implementation context.
Disabled All interactive controls (remove buttons, add trigger) are non-interactive and visually muted at reduced opacity. Read-only tags remain visible.

Usage guidelines

Do / Don't

Do

Give the group container an accessible label that describes what the tags represent (e.g. aria-label='Engagement topics').

Don't

Rely on surrounding visual layout to imply what the tags mean — screen readers need an explicit label.

Do

Keep individual tag labels short (1–3 words). Truncate with a tooltip if the source value is longer.

Don't

Wrap long sentences inside a tag; this breaks visual scanning and overflows layouts on small screens.

Do

Use the removable variant only when the action has a clear save path — either auto-save or a visible Save button nearby.

Don't

Show remove buttons on tags in a read-only summary view where the user cannot actually change the data.

Do

When a tag group is empty after all items are removed, provide a visible empty state or hide the group gracefully.

Don't

Leave an invisible group container in the DOM — it confuses screen reader users who tab into empty space.

Do

Ensure colour is not the sole differentiator between tag variants. Combine colour with a shape or prefix icon where semantics differ.

Don't

Use raw hex colours or non-token values for tag backgrounds; always pull from --op-color-* tokens.

Layout & Spacing

Group container: display flex; flex-wrap wrap; gap --op-space-8 (8px). Between the group and adjacent content (e.g. a heading above): margin-top --op-space-12 (12px). When an add trigger follows the last tag: gap --op-space-8 between the last tag and the trigger. Overflow indicator: margin-left --op-space-4 (4px) from the last visible tag. Minimum group height: 28px (inherits from Tag height).

Tokens

PartTokenValue
Tag background (default) --op-color-bg-subtle Neutral light background for read-only informational tags.
Tag text --op-color-text-primary High-contrast label text on neutral tag background.
Tag border --op-color-border-default 1px solid border giving the tag shape on light backgrounds.
Tag background (selected) --op-color-interactive-default Active/selected state for selectable tag variant (green-400).
Tag text (selected) --op-color-text-on-interactive White or near-white text on the interactive green background.
Remove button icon --op-color-text-secondary Subdued icon colour; shifts to --op-color-text-primary on hover.
Focus ring --op-color-interactive-focus 3px outline on focused tag or remove button.
Overflow indicator background --op-color-bg-muted Slightly more prominent than --op-color-bg-subtle to distinguish from regular tags.
Disabled opacity opacity: 0.4 Applied to interactive controls in the disabled state; no separate token.

Engineering notes

  • Wrap the set of wa-tag elements in a <div role='group' aria-label='[descriptive label]'> element. Do not use role='list' unless the tags are purely presentational list items with no interactivity.
  • For removable tags, attach a click handler to each remove button that updates the data model and re-renders the group. Do not mutate the DOM directly.
  • For selectable tags, manage selected state in your component state layer and pass a selected attribute/class to each wa-tag. Use aria-pressed='true/false' on the tag button.
  • The overflow indicator should be a <button> element (not a div) so it is keyboard reachable. Toggle an expanded state class on the group container.
  • Respect prefers-reduced-motion: wrap the collapse animation in a media query check and skip the transition when the user preference is set.
  • When tags are linked (variant: linked), render each wa-tag as or wrapping an <a> element. Ensure the href is descriptive — avoid generic 'click here' labels.
  • For the add trigger pattern, use a wa-combobox or wa-select restricted to the valid taxonomy values. This prevents free-text entry of invalid categories.

Keyboard interaction

KeyAction
Tab Moves focus sequentially to each interactive tag (or its remove button) in source order. Read-only tags are not in the tab sequence unless they are linked.
Enter On a linked tag: navigates to the href. On a selectable tag: toggles selected state. On a remove button: removes the tag.
Space Same as Enter for selectable tags and remove buttons.
Escape If an add trigger combobox is open, closes it and returns focus to the trigger button.

Why it matters

Government platforms are used by stakeholders and community members with a wide range of abilities, including motor and visual impairments. Tag groups appear on high-frequency screens such as stakeholder profiles and consultation listings. Missing keyboard access or ambiguous labels can prevent users from understanding or editing the classification of critical records, affecting both the quality of engagement data and compliance with government accessibility mandates.

Focus

Focus enters the group from a preceding focusable element via Tab. Each interactive tag (remove button, selectable tag, or linked tag) is a discrete stop in the tab order. Remove buttons are nested within their tag and receive focus after the tag label if both are focusable. When a tag is removed, focus moves to the next tag in the group, or to the add trigger if it was the last tag, or to the preceding interactive element if the group is now empty.

ARIA

Role or attributeWhen to useExample
role="group" Applied to the group container div to semantically associate the tags. <div role="group" aria-label="Engagement topics">
aria-label (group) Provides a human-readable name for the group so screen readers announce context before reading each tag. aria-label="Consultation themes"
aria-pressed Applied to selectable tag buttons to communicate toggle state. <button aria-pressed="true">Environment</button>
aria-label (remove button) Makes the remove button purpose unambiguous; must include the tag value in the label. <button aria-label="Remove Environment tag">
aria-hidden Applied to decorative prefix icons inside tags so they are not announced separately. <wa-icon name="tag" aria-hidden="true"></wa-icon>
aria-live="polite" Applied to a visually hidden status region that announces tag additions and removals to screen reader users. <span aria-live="polite" class="sr-only">Environment tag removed. 3 tags remaining.</span>

Contrast

Default tag: --op-color-text-primary on --op-color-bg-subtle must meet 4.5:1 for normal text. Selected tag: --op-color-text-on-interactive on --op-color-interactive-default (green-400) — verify this pairing in the token audit; if contrast is below 4.5:1, use a darker text token. Remove button icon: --op-color-text-secondary on --op-color-bg-subtle must meet 3:1 (UI component threshold). Overflow indicator: --op-color-text-primary on --op-color-bg-muted must meet 4.5:1.

Touch targets

Each interactive tag (selectable or linked) and each remove button must meet the 44x44px minimum touch target. If the visual tag height is less than 44px, use padding or an invisible tap area extension (e.g. ::after pseudo-element) to expand the target without affecting layout.

Things to avoid

  • Do not rely on colour alone to communicate tag semantics — always pair colour with a text label or icon.
  • Do not place non-interactive tags in the tab order unless they are linked; this creates unnecessary tab stops for keyboard users.
  • Do not use title attributes as the primary accessible label for remove buttons — they are not reliably exposed by all screen readers and are not available on touch devices.
  • Do not animate tag removal without checking prefers-reduced-motion — vestibular-sensitive users can be affected by unexpected motion.

Was this page helpful?

Updated 2 October 2026