Documentation versions (currently viewingVaadin 14)

You are viewing documentation for an older Vaadin version. View latest documentation

Theming, styling, look and feel

This chapter covers how to adjust the visual look of your application, including styles, icons, home screen icons, and some other customizations for mobile.

It should be noted up-front that the app comes with two parts that need to be styled separately:

  1. the offline page (offline-page.html) which is an independent HTML page with minimal CSS defining the look of the offline screen

  2. the actual application which uses the Polymer’s approach to styling (style modules, see for more details).

Styling the offline page

The offline page is defined in the stand-alone offline-page.html file. It has a pretty simple DOM structure, which can still support multiple screen sizes and layouts. The included CSS makes the page look the same as the other (online) pages of the application and defines some responsive behavior.

The offline page

The main fonts and colors are chosen to match the fonts and colors of the Vaadin Lumo theme used in the other pages of the application, and can easily be changed.

You can modify the background-image, or remove it entirely:

.info {
    background-image: url(images/offline-login-banner.jpg);
    background-size: cover;
    background-position-x: center;

Styling the application

The Bakery app starter uses the Vaadin Lumo theme as a baseline for its visual styles. The theme sets the global fonts and base colors for the app and provides styles for all Vaadin components. The app makes a few customizations to the Lumo theme (in the shared-styles.js file) and defines styles for all application-specific components and views.

Notice that the Lumo theme is set on all root @RouterLayout classes (MainView and LoginView). You can read more about the @Theme annotation in the Using Themes chapter.

public class MainView extends PolymerTemplate<TemplateModel>

Most views and components in the Bakery app starter take advantage of the Vaadin 10+ support for Polymer-based templates. That’s why the styling approach recommended for Polymer-based Web Components applies fully to the Bakery app starter.


This file is the “entry point” to the 'global' application styles. It includes the shared-styles Polymer style module that should be included into the local styles of every Polymer template in the app. It also contains customizations for the Lumo theme for a number of Vaadin components (for example, for <vaadin-text-field> and <vaadin-grid>):

<dom-module id="bakery-grid-styles" theme-for="vaadin-grid">
      :host {
         width: 100%;
         margin: auto;
         flex: 1;

Any change that you want to apply to all components in the app should be either placed directly into the shared-styles.js file, inside the innerHTML along with the other declarations. Alternatively, you can import a javascript file using the import directive. The file should have the same format:

import '@polymer/polymer/lib/elements/custom-style.js';
const $_styleContainer = document.createElement('template');

$_styleContainer.innerHTML = `
// Place custom styles here


This file defines a custom extension to the default theme for the <vaadin-chart> element. Any changes to the charts look-and-feel on the dashboard view would be defined in this file:

import '@polymer/polymer/polymer-element.js';
import '@vaadin/vaadin-charts/vaadin-chart-default-theme.js';
const $_documentContainer = document.createElement('template');

$_documentContainer.innerHTML = `
<dom-module id="bakery-charts-theme" theme-for="vaadin-chart">
    <style include="vaadin-chart-default-theme">
      :host(.yearly-sales) .highcharts-color-0 {
        stroke: #18ddf2;
        fill: #18ddf2;

Adjusting Lumo properties

Various aspects of the Lumo theme (such as base fonts and colors) can be easily adjusted by changing the CSS custom properties.

For instance, the font in the Lumo theme is defined by the --lumo-font-family custom property. Changing the value of this property for the entire application or for some parts of it would change the font. For example, setting it in the main-view.js would affect all pages of the app that use the MainView class as a parent layout (that is, all the pages except for the login page).

<dom-module id="main-view">
      :host {
        /* Assuming you have this font imported e.g. from Google Fonts*/
        --lumo-font-family: 'Roboto Condensed';

The full list the custom CSS properties exposed by the Lumo theme is available in the Lumo documentation.

Lumo has a built-in dark color palette which can be enabled by setting the theme="dark" attribute on the root element of the app (or on the <body> of the page). More information is available in the Lumo docs.
Dark-gray Bakery

Icons, logos and viewport configuration

The icons/ folder contains the application logo image in different formats. It can be replaced with another image of your choice, but make sure to provide the image in all formats required by the set of your target browsers and devices (see this article for details).


The image displayed by browsers in the tab / window header is a 'favicon'. Most modern browsers would use the image specified in <link rel="icon" sizes="96x96" href="icons/icon-96.png" >, but other sizes might be used as well. The icons/favicon.ico file is provided as a fallback option because that format is supported by all browsers (but it is inefficient and does not support high quality images).

Chrome displaying a favicon

Homescreen icons

The app contains the application icons which are used as “homescreen” icons (i.e. when added to the homescreen of a device). If you need to provide icons for different target devices, or more icon sizes, make sure you also update CustomBootstrapListener in addition to putting the new files into the icons/ folder.

Adding to iOS homescreen

Viewport configuration

Making the application work well on mobile devices of various sizes requires us to tell the device how we intend it to be shown. We can do this by using the @Viewport(VIEWPORT) annotation in the MainView.

Applications that are built for mobile tend to give a more robust feel if zooming is turned off, but you might want to turn it back on, if your application contains content that the user might want to zoom.

Full screen app

If you want your application to run full-screen - without any browser controls, just like a native app - you can add the mobile-web-app-capable meta-tag.

<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">

That can be done by using the Meta annotation in the MainView.

Don’t forget offline-page.html

Remember that offline-page.html is a stand-alone page and has all the icons/viewport tags mentioned above added separately; please remember to update it as well.

In fact, you might want to start customizing by setting up offline-page.html so that it works as you wish, then modify the Java code to match.