Skip to content

Tag

A tag labels content: topics on an article, chosen filters above a list. If the tag says what state something is in, such as “Approved” or “Overdue”, Badge is the right choice instead.

data-variantUsed for
(omitted)Outline. The default.
filledMuted surface, when the tags sit on a light surface

Three filters above a list of cases. “Approved” is selected, the other two are not, and aria-pressed says which is which:

<div role="group"> with a label is what ties the three together. Without it they are three loose buttons, and someone listening to the page does not know they belong to the same question.

data-selectable gives hover and a focus indicator. The element has to be a <button>, and you set aria-pressed yourself:

<script type="module">
for (const tag of document.querySelectorAll(".lt-tag[data-selectable]")) {
tag.addEventListener("click", () => {
const selected = tag.getAttribute("aria-pressed") === "true"
tag.setAttribute("aria-pressed", String(!selected))
})
}
</script>

aria-pressed is what makes the screen reader say “pressed” or “not pressed”. Colour alone says nothing.

ClassWhat it is
.lt-tagThe tag. The variant comes from data-variant.
VariableDefault
--lt-tag-paddingvar(--lt-spacing-0-5) var(--lt-spacing-2)
--lt-tag-radiusvar(--lt-spacing-1)

See Customising for how the variables and the layer work.

  • A tag that cannot be pressed should not look as if it can. Use data-selectable only on real buttons.
  • If you have many filters, put them in a list with a heading that says what they filter.
  • If the tag should be removable, make a separate button inside it with text that says what is removed: “Remove the Approved filter”, not just a cross.