Icon
Icon renders a single glyph, loaded by name, in any size or color. It works well on its own, or gets composed automatically inside other components that expose their own icon option.
When to use
Use an icon on its own for a standalone visual cue, such as a status marker, a decorative flourish next to a heading, or an inline glyph. When it lives inside another component that already offers its own icon option, such as a button or a tab, set that option instead of composing an icon by hand, since it keeps sizing and spacing consistent for free.
Install & usage
Pick a framework in the toolbar above and these snippets adapt.
npm install @eunomia/elements
import "@eunomia/elements/icon.js";
<eun-icon name="favorite"></eun-icon>
Importing the file registers <eun-icon> 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/icon.js";
</script>
<eun-icon name="favorite"></eun-icon>
npm install @eunomia/elements
import "@eunomia/elements/icon.js";
function Favorite() {
return <eun-icon name="favorite"></eun-icon>;
}
npm install @eunomia/elements
"use client";
import "@eunomia/elements/icon.js";
export function Favorite() {
return <eun-icon name="favorite"></eun-icon>;
}
npm install @eunomia/elements
<script setup>
import "@eunomia/elements/icon.js";
</script>
<template>
<eun-icon name="favorite"></eun-icon>
</template>
npm install @eunomia/elements
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import "@eunomia/elements/icon.js";
@Component({
selector: "app-favorite",
template: `<eun-icon name="favorite"></eun-icon>`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class FavoriteComponent {}
Guidance
- Use
eun-icondirectly for a standalone glyph: a status marker, a decorative flourish, an inline visual cue - Prefer a component's own
iconproperty (eun-button,eun-tab, ...) over composingeun-iconby hand inside it, when that property exists - Browse the full set on the
Icons page and copy the exact name from there - Pick a shape that matches the surrounding state (e.g. an
outlineglyph for an empty/inactive state, the filled default for an active one)
- Relying on an icon's color or shape alone to convey meaning, with no accompanying text
- Using an icon-only interactive element without an
aria-labelon that parent element - Assuming every icon ships all four shapes: an icon missing a given shape automatically falls back to its default (filled) glyph instead of disappearing, but that fallback still changes what's rendered
Live testing
Properties
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
| name | EunomiaIconName | — | The icon to render. A shape variant baked into the name is used when shape isn't set |
| shape | EunomiaIconType | — | Forces a shape variant, taking priority over any variant already baked into name |
| size | string | — | The icon size, in any valid CSS unit. A bare number is treated as pixels |
Import the exact TypeScript type behind any property above, see
CSS custom properties
| Name | Description |
|---|---|
| --icon-size | Sets the size of the icon, overridden by the size property when set |
| --icon-color | Sets the color of the icon, defaulting to the surrounding text color |
| --icon-background | Sets a background color behind the icon, for example for a hover highlight. Transparent by default |
| --icon-padding | Sets the space between the icon and its background box. Zero by default |
| --icon-border-radius | Sets the corner radius of the background box |
Shapes
Every icon is available in up to four shapes: default (filled),
outline, round, and sharp. Set it via the shape property.
Not every icon ships all four, so one that's missing a given shape
falls back to its default glyph automatically.
<eun-icon name="add_location"></eun-icon>
<eun-icon name="add_location" shape="outline"></eun-icon>
<eun-icon name="add_location" shape="round"></eun-icon>
<eun-icon name="add_location" shape="sharp"></eun-icon>
Shape baked into the name
As a shorthand, name can carry its own shape suffix (e.g.
add_location_outline) instead of setting shape separately, handy when
copying a name straight from the
shape property always wins.
<eun-icon name="add_location_outline"></eun-icon>
<!-- shape="round" overrides the "_outline" suffix baked into name -->
<eun-icon name="add_location_outline" shape="round"></eun-icon>
Sizes
Set any CSS size unit via the size property, or --icon-size for a
CSS-only override. A bare number is treated as pixels, while a % value
is converted to rem.
<eun-icon name="favorite" size="16"></eun-icon>
<eun-icon name="favorite" size="24"></eun-icon>
<eun-icon name="favorite" size="32"></eun-icon>
<eun-icon name="favorite" size="48"></eun-icon>
Part of the shared vocabulary covered in
Color
By default (no --icon-color set), an icon inherits the surrounding
text color, handy for an icon embedded inline in a link or a piece of
text.
<div style="color: #148cd2;">
<eun-icon name="favorite"></eun-icon>
</div>
Override it with --icon-color:
<eun-icon name="favorite" style="--icon-color: #dc1414;"></eun-icon>
Background
Give the icon a background box with --icon-background, combine it
with --icon-padding (zero by default, so the background hugs the
icon exactly) to add breathing room around it, and
--icon-border-radius to shape the corners. Both the color and
background transition smoothly, so this is typically wired to
:hover to build an icon-picker-style highlight. Hover the icon
below:
eun-icon {
--icon-color: var(--eun-color-grey-600);
--icon-padding: 8px;
}
eun-icon:hover {
--icon-color: var(--eun-color-primary-500);
--icon-background: var(--eun-color-primary-transparent);
}
Composed into other components
Most interactive components that accept an icon render eun-icon
internally through their own icon property or slot, rather than
requiring it to be composed by hand:
<!-- eun-button: icon slotted at start or end -->
<eun-button>
Delete
<eun-icon slot="start" name="delete"></eun-icon>
</eun-button>
<!-- eun-tab: icon set directly as an attribute -->
<eun-tab slot="navigation" panel="inbox" icon="mail">Inbox</eun-tab>
See
Full icon set
Every icon this component can render, browsable by name and shape,
with click-to-copy markup: see
Keyboard interactions
None: the icon isn't focusable or interactive on its own, so there's nothing to reach with the keyboard.
Decorative by default
The rendered SVG always carries aria-hidden="true": eun-icon is
treated as purely decorative and is never exposed to assistive
technology, even when used alone with no other visible content.
Icon-only interactive elements
When an icon is the only content of an interactive element (an
icon-only button, for instance), set an aria-label on that parent
element yourself, describing the action, not the icon.
eun-icon cannot provide one on its own behalf: since its SVG is
aria-hidden, a screen reader would otherwise announce nothing at
all for that control. See the Icon-only example on the
Color contrast
When an icon conveys meaning on its own rather than being purely
ornamental (a status marker, a severity indicator in a table row,
...), its color against its background must still meet the
Reduced motion
The color and background transition used for hover/focus highlights
(see the Background example) respects
prefers-reduced-motion: reduce: with that OS-level setting on, the
change applies instantly instead of fading.
Direction (RTL)
eun-icon never auto-mirrors a glyph for right-to-left layouts.
For a directional icon (an arrow, a "next"/"previous" chevron, ...),
either pick an icon name whose meaning doesn't depend on direction,
or apply your own transform: scaleX(-1); in an RTL context.
Reference links
RGAA 4.1.2 MDN: aria-hidden WCAG 1.4.11: Non-text Contrast