Docs

Documentation versions (currently viewingVaadin 24)

Icons

Lumo and Vaadin icons and how to use them in your projects.

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

Open in a
new tab
Icon lumoIcon = LumoIcon.PHOTO.create();
Icon vaadinIcon = VaadinIcon.PHONE.create();

layout.add(lumoIcon, vaadinIcon);

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

Vaadin Icons

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

Open in a
new tab
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);

The Default Icons tab contains a list of the full Vaadin Icons collection.

Lumo Icons

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

Open in a
new tab
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);

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 contains a list of the full Lumo Icons collection.

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.

Standalone SVG Images

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

Open in a
new tab
StreamResource iconResource = new StreamResource("code-branch.svg",
        () -> getClass().getResourceAsStream("/icons/code-branch.svg"));
SvgIcon icon = new SvgIcon(iconResource);

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.

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 #:

Open in a
new tab
StreamResource iconResource = new StreamResource("solid.svg",
        () -> getClass().getResourceAsStream("/icons/solid.svg"));

SvgIcon codeBranchIcon = new SvgIcon(iconResource, "code-branch");
SvgIcon userIcon = new SvgIcon(iconResource, "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.

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

Open in a
new tab
FontIcon codeBranchIcon = new FontIcon("fa", "fa-code-branch");
FontIcon userIcon = new FontIcon("fa", "fa-user");

layout.add(codeBranchIcon, userIcon);
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)
...
@import url('fontawesome/solid.css');
@import url('fontawesome/fontawesome.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 with applyTheme().

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

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

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

Icon Configuration

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

Color & Other Styles

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

Open in a
new tab
StreamResource codeBranch = new StreamResource("svg-branch.svg",
        () -> getClass().getResourceAsStream("/icons/code-branch.svg"));
SvgIcon svgIcon = new SvgIcon(codeBranch);
svgIcon.setColor("red");

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

layout.add(svgIcon, fontIcon);

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.

Open in a
new tab
SvgIcon iconDefaultSize = new SvgIcon(codeBranch);

SvgIcon iconLumoSize = new SvgIcon(codeBranch);
iconLumoSize.setSize("var(--lumo-icon-size-l)");

SvgIcon iconPxSize = new SvgIcon(codeBranch);
iconPxSize.setSize("48px");

layout.add(iconDefaultSize, iconLumoSize, iconPxSize);

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

Open in a
new tab
SvgIcon iconDefaultSize = new SvgIcon(codeBranch);

SvgIcon iconSmallPadding = new SvgIcon(codeBranch);
iconSmallPadding.getStyle().set("padding", "0.25em");

SvgIcon iconLargePadding = new SvgIcon(codeBranch);
iconLargePadding.getStyle().set("padding", "0.5em");

layout.add(iconDefaultSize, iconSmallPadding, iconLargePadding);

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:

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

Accessibility

Screen readers are not able to announce icons correctly, 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 provide a screen reader friendly accessible name.

Open in a
new tab
Button closeButton = new Button(VaadinIcon.CLOSE.create());
closeButton.setAriaLabel("Close dialog");

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), they need to be given an accessible name and an ARIA image role attribute in order to be announced correctly by screen readers.

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

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