Tag
Tag is a small inline label for a piece of metadata, such as a status, a category, or a count. Its content comes entirely from what's placed inside it, plus an optional leading icon set explicitly or derived from its severity. It's purely presentational, with no interactive behavior and no accessibility role of its own, reading to assistive technology as plain inline text (see the Accessibility tab).
Dependencies
When to use
Use tag for a short piece of metadata that should be readable on its own,
such as a status like "Active", a category, a plan tier, or a count in a
table cell. If what you're showing is more of a quick visual nudge next to
something else rather than text that needs to be read, such as an unread
count on an icon,
Install & usage
Pick a framework in the toolbar above and these snippets adapt.
npm install @eunomia/elements
import "@eunomia/elements/tag.js";
<eun-tag severity="success">Active</eun-tag>
Importing the file registers <eun-tag> as a custom element, with no
further setup needed. It works with any framework, or none, since it's a
standard web component.
npm install @eunomia/elements
<script type="module">
import "@eunomia/elements/tag.js";
</script>
<eun-tag severity="success">Active</eun-tag>
npm install @eunomia/elements
import "@eunomia/elements/tag.js";
function StatusTag() {
return <eun-tag severity="success">Active</eun-tag>;
}
npm install @eunomia/elements
"use client";
import "@eunomia/elements/tag.js";
export function StatusTag() {
return <eun-tag severity="success">Active</eun-tag>;
}
npm install @eunomia/elements
<script setup>
import "@eunomia/elements/tag.js";
</script>
<template>
<eun-tag severity="success">Active</eun-tag>
</template>
npm install @eunomia/elements
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import "@eunomia/elements/tag.js";
@Component({
selector: "app-status-tag",
template: `<eun-tag severity="success">Active</eun-tag>`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class StatusTagComponent {}
Alternatives
eun-badgeeun-chipGuidance
- Use
severityfor a state that maps to a semantic meaning (success/warning/critical/info/neutral), which also picks the matching icon automatically - Use
colorinstead for a purely brand/categorical label with no semantic state (a tag, a plan tier, ...) - Keep the label short: a tag is a fragment of a sentence or a table cell, not a paragraph
- Reserve
uppercasefor very short labels (one or two words), see the Accessibility tab
- Setting both
colorandseverity:severityalways wins, so acolorset alongside it is silently ignored - Relying on color alone to convey the status: keep the label text (and, when relevant, the severity icon) descriptive on its own
- Using
eun-tagfor a removable filter or chip: it has no click, focus, or removal behavior built in, see Alternatives above - Overriding colors with inline styles instead of the
--tag-*CSS variables
Live testing
Properties
Tag <eun-tag>
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
| hide-icon | boolean | false | Whether the icon is hidden from the tag. Takes priority over iconOnly |
| icon-only | boolean | false | Shows only the icon, visually hiding the slotted label while keeping it available to assistive technology as the tag's accessible name. Requires icon or severity to be set |
| color | 'primary' | 'secondary' | 'light' | 'medium' | 'dark' | "medium" | The color to apply to the tag |
| severity | 'info' | 'success' | 'warning' | 'critical' | 'neutral' | — | The severity of the tag, matching the nature of the information conveyed. Takes priority over color when both are set |
| appearance | 'default' | 'fill' | 'outline' | 'flat' | "default" | The surface style of the tag. Flat always renders the same muted, low emphasis surface regardless of color or severity |
| icon | EunomiaIconName | — | The name of the custom icon to display. By default, the icon is set according to the tag's severity |
| size | 's' | 'm' | 'l' | "m" | The size of the tag |
| rounded | boolean | false | Whether the tag has rounded corners |
| uppercase | boolean | false | Whether the tag label is uppercased with extra letter spacing |
Import the exact TypeScript type behind any property above, see
Slots
| Name | Description |
|---|---|
| (default) | The label of the tag. Still required when icon only is set, since it becomes the tag's accessible name, visually hidden but announced to assistive technology |
| icon | Replaces the icon entirely with any content, not just an icon element. Falls back to the resolved icon or severity glyph when empty |
CSS custom properties
| Name | Description |
|---|---|
| --tag-background-color | Sets the background color of the tag |
| --tag-border-color | Sets the border color of the tag, for the outline appearance |
| --tag-color | Sets the text color of the tag |
| --tag-border-radius | Sets the corner radius of the tag |
| --tag-gap | Sets the gap between the tag icon and the label |
Basic
<eun-tag>Default</eun-tag>
Severity
Sets both the color scheme and, unless hide-icon is set, the matching
icon. Takes precedence over color when both are set.
<eun-tag severity="info">Info</eun-tag>
<eun-tag severity="success">Success</eun-tag>
<eun-tag severity="warning">Warning</eun-tag>
<eun-tag severity="critical">Critical</eun-tag>
<eun-tag severity="neutral">Neutral</eun-tag>
Part of the shared vocabulary covered in
Color
For a label with no semantic state, such as a category or a plan tier, use
color instead of severity.
<eun-tag color="primary">Primary</eun-tag>
<eun-tag color="secondary">Secondary</eun-tag>
<eun-tag color="light">Light</eun-tag>
<eun-tag color="medium">Medium</eun-tag>
<eun-tag color="dark">Dark</eun-tag>
Display appearance
<eun-tag severity="success" appearance="default">Default</eun-tag>
<eun-tag severity="success" appearance="fill">Fill</eun-tag>
<eun-tag severity="success" appearance="outline">Outline</eun-tag>
<eun-tag severity="success" appearance="flat">Flat</eun-tag>
flat always renders the same muted, low-emphasis surface regardless of
color/severity, handy for a secondary piece of metadata that shouldn't
compete visually with a severity tag next to it.
Sizes
<eun-tag severity="info" size="s">Small</eun-tag>
<eun-tag severity="info">Medium</eun-tag>
<eun-tag severity="info" size="l">Large</eun-tag>
Custom icon
Set icon to add an icon to a plain color tag, which otherwise renders
none. It has no effect when severity is also set, since a severity's own
icon always takes precedence (see the API tab).
<eun-tag color="primary" icon="star">Featured</eun-tag>
Need something other than a eun-icon, or a different icon library
entirely? Slot your own content into icon instead. It replaces the
resolved icon/severity glyph entirely.
<eun-tag color="primary">
<svg
slot="icon"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path
d="m12 2 2.9 6.9L22 10l-5.5 4.8L18 22l-6-3.7L6 22l1.5-7.2L2 10l7.1-1.1L12 2Z"
></path>
</svg>
Featured
</eun-tag>
Hiding the icon
<eun-tag severity="success" hide-icon>Active</eun-tag>
Rounded
<eun-tag severity="info" rounded>12</eun-tag>
<eun-tag color="medium" rounded hide-icon>Beta</eun-tag>
Uppercase
<eun-tag severity="warning" uppercase hide-icon>Draft</eun-tag>
Reserve this for very short labels, see the Accessibility tab for why.
Icon only
Set icon-only to shrink the tag to its icon alone, into a compact square
badge, typically paired with rounded. Requires icon or severity to be
set. The slotted label stays in the DOM as the tag's accessible name,
visually hidden but still announced to assistive technology (see the
Accessibility tab).
<eun-tag severity="success" icon-only rounded>Active</eun-tag>
<eun-tag color="primary" icon="star" icon-only rounded>Featured</eun-tag>
<eun-tag severity="critical" icon-only appearance="fill" rounded>Error</eun-tag>
Custom colors
Override the --tag-* CSS variables, listed in full in the API tab. Only
applies when neither color nor severity is set, since both take over
the same internal color slots.
<eun-tag class="custom-tag">Custom</eun-tag>
.custom-tag {
--tag-background-color: #fdf2f8;
--tag-color: #be185d;
}
Keyboard interactions
None. eun-tag isn't focusable or interactive on its own, so there's
nothing to reach with the keyboard. It carries no tabindex and no click
handling.
No ARIA role of its own
eun-tag sets no role and no ARIA state on its host, so it reads to
assistive technology as plain inline content, exactly like a <span>
wrapping the same text would. Its internal eun-icon is always
aria-hidden="true" (see eun-icon's own Accessibility tab), so only the
slotted label text is ever announced. A eun-tag with hide-icon and one
without read identically to a screen reader.
Icon only still needs a real label
icon-only only changes what's painted on screen: the slotted text stays in
the DOM and is what a screen reader announces, since the icon itself is
aria-hidden. Always slot a real, descriptive label ("Active", not an empty
string or a repeat of the icon's file name) even though it's visually
hidden — an icon alone conveys no reliable meaning to assistive technology.
Don't rely on color alone
severity/color change the tag's visual appearance only, and WCAG 1.4.1
requires that information conveyed by color also be available another way.
eun-tag already helps here by pairing every severity with a matching
icon by default, but that icon is itself aria-hidden (decorative, not a
substitute accessible cue), so the actual carrier of meaning for assistive
technology is the slotted text. Keep it descriptive on its own
("Payment failed", not just "●") rather than relying on the reader
inferring status from a color or glyph they can't perceive.
Color contrast
The default and fill types are built from this design system's own color
tokens, already chosen to meet contrast minimums against their paired
background. A custom --tag-background-color/--tag-color combination (or
a custom brand color) must still be checked against
Uppercase and readability
uppercase adds letter-spacing and forces the label's visual case, but it
does not change the accessible name, which is still the actual slotted
text content regardless of how it's displayed. Some screen readers spell
out an all-caps word letter-by-letter as though it were an acronym,
which is disruptive for anything longer than a couple of characters, so
reserve uppercase for genuinely short labels (a two-word status, an
abbreviation), not a full phrase.
Not a live region
eun-tag has no built-in aria-live/role="status" semantics. If its
content updates in place to reflect new information the user should be
told about immediately (e.g. a count going from "3 new" to "4 new" without
a full page navigation), wrap it in your own aria-live="polite" region,
since eun-tag itself stays silent about the change otherwise.
Reference links