Changes to component styling in V23

Rolf Smeds
Rolf Smeds
On Mar 15, 2022 1:02:56 PM
In Product

Vaadin 23 was released in the first week of March. As it is the latest version of Vaadin for which long-term support is provided, many applications currently on versions 10–22 will be upgraded to V23 in the near future.
blue background with a CSS code snippetIn addition to new Flow features, like improved Spring Boot integration and the Java version bump to 11, some of the biggest changes for those coming from earlier versions can be found in the components that make up the Vaadin Design System. This article aims to provide an outline of the most important changes to existing components and what they mean for developers migrating their applications from older versions of the platform.

Improvements to components

As described in an earlier article, we are investing a significant amount of effort in improving the accessibility of the Vaadin Design System in order to meet the requirements of various accessibility regulations in the EU, the US, and elsewhere. This effort began in 2021, and the first batch of accessibility improvements shipped in Vaadin 22. Some additional fixes shipped in Vaadin 23, with more planned to be released in minor versions later this year.

Somewhat related to that is improved support for form autocompletion features in browsers. These help end users fill in forms by providing automatic population of common fields like addresses and phone numbers.

Finally, custom styling of the new generation of Vaadin components has, in some ways, been more difficult than it used to be in Vaadin 7 and 8, and we are planning several measures to improve the situation in upcoming versions. Vaadin 23 contains a number of small first steps towards this goal.

Benefits and disadvantages of Shadow DOM

Shadow DOM is a feature of Web Components that isolates the internal HTML, CSS and JavaScript of the component from the surrounding page. It brings many benefits compared to traditional web-based components:

  • A powerful composition mechanism through <slot> elements
  • Style scoping that prevents CSS conflicts with the surrounding page and other components (including third-party libraries), and simplifies the component’s built-in CSS
  • Isolation of the component’s internal client-side scripting from the surrounding page

Unfortunately, its use has also led to some issues in our components:

  • Assistive technologies like screen readers have trouble parsing the components correctly, leading to issues like input field labels not being correctly announced
  • Autocompletion features in browsers have been unable to identify fields to fill them in
  • Component features that are intended to be styleable have been difficult to target with CSS

Changes to components

Most of the fixes outlined above have been achieved by moving certain parts of components out of their Shadow DOM, turning them into regular child elements in the page’s DOM structure, slotted into their appropriate places in the components using <slot> elements.

As an example, the labels (1), error messages (3), and the native <input> elements (2) in all input field components have been moved out of the Shadow DOM of these components:

Effects on custom styles in existing applications

Since CSS styles are applied by targeting specific HTML elements using selectors that often rely on a specific DOM structure, changes to components’ DOM structures inevitably affect some custom styles in many applications when migrating from earlier versions.

Continuing on the above Text Field example, a Vaadin 14 application might use the following CSS to make the field’s value bold:

[part=”value”] {
 font-weight: bold;

As the <input> element is no longer in the Shadow DOM, the selector based on the part attribute no longer works, and needs to be replaced with a selector targeting a slotted input element:

::slotted(input) {
 font-weight: bold;

We’ve done our best to minimize the effects of these changes, for example by wrapping the slots into which the child elements are rendered inside elements with the same part names as the ones they had before, so that selectors like [part=”label”] and [part=”error-message”] still work (although they now target those wrapper elements instead of the elements containing the label and error message, so they might still need to be refactored, depending on the styling applied).

Most input fields no longer based on Text Field

In Vaadin versions 11–21, most text input fields were based on the Text Field component, which meant that styles applied to the Text Field’s internals (whether through the @CssImport annotation’s themeFor attribute or the components folder in the new theme folder feature) were also applied to these.

With the exception of Email Field and Password Field, this is no longer the case. This means that other text input fields, like Combo Box, Number Field and Select, need to be styled separately.

Upgrading Guide

All component changes that we predict might affect custom styles in existing applications are included in the new Upgrading Guide. You’ll find  instructions related to component styling in a section called "Update your CSS".

A note on Shadow part selectors

Readers familiar with recent developments in CSS may be wondering why we are not recommending the use of the ::part() selector. You can indeed use it to target most Shadow DOM elements in Vaadin components, although there are some exceptions due to nested shadow roots. We decided not to use the ::part() selector in the upgrading guide for V23, as that would require a more fundamental refactoring of an application’s CSS than simply changing selectors.

Can we help?

If you encounter a change affecting custom styles that is not mentioned in the guide, please file a ticket about it in our documentation repo on GitHub, so that we can provide you with assistance and add it to the upgrading guide, or reach out to us through our Discord chat, or, if you have a Prime or Enterprise subscription, through the Expert Chat service.

Rolf Smeds
Rolf Smeds
Rolf is the Product Owner for Vaadin Design System
Other posts by Rolf Smeds