Customizing Vaadin component's shadow doms in one file

Before version 23 I put all the customizations to the Vaadin shadow doms in the index.html. Like so…

  <template>
    <style>
        :host [part="form-title"] {
            font-size: clamp(16px, 1.5rem, 22px);
        }
    </style>
  </template>
</dom-module>```

But with v23 I had to put them in the theme's component folder, like this...

```frontend/themes/default/components$ ls
color-picker-field.css
multiselect-combo-box-input.css
multiselect-combo-box.css
vaadin-app-layout.css
vaadin-button.css
vaadin-checkbox.css
vaadin-combo-box-item.css
vaadin-context-menu-item.css
vaadin-context-menu-list-box.css
vaadin-date-time-picker-custom-field.css
vaadin-date-time-picker-time-text-field.css
vaadin-date-time-picker.css
vaadin-details.css
vaadin-dialog-overlay.css
vaadin-grid.css
vaadin-login-form-wrapper.css
vaadin-menu-bar.css
vaadin-notification-card.css
vaadin-number-field.css
vaadin-password-field.css
vaadin-radio-button.css
vaadin-text-area.css
vaadin-text-field.css```

But this is causing too many files to by retrieved during page load.  Is there a way to put all the shadow dom customizations in one file?

Does the lack of responses mean there is no way to combine them into one file?

Naah, you just managed to write your Q just before end of workday in Finland :slightly_smiling_face: (AND many of us have been on security training today)

There’s a few different ways to avoid the above:

  1. You can use the @CssImport annotation to load your styles instead of the theme folder. There’s some stuff about using the same stylesheet for multiple components at the end of this docs page: https://vaadin.com/docs/v14/flow/styling/importing-style-sheets. It does mean you need to prefix all your selectors with the component name (inside a :host() selector) to scope them to the correct component,e.g. :host(vaadin-button) some-other-selector { ... }

  2. You can use the new ::part() selector to style the internals of components, instead of the /components folder or the above annotation, and you can put that stuff in any stylesheet, so you could even put 100% of your css into styles.css. With that selector, instead of having something like [part~="label"] {...} in vaadin-button.css, you instead have vaadin-button::part(label) in any stylesheet that’s loaded. This limits you to shadow DOM parts that have a part attribute (and parts that are no longer in shadow DOM), but I think you’ll find that’s at least 90% of what you need to style anyway. This will be the recommended way to style components in Vaadin 24 btw (for details, see https://github.com/vaadin/platform/issues/3149)

  3. You don’t actually need separate files for all of those. As an example, vaadin-date-time-picker-time-text-field no longer exists in V23, and vaadin-date-time-picker-time-picker inherits css from vaadin-time-picker so no need to style it separately.

I’ve also never heard of anyone having that problem. Is that on the server or the browser?

@useful-whale thanks for the awesome response. I am going through your suggestions now.

I’ve also never heard of anyone having that problem. Is that on the server or the browser?

It seems like all the .css files in a theme’s component directory are downloaded. If the problem you referring to is why I moved the styles from index.html to theme’s component directory… that was because they were not working from the index.html and the Vaadin docs states that this is how it is done… see the example… https://vaadin.com/docs/latest/styling/custom-theme/styling-components/#example

But its good to hear that there are options. I’ll respond back with the results of trying out your suggestions. Thanks again!!!

@useful-whale Solution 2 is working out great. Amazing. This is so much easier. I’ll keep at it and will respond if I run into problems. And you were right, most of the theming was on parts.

glad to hear it! In V23 the ::part() selector doesn’t work for parts that are inside a nested shadow DOM, but in V24 that will be resolved. Also some things like classnames applied to MenuBar items or Grid cells cannot be targeted that way, but that will also be resolved in V24. We’ll also publish a list of all the part names and other supported selectors for each component early next year.

In any case, it does not sound right that ALL files placed in /components folder are downloaded separately. They should be processed into a bundle on the server and injected into the components’ shadow DOM, and I don’t see any reason why they would be downloaded by the browser separately.

ah, on second thought, I think that is normal in devmode. In a production build they would not be there though, so it’s only an issue to the extent it’s an issue for you while developing.

(I think there was a bug in V23.2.0 affecting this, so being on the latest 23.2.x version is recommended)

@useful-whale thank you for the valuable information. Now i’m looking forward to v24.