Themes and Theming Applications

Themes define the look and feel of the Vaadin components. The built-in themes have been the base for the application specific theme. Vaadin 7 introduced the themes in Sass format and the parameterized Valo theme, which made it possible to customize the UI by tweaking the parameters.

New CSS Based Themes - No Sass

Since we introduced Sass as a helper to Vaadin Application theming, browsers have started to support CSS Custom Properties[1] (IE11 is polyfilled for production mode.), which brings the customizability gains from Sass to basic CSS, without the overhead of needing to compile the Sass to CSS.

Thus, Vaadin 14 itself isn’t using Sass, but you can of course use it for your own application theming if you want to. You’ll have to setup the sass-compiler workflow yourself, but there are Maven Plugins available for this.

None of the old themes are available for Vaadin 14. By customizing the new Vaadin 14 themes you can easily achieve the same look and feel your application you had before. The DOM is, however, different for the new components, so this is not a copy-paste step.

Theming in Vaadin 14

In Vaadin 14 the theming is built inside the Web Components. There is a different variant of the Web Component for each available theme. Themes cannot typically be mixed and matched, and for coherent user experience you should always use the same theme for all of the components.

The following example shows all the tricks for theming applications, covered in the next topics:

@Theme(Lumo.class) // the theme for Vaadin Components. You can omit it for Lumo
@CssImport("./styles/shared-styles.css") // the application specific styles
@Viewport("width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes")
public class MainLayout extends Div implements RouterLayout,
        AfterNavigationObserver, PageConfigurator {


@Theme Annotation

Vaadin needs to know which theme it should use for the components. Similarly to Vaadin 8 and previously, in Vaadin 14 this is done with a @Theme annotation. This should be applied on the root layout of the application. It can also be in an abstract class if you have multiple root layouts.

When no @Theme is used, the Lumo theme is used by default (if present in the classpath).

Instead of a magic string, you need to provide a Class reference to an theme class that extends AbstractTheme. There are two ready-made themes available for Vaadin 14: Lumo, which was introduced in Vaadin 10, and Material, which has been available since Vaadin 12. You should always use a theme, since the unthemed versions of the components are only meant as a baseline for creating a new theme from scratch!

The theme class will handle two things:

  • It tells Vaadin 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 Vaadin for the theme.

Both Lumo and Material can be customized, see Themes and Styling for more information.

Application Theming

@CssImport("./styles/shared-styles.css") imports the application’s style file.

As the @Theme annotation only specifies the theme for the components, you should have a separate style module for the styling that only applies to the application. The recommended default is to have that inside the frontend folder, e.g. /frontend/styles/shared-styles.css.

You should always use this location for style files to

  • have the file included in the bundle file and allow it to override default theme specific styles

  • have the file automatically imported to templates when using Vaadin Designer to design UIs

You can also use and import a CSS file with the @StyleSheet annotation, but this is not recommended (staring from V14). Regular stylesheets are not processed by ShadyCSS, so you should avoid using custom properties or mixins in them if you want to support Internet Explorer 11.

When creating the UI by defining html templates in JavaScript modules, it makes sense to apply the theming that only applies to a specific template directly in the template and scope it to only affect that.

Specifying the Viewport and <body> element styles

In the previous Vaadin versions, the @Viewport styling was applied to the UI, but now it should be done for the root layout. Otherwise the usage has not changed from Vaadin 8:

@Viewport("width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes")

Vaadin 14 maps the UI directly to the <body> element and gives you more fine grained control easily on what styles it gets with the @BodyStyles annotation. In Vaadin 14 the body has only the margin: 0; style applied, whereas in Vaadin 8 there are the following styles:

overflow: hidden;
margin: 0;
padding: 0;
border: 0;