Themes

Themes are collections of style sheets, fonts, and other assets that define the look and feel of components and other UI features.

Vaadin has two built-in themes, Lumo and Material, that provide great starting points for an application’s appearance. Both built-in themes have a dark mode variant and the Lumo theme also has a compact sizing preset. Their styles are based on CSS properties that can be customized to change the appearance of Vaadin components. You can also create your own custom theme that can be packaged for reuse in multiple applications.

Note
CSS custom properties
See the Foundation section for details on the CSS properties available in the Lumo and Material themes, and the CSS Custom Properties section on how to use custom properties.

Applying a Theme

By default, Vaadin applications use the Lumo theme. You can apply a different theme using the @Theme annotation on a class that implements AppShellConfigurator. An application may only have one such class and you need to define any similar configuration annotations in the same class, such as @PWA or PageTitle.

For example, in a Spring Boot application, you could have an application configuration class such as the following:

@Theme(value = Material.class)
public class Application extends SpringBootServletInitializer
                         implements AppShellConfigurator {
  ...
}

The dark mode variants can be applied by providing a variant parameter.

@Theme(value = Lumo.class, variant = Lumo.DARK)

Custom themes are applied with a string corresponding to the theme folder.

@Theme(themeFolder = "my-theme")

Customizing a Theme

No Theme

You can opt-out of loading any theme if you want to control the importing of style sheets manually. This means that you rely on application-specific style sheets to also handle component styling. You are also responsible for any lazy-loading or code-splitting of the style sheets.

Use the @NoTheme annotation to opt-out of loading any theme style sheets.

@NoTheme
public class Application extends SpringBootServletInitializer implements AppShellConfigurator {
  ...
}

Theme Resolving Order

The following logic is used to determine which theme is used:

  1. If the @Theme annotation is found on the application shell class, the theme set in the annotation is used

  2. If the @NoTheme annotation is found on the application shell class, no theme style sheets are loaded

  3. If the com.vaadin.flow.theme.lumo.Lumo class is available in the classpath, the Lumo theme is used

Resolving stops when a match is found. No theme is used if none of the conditions are met.

Limitations

Themes can’t be switched at runtime

Full page reload is required. You can’t for example use different themes for different views.

Component themes can’t be mixed

For example, you can’t use the Lumo theme for Date Picker and the Material theme for Button at the same time, because Date Picker internally uses the Button component. If you did, both themes would be applied simultaneously and would cause style conflicts.

This mainly affects client-side development, where you have fine-grained control over the component imports which you use in your views and templates.