Documentation

Documentation versions (currently viewingVaadin 24)

Styling Vaadin Components

Explanation and examples on how to customize the styling of Vaadin components.

You can style Vaadin components in two primary ways: customizing Lumo style properties; and applying custom CSS.

Using Lumo style properties, identified by the --lumo- prefix, is the best way to modify styles across all Vaadin components. For example, in addition to applying a consistent visual brand for an entire application (or multiple applications), they can also be scoped to views, layouts, and components. Style property values are assigned in CSS stylesheets, but require minimal knowledge of CSS.

Applying custom CSS to components requires more CSS knowhow, but can be necessary to introduce styling that is not covered by style properties.

In both cases, styles are applied with CSS stylesheets, typically placed in the application theme folder, for example in the styles.css master stylesheet.

A stylesheet contains one or more style blocks, consisting of a selector that specifies the HTML elements to which the styles are applied, and, within curly braces, a set of style properties and their values:

vaadin-text-field {
  width: 200px;
  margin-left: 20px;
}

The web.dev CSS tutorial is helpful in learning the basics of CSS.

Customizing Lumo Style Properties

The default Lumo theme is based on a set of style properties — CSS custom properties — representing colors, fonts, sizes and other styles used by Vaadin components. These can be customized by providing new values for them in a CSS stylesheet, either globally, or scoped to a certain component type or instance.

To modify them globally — for all components in the entire application — place the value assignments in a CSS style block using the html selector:

html {
  --lumo-primary-color: green;
  --lumo-font-family: 'Roboto';
}
Note
Embedded Components

If the theme is to be used with embedded Flow applications or components, such as for use with Design System Publisher, an additional :host selector must be used for global style property assignments: html, :host { /* global styles */ }

Style Properties Scoped to Specific Components

Style property assignments can be scoped to a specific component type, such as Buttons or Text Fields, by using the corresponding HTML element name as the selector:

vaadin-button {
  --lumo-primary-text-color: green;
}

vaadin-text-field {
  --lumo-font-family: 'Roboto';
}

You’ll find the HTML element names for a component in the Styling page of each component.

Style property assignments can also be scoped to specific component instances, by applying CSS class names to the components with the addClassName method and adding them to the root element selector prefixed with a period:

Button specialButton = new Button("I'm special");
specialButton.addClassName("special");
vaadin-button.special {
  --lumo-primary-text-color: cyan;
}
Note
CSS Class Names
CSS class names are identifier-attributes applied to HTML elements in order to scope CSS styling to them. The same class name can be applied to multiple elements, and each element can have multiple class names. They have nothing to do with Java or TypeScript classes.

Style Properties Scoped to Part of the UI

Style property values can also be applied to any container element, such as Horizontal Layout and Vertical Layout or HTML elements like divs, typically by applying CSS class names to them. All Vaadin components, as well as other child elements, automatically inherit style property values applied to their parent elements:

Button logOutButton = new Button("Log out");
HorizontalLayout appHeader = new HorizontalLayout(logOutButton);
appHeader.addClassName("app-header");
.app-header {
  /* This will be applied to the button and all other elements in the app-header */
  --lumo-primary-text-color: green;
}

This can be used to apply a unique set of style properties to specific views in the application, by applying a CSS class name to the view’s root layout element, and scoping style property assignments to it.

Applying Custom CSS

Vaadin components are more complex than native HTML elements due to the additional features they provide. They also utilize an HTML feature called shadow DOM, which encapsulates their internal HTML structure, and isolates it from the page’s global CSS.

Because of this, even seemingly simple components like Text Fields and Buttons cannot be styled using native HTML element selectors like input {…​} and button {…​}. Instead, each component exposes a number of parts and states that can be used as selectors in CSS style blocks, that are listed in the Styling page of each component.

As an example, to apply a background color and a border to the actual input field part of a Text Field – the gray area where text is entered – you need to target a shadow part called input-field, which can be styled using the ::part(input-field) CSS selector, as shown below.

vaadin-text-field::part(input-field) {
  background: white;
  border: 1px solid gray;
}

Component styles can be placed in the master stylesheet, or any other stylesheet imported through it, in the theme folder.

Note
@CssImport Supported, Not Recommended
In older versions of Vaadin, stylesheets were loaded using @CssImport and @Stylesheet annotations – and in very old versions using the @HtmlImport annotation. While @CssImport and @Stylesheet still work, they are no longer recommended as the primary way to load styles for components.

Be Aware of States & Variants When Applying CSS

Custom CSS applied to a component can often override state and variant styles built into the component. As an example, the following CSS changes the text color of all Buttons, including the built-in Primary style variant and the disabled state:

vaadin-button {
  color: red;
}

To only change the text color of enabled buttons using the default style variant, you need to exclude those with the :not() selector:

vaadin-button:not([disabled]):not([theme~="primary"]) {
  color: red;
}