Using Component Themes

Flow uses the following logic to determine which theme to use for the application:

  1. If a @Theme annotation is found at the root navigation level, the theme defined by it is used;

  2. If a @NoTheme annotation is found at the root navigation level, theming is disabled;

  3. If the com.vaadin.flow.theme.lumo.Lumo class is available in the classpath (which comes from the vaadin-lumo-theme project), then it is used as the default theme;

  4. If all the previous conditions are not met, no theme is used.

In summary - if your project uses the vaadin-core dependency, and doesn’t declare any @Theme or @NoTheme, the Lumo theme will be used by default.

To use any custom themes, just add Theme annotation to your root navigation level, RouterLayout or to the top level @Route (see below).

Each root RouterLayout can define it’s own theme. This is not recommended though as any bootstrap addition can cause theme not to be used. We don’t support nor recommend mixing different themes together - the UX should be consistent in one application.

public class MainLayout extends Div implements RouterLayout {

@Route(value = "", layout = MainLayout.class)
public class HomeView extends Div {

@Route(value = "blog", layout = MainLayout.class)
public class BlogPost extends Div {
@Route(value = "")
@Theme(Lumo.class) // can be omitted for Lumo
public class Application extends Div {
@Route(value = "")
public class UnThemedApplication extends Div {

The theme class automatically handles two things:

  • It tells Flow what theme it should use for the Vaadin Components and where the files can be found

  • It specifies a set of shared styles like fonts etc. that will be automatically loaded to the initial page by Flow for the theme.

If the Theme annotation is not on a @Route Component or a top RouterLayout an exception will be thrown on startup.

Theme variants

You can use a Theme variant by defining it on the @Theme annotation:

@Route(value = "")
@Theme(value = MyTheme.class, variant = "large")
public class LargeThemedApplication extends Div {

Variants are like "skins" for the theme - it uses the same files for the theme, but sets special selectors in the body to make it appear different.

Available Themes and Customizations

In Vaadin 10 there is only one ready-made component theme, Lumo, which is the main theme for all Vaadin components. Vaadin 12 also includes the Material theme. Both themes gives you a full set of building blocks to build a modern looking web application that works just as well on desktop and on mobile.

The Flow integration for Lumo is a part of the vaadin-core dependency, and as shown in the previous chapter, very easily taken into use. You can explicitly declare @Theme(Lumo.class) or omit it completely, since the default behavior is to use Lumo if available in the classpath.

Lumo provides some customization points for the components, that allow you to fine tune the look and provide a better UX. It can be customized by using CSS custom properties, see the Lumo documentation for more information. The theming for the Vaadin components is built using Vaadin.ThemableMixin. See vaadin-themable-mixin wiki to learn how theming of Vaadin components is done.

Using Lumo variants

Lumo comes with two variants: light (the default) and dark. You can use the dark variant by using:

@Route(value = "")
@Theme(value = Lumo.class, variant = Lumo.DARK)
public class DarkApplication extends Div {

Individual components have also variants available. Component variants are applied by using the element API to set the variant as the theme attribute. For example, to create a Button with increased legibility, you can use:

Button button = new Button("Themed button");
button.getElement().setAttribute("theme", "contrast primary");

The contrast primary String in this case are theme variants for the Button component. For looking up all available component variants, see the component HTML examples and look under the Lumo Theme tab for examples of the variants.