Eunomia v1.1.0
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

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

eun-icon · for the severity or custom icon, unless hidden
Overview API Examples Accessibility
New Favorite

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, badge fits better. If it needs to be removable, such as a selected filter or an invited guest, use chip instead, which ships with its own delete button built in.

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.

Alternatives

You want… Prefers
A quick visual nudge next to something else, not text that needs to be read eun-badge
Something removable, such as a selected filter or an invited guest eun-chip

Guidance

  • Use severity for a state that maps to a semantic meaning (success/warning/critical/info/neutral), which also picks the matching icon automatically
  • Use color instead 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 uppercase for very short labels (one or two words), see the Accessibility tab
  • Setting both color and severity: severity always wins, so a color set 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-tag for 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

NameTypeDefaultDescription
hide-iconbooleanfalseWhether the icon is hidden from the tag. Takes priority over iconOnly
icon-onlybooleanfalseShows 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
fixed-colorbooleanfalseKeeps a light or dark tag white or black in every theme. Without it, they follow the grey scale, which flips with the active theme. Has no effect on the other colors or on severity
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 renders the same muted, low emphasis surface regardless of color or severity, except for the light and dark colors, which keep their own white or black
iconEunomiaIconName—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
roundedbooleanfalseWhether the tag has rounded corners
uppercasebooleanfalseWhether the tag label is uppercased with extra letter spacing

Import the exact TypeScript type behind any property above, see Types.

Slots

NameDescription
(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
iconReplaces 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

NameDescription
--tag-background-colorSets the background color of the tag, for every appearance, color and severity
--tag-border-colorSets the border color of the tag, for every appearance, color and severity
--tag-border-widthSets the border width of the tag, for every appearance. The border takes room out of the padding, so the tag keeps its size
--tag-colorSets the text and icon color of the tag, for every appearance, color and severity
--tag-border-radiusSets the corner radius of the tag, also over rounded
--tag-gapSets the gap between the tag icon and the label
--tag-padding-blockSets the vertical padding of the tag, for every size. The border is taken out of it, so the tag keeps the same size with or without one
--tag-padding-inlineSets the horizontal padding of the tag, for every size. The border is taken out of it, so the tag keeps the same size with or without one
--tag-font-sizeSets the font size of the tag, for every size
--tag-font-weightSets the font weight of the tag

Basic

Default
<eun-tag>Default</eun-tag>

Variants

Severity

Sets both the color scheme and, unless hide-icon is set, the matching icon. Takes precedence over color when both are set.

Info Success Warning Critical Neutral
<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, alongside every other component that reuses it.

Color

For a label with no semantic state, such as a category or a plan tier, use color instead of severity.

Primary Secondary Light Medium Dark
<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>

light and dark are absolute colors: white and black, whatever the appearance. fill is solid white with black text (solid black with white text for dark), and outline is a white border with white text (black for dark). default is as solid as fill, since white and black have no pale wash, and flat is a faint wash of the color itself. Pick them for a background of the opposite tone.

Default Fill Outline Flat
Default Fill Outline Flat
<eun-tag color="light" fixed-color appearance="outline">Outline</eun-tag>
<eun-tag color="dark" fixed-color appearance="fill">Fill</eun-tag>

Keeping light and dark in every theme

By default, light and dark follow the grey scale, which flips with the active theme: a light tag is white in the light theme and dark in the dark theme. Set fixed-color to pin it to white (or black) in every theme, without overriding any CSS variable. Toggle the theme in the toolbar above to compare: the left column follows the theme, the right one does not. fixed-color has no effect on the other colors or variants.

Follows the theme Fill Outline
Fixed Fill Outline
<eun-tag color="light" fixed-color>Light</eun-tag>
<eun-tag color="dark" fixed-color appearance="outline">Dark</eun-tag>

Display appearance

Default Fill Outline Flat
<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 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. The light and dark colors are the exception: their flat stays a faint wash of white or black.

Sizes

Small Medium Large
<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>

Rounded

12 Beta
<eun-tag severity="info" rounded>12</eun-tag>
<eun-tag color="medium" rounded hide-icon>Beta</eun-tag>

Uppercase

Draft
<eun-tag severity="warning" uppercase hide-icon>Draft</eun-tag>

Reserve this for very short labels, see the Accessibility tab for why.

Icon

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).

Featured
<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.

Featured
<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

Active
<eun-tag severity="success" hide-icon>Active</eun-tag>

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).

Active Featured Error
<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>

Server-side rendering

The tag's box lives in its shadow root, so a server-rendered tag is plain inline text until the element upgrades. Link tag-ssr.css in the page's <head> to draw the final box from the first paint:

<link
  rel="stylesheet"
  href="node_modules/@eunomia/elements/dist/ssr/tag-ssr.css"
/>

A bundler that resolves package exports can reach it as @eunomia/elements/tag-ssr.css. It covers every size, color, severity and appearance, rounded, uppercase, icon-only, hide-icon and the --tag-* custom properties, and keeps room for the icon, which appears with the upgrade.

Customization

Custom colors

Override the --tag-* CSS variables, listed in full in the API tab. They apply to every color, severity and appearance, and always win over them, so a custom value never depends on which combination the tag uses.

Variable Sets
--tag-background-color The background
--tag-color The text and the icon
--tag-border-color The border color
--tag-border-width The border width (1px by default)
--tag-border-radius The corner radius, also over rounded

Every appearance has the same border box, transparent unless it's drawn, and the border is taken out of the padding. Setting a border color, or switching appearance, never changes the size of the tag. Only outline draws its border on its own: give any other appearance a --tag-border-color to draw one, or set --tag-border-width: 0 to remove the outline's.

Custom Bordered fill Custom outline
<eun-tag class="custom-tag">Custom</eun-tag>
.custom-tag {
  --tag-background-color: #fdf2f8;
  --tag-color: #be185d;
  --tag-border-color: #f9a8d4;
}

Custom size

Each size sets its own padding and font size. To size a tag outside of s, m and l, such as a compact numbered pill, override them with the variables below. Like the sizes, they include the border, so the tag keeps the same box with or without one.

Variable Sets
--tag-padding-block The vertical padding
--tag-padding-inline The horizontal padding
--tag-font-size The font size
--tag-font-weight The font weight (500 by default)
01
<eun-tag class="step-pill" color="primary" rounded>01</eun-tag>
.step-pill {
  --tag-padding-block: 0.2em;
  --tag-padding-inline: 0.7em;
  --tag-font-weight: 700;
}

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.

Semantics and screen readers

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.

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.

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, because an icon alone conveys no reliable meaning to assistive technology.

Visual

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 WCAG 1.4.3 text contrast (4.5:1 for this size of text). See Color for the tokens that already meet it.

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.

Reference links

WCAG 1.4.1: Use of Color
WCAG 1.4.3: Contrast (Minimum)
WCAG 1.4.11: Non-text Contrast