> Markdown version of [Icons](https://vaadin.com/docs/next/components/icons). Section index: [llms.txt](https://vaadin.com/docs/next/components/llms.txt)

# Icons

The icon component can render SVG and font icons. Two icon collections are available out-of-the-box.

**Lit** — `icon-basic.ts`

```typescript
<vaadin-icon icon="lumo:photo"></vaadin-icon>
<vaadin-icon icon="vaadin:phone"></vaadin-icon>
```

**Flow** — `IconBasic.java`

```java
Icon lumoIcon = LumoIcon.PHOTO.create();
Icon vaadinIcon = VaadinIcon.PHONE.create();

layout.add(lumoIcon, vaadinIcon);
```

**React** — `icon-basic.tsx`

```tsx
<Icon icon="lumo:photo" />
<Icon icon="vaadin:phone" />
```

## <a id="default-icon-collections"></a>Default Icon Collections

Two icon collections are available through Vaadin dependencies: Vaadin Icons and Lumo Icons. The Flow API provides enumations for these collections that makes them easy to use.

> **Note: Explicitly Import Icon Collections**
>
> To use the Lumo icon collection in Flow, create icons with the `LumoIcon` enum, which ensures that the Lumo icons are automatically included in the application bundle. The Vaadin icon collection is included by default.
>
> To use icons in client-side code (React / HTML), remember to import the necessary iconset explicitly. For Vaadin icons, use `import '@vaadin/icons';` etc. Failing to do so may result in icons being visible only in development mode but not in production.

### <a id="vaadin-icons"></a>Vaadin Icons

Vaadin Icons is a collection of over six-hundred icons.

**Lit** — `vaadin-icons.ts`

```typescript
<vaadin-icon icon="vaadin:phone"></vaadin-icon>
<vaadin-icon icon="vaadin:calendar"></vaadin-icon>
<vaadin-icon icon="vaadin:alarm"></vaadin-icon>
<vaadin-button theme="icon">
  <vaadin-icon icon="vaadin:bell"></vaadin-icon>
</vaadin-button>
```

**Flow** — `VaadinIcons.java`

```java
Icon phoneIcon = VaadinIcon.PHONE.create();
Icon calendarIcon = VaadinIcon.CALENDAR.create();
Icon alarmIcon = VaadinIcon.ALARM.create();
Button button = new Button(VaadinIcon.BELL.create());

layout.add(phoneIcon, calendarIcon, alarmIcon, button);
```

**React** — `vaadin-icons.tsx`

```tsx
<Icon icon="vaadin:phone" />
<Icon icon="vaadin:calendar" />
<Icon icon="vaadin:alarm" />
<Button theme="icon">
  <Icon icon="vaadin:bell" />
</Button>
```

The [Built-In Icons](https://vaadin.com/docs/next/components/icons/default-icons.md) page contains a list of the full Vaadin Icons collection.

#### <a id="lumo-icons"></a>Lumo Icons

Lumo Icons are used in the default Lumo theme for Vaadin components.

**Lit** — `lumo-icons.ts`

```typescript
<vaadin-icon icon="lumo:photo"></vaadin-icon>
<vaadin-icon icon="lumo:calendar"></vaadin-icon>
<vaadin-icon icon="lumo:clock"></vaadin-icon>
<vaadin-button theme="icon">
  <vaadin-icon icon="lumo:bell"></vaadin-icon>
</vaadin-button>
```

**Flow** — `LumoIcons.java`

```java
Icon phoneIcon = LumoIcon.PHOTO.create();
Icon calendarIcon = LumoIcon.CALENDAR.create();
Icon alarmIcon = LumoIcon.CLOCK.create();
Button button = new Button(LumoIcon.BELL.create());

layout.add(phoneIcon, calendarIcon, alarmIcon, button);
```

**React** — `lumo-icons.tsx`

```tsx
<Icon icon="lumo:photo" />
<Icon icon="lumo:calendar" />
<Icon icon="lumo:clock" />
<Button theme="icon">
  <Icon icon="lumo:bell" />
</Button>
```

Lumo Icons are rendered on a 24×24 pixel canvas, with a 16×16 pixel active area for the icon itself and 4 pixels of whitespace around the icon.

The [Default Icons](https://vaadin.com/docs/next/components/icons/default-icons.md) contains a list of the full Lumo Icons collection.

## <a id="using-third-party-icons"></a>Using Third-Party Icons

Third-party icons can be rendered with the icon component. Three common formats are supported: standalone SVG files; SVG sprites; and icon fonts.

### <a id="standalone-svg-images"></a>Standalone SVG Images

Standalone SVG images can be rendered as inline SVG icons using the icon component.

**Lit** — `svg-standalone.ts`

```typescript
<vaadin-icon src="${codeBranchIcon}"></vaadin-icon>
```

**Flow** — `SvgStandalone.java`

```java
SvgIcon icon = new SvgIcon("/icons/code-branch.svg");
```

**React** — `svg-standalone.tsx`

```tsx
<Icon src={codeBranchIcon} />
```

Thanks to inline SVG rendering, an icon can be styled with CSS. For example, you could change its fill color or stroke.

The advantage of standalone SVG images is that only the icons actually needed in the UI are loaded into the browser.

### <a id="svg-sprites"></a>SVG Sprites

SVG sprites are SVG files containing multiple images wrapped in `<symbol>` tags. An `id` attribute on the symbol tag is used to identify the images.

Using an image from an SVG sprite is similar to using a standalone SVG image — append the symbol `id` to the file path, prefixed by `#`:

**Lit** — `svg-sprites.ts`

```typescript
<vaadin-icon src=${solidSprite} symbol="code-branch"></vaadin-icon>
<vaadin-icon src=${solidSprite} symbol="user"></vaadin-icon>
```

**Flow** — `SvgSprites.java`

```java
SvgIcon codeBranchIcon = new SvgIcon("/icons/solid.svg", "code-branch");
SvgIcon userIcon = new SvgIcon("/icons/solid.svg", "user");
```

**React** — `svg-sprites.tsx`

```tsx
<Icon src={spriteIcons} symbol="code-branch" />
<Icon src={spriteIcons} symbol="user" />
```

Like standalone SVG images, sprite icons are also rendered as inline SVG for styling support.

The advantage of using an SVG sprite is that only one file needs to be loaded into the browser. Custom SVG sprites that contain only the icons needed in the application, can provide performance benefits compared to standalone SVG images.

Many [third-party tools for creating SVG sprites](https://www.google.com/search?q=svg+sprite+generator) are available.

### <a id="icon-fonts"></a>Icon Fonts

Icon fonts are loaded into the UI through a combination of a few factors:

- First, a font file — usually placed in the theme folder;

- Second, a [`@font-face` declaration](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face) — usually in a stylesheet provided with the font and imported into your theme’s master stylesheet, `styles.css`; and

- Optionally, a stylesheet with CSS classes representing the font and the icons in it — usually also imported into `styles.css`, which may be included in same stylesheet as the `@font-face` declaration.

The desired icon can be specified in three different ways, depending on the font and stylesheets provided:

- Icon-specific CSS class (e.g., `fa-calendar`), which requires a stylesheet defining CSS classes for each icon, usually bundled with the icon font;

- Ligature (e.g., `calendar`), which requires an icon font that supports ligatures; and

- Character code (e.g., `f199`), corresponding to the code point of the icon’s glyph in the font.

**Lit** — `icon-fonts.ts`

```typescript
<vaadin-icon icon-class="fa fa-code-branch"></vaadin-icon>
<vaadin-icon icon-class="fa fa-user"></vaadin-icon>
```

**Flow** — `IconFonts.java`

```java
FontIcon codeBranchIcon = new FontIcon("fa", "fa-code-branch");
FontIcon userIcon = new FontIcon("fa", "fa-user");

layout.add(codeBranchIcon, userIcon);
```

**React** — `icon-fonts.tsx`

```tsx
<Icon iconClass="fa fa-code-branch" />
<Icon iconClass="fa fa-user" />
```

`icon-fonts.css`

```css
.fa {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: 'Font Awesome 6 Free' !important;
  speak: never;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.fa-code-branch:before {
  content: "\f126";
}
.fa-user:before {
  content: "\f007";
}
```

Theme folder with files for FontAwesome icon font

```
themes/
  └── my-theme/
      ├── styles.css
      └── fontawesome/
          ├── fontawesome.css (classes for individual icons in the font)
          ├── solid.css (stylesheet with @font-face declaration)
          └── fa-solid-900.woff2 (icon font)
...
```

styles.css

```css
@import url('fontawesome/solid.css');
@import url('fontawesome/fontawesome.css');
```

solid.css

```css
@font-face {
  font-family: 'Font Awesome 6 Free';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("fa-solid-900.woff2") format("woff2"), url("fa-solid-900.ttf") format("truetype");
}
```

The `@font-face` declaration defining the icon font family must be placed in a global stylesheet, not in a Shadow DOM stylesheet.

> **Note: Icon Font Stylesheets Inside a Shadow Root**
>
> To use CSS classes for icon fonts inside a Shadow DOM, such as that of a Lit template, they must be loaded separately into it. The easiest way to do this is to load them as part of the application’s theme, and [apply the theme inside the Shadow DOM](https://vaadin.com/docs/next/flow/component-internals/templates/styling-templates.md) with `applyTheme()`.

The font can also be defined using its `font-family` name — as defined in the `@font-face` declaration.

```html
<vaadin-icon font-family="Material Icons" ligature="home"></vaadin-icon>
```

```java
// font-family name for font, ligature for icon
FontIcon fi3 = new FontIcon();
fi3.setFontFamily("Material Icons");
fi3.setLigature("home");
```

```tsx
<Icon fontFamily="Material Icons" ligature="home" />
```

Note that the rendering quality of icon fonts is inferior to SVGs, especially in smaller sizes.

## <a id="icon-configuration"></a>Icon Configuration

You may configure a few properties or styles for the icons.

### <a id="color-other-styles"></a>Color & Other Styles

The icon’s fill or text color can be set to any CSS color value.

**Lit** — `icons-color.ts`

```typescript
<vaadin-icon src="${codeBranch}" style="color: red"></vaadin-icon>
<vaadin-icon icon-class="fa fa-user" style="color: red"></vaadin-icon>
```

**Flow** — `IconsColor.java`

```java
SvgIcon svgIcon = new SvgIcon("/icons/code-branch.svg",
        "svg-branch.svg");
svgIcon.setColor("red");

FontIcon fontIcon = new FontIcon("fa", "fa-user");
fontIcon.setColor("red");

layout.add(svgIcon, fontIcon);
```

**React** — `icons-color.tsx`

```tsx
<Icon src={codeBranch} style={{ color: 'red' }} />
<Icon iconClass="fa fa-user" style={{ color: 'red' }} />
```

### <a id="size-padding"></a>Size & Padding

The icon component has a property for setting the desired outer size of the icon in pixels. This automatically sets the icon’s width and height to the same value, as icons are rendered in a square (i.e., 1:1) aspect ratio, by default.

**Lit** — `icons-sizing.ts`

```typescript
<vaadin-icon src="${codeBranch}"></vaadin-icon>
<vaadin-icon src="${codeBranch}" style="--vaadin-icon-size: 2rem;"></vaadin-icon>
<vaadin-icon src="${codeBranch}" style="--vaadin-icon-size: 3rem;"></vaadin-icon>
```

**Flow** — `IconsSizing.java`

```java
SvgIcon iconDefaultSize = new SvgIcon("/icons/code-branch.svg",
        "svg-branch.svg");

SvgIcon iconMediumSize = new SvgIcon("/icons/code-branch.svg",
        "svg-branch.svg");
iconMediumSize.setSize("2rem");

SvgIcon iconLargeSize = new SvgIcon("/icons/code-branch.svg",
        "svg-branch.svg");
iconLargeSize.setSize("3rem");

layout.add(iconDefaultSize, iconMediumSize, iconLargeSize);
```

**React** — `icons-sizing.tsx`

```tsx
<HorizontalLayout
  theme="spacing"
  className="icons-sizing-padding-example"
  style={{ alignItems: 'flex-end' }}
>
  <Icon src={codeBranch} />
  <Icon src={codeBranch} style={{ '--vaadin-icon-size': '2rem' }} />
  <Icon src={codeBranch} style={{ '--vaadin-icon-size': '3rem' }} />
</HorizontalLayout>
```

The visual size of the icon can be adjusted to create internal padding to compensate for the lack of surrounding whitespace in the icon itself.

**Lit** — `icons-padding.ts`

```typescript
<vaadin-icon src="${codeBranch}" style="--vaadin-icon-size: 3rem;"></vaadin-icon>
<vaadin-icon
  src="${codeBranch}"
  style="--vaadin-icon-size: 3rem; --vaadin-icon-visual-size: 2rem;"
></vaadin-icon>
<vaadin-icon
  src="${codeBranch}"
  style="--vaadin-icon-size: 3rem; --vaadin-icon-visual-size: 1rem;"
></vaadin-icon>
```

**Flow** — `IconsPadding.java`

```java
SvgIcon icon = new SvgIcon("/icons/code-branch.svg");
icon.getStyle().set("--vaadin-icon-size", "3rem");

SvgIcon iconSmallPadding = new SvgIcon("/icons/code-branch.svg");
iconSmallPadding.getStyle().set("--vaadin-icon-size", "3rem");
iconSmallPadding.getStyle().set("--vaadin-icon-visual-size", "2rem");

SvgIcon iconLargePadding = new SvgIcon("/icons/code-branch.svg");
iconLargePadding.getStyle().set("--vaadin-icon-size", "3rem");
iconLargePadding.getStyle().set("--vaadin-icon-visual-size", "1rem");

layout.add(icon, iconSmallPadding, iconLargePadding);
```

**React** — `icons-padding.tsx`

```tsx
<HorizontalLayout
  theme="spacing"
  className="icons-sizing-padding-example"
  style={{ alignItems: 'flex-end' }}
>
  <Icon src={codeBranch} style={{ '--vaadin-icon-size': '3rem' }} />
  <Icon
    src={codeBranch}
    style={{ '--vaadin-icon-size': '3rem', '--vaadin-icon-visual-size': '2rem' }}
  />
  <Icon
    src={codeBranch}
    style={{ '--vaadin-icon-size': '3rem', '--vaadin-icon-visual-size': '1rem' }}
  />
</HorizontalLayout>
```

## <a id="custom-icon-collection-apis"></a>Custom Icon Collection APIs

Within the application context, various icon libraries — including FontAwesome, Material Symbol, and others — may be utilized. Implementing custom icon libraries, as exemplified by the `VaadinIcon` enumeration, simplifies developer workflows by eliminating the need to recall specific URL paths, or to remember which CSS classes to apply when working with font icons:

`FontIconCollection.java`

```java
public enum FontAwesomeIcons {
    CODE_BRANCH("fa-code-branch"), USER("fa-user");

    private String iconClass;

    FontAwesomeIcons(String iconClass) {
        this.iconClass = iconClass;
    }

    public FontIcon create() {
        return new FontIcon("fa", iconClass);
    }
}

...

FontIcon codeBranch = FontAwesomeIcons.CODE_BRANCH.create();
add(codeBranch);
```

## <a id="accessibility"></a>Accessibility

Screen readers are not able to announce icons, by default. In fact, the icon component is built in a way that is completely ignored by assistive technologies.

However, in most cases, there shouldn’t be a need to make icons themselves screen reader friendly. Instead, the component (e.g., Button) in which the icon is used, should have a screen reader friendly accessible name.

**Lit** — `icons-accessibility.ts`

```typescript
<vaadin-button aria-label="Close dialog" theme="icon">
  <vaadin-icon icon="vaadin:close"></vaadin-icon>
</vaadin-button>
```

**Flow** — `IconsAccessibility.java`

```java
Button closeButton = new Button(VaadinIcon.CLOSE.create());
closeButton.setAriaLabel("Close dialog");
```

**React** — `icons-accessibility.tsx`

```tsx
<Button aria-label="Close dialog" theme="icon">
  <Icon icon="vaadin:close" />
</Button>
```

In situations where icons are used to convey information on their own (e.g., in a table column to convey a value in a graphical manner), you need to give them an accessible name and an ARIA image role attribute to make them announced correctly by screen readers.

```html
<vaadin-icon icon="vaadin:star" role="img" aria-label="Favorite"></vaadin-icon>
```

```java
Icon favoriteStatusIndicator = VaadinIcon.STAR.create();
favoriteStatusIndicator.getElement().setAttribute("role", "img");
favoriteStatusIndicator.getElement().setAttribute("aria-label", "Favorite");
```

```tsx
<Icon icon="vaadin:star" role="img" aria-label="Favorite" />
```

`47B97C93-9646-4D2A-882F-C4F709D3D099`
