platform
platform copied to clipboard
Theming system renewal
Description
A simplification of the theme/styling system in Vaadin, to bring it closer to normal/native web development, and minimize Vaadin-specific peculiarities, while keeping migration from earlier versions as painless as possible.
Tier
Free
License
Apache 2.0
Motivation
Background
Mainly due to shadow DOM styling in Vaadin components, Vaadin themes have traditionally needed to be more than just stylesheets. This has required various Vaadin-specific concepts and APIs that new users have had to learn, regardless of their prior knowledge of web development and CSS.
Problem
With the introduction of 100% light-DOM styling in V24, and developments in web standards, those Vaadin-specific features are no longer necessary, but are still retained, and in some cases required, in V24, keeping the learning threshold for new users higher then necessary, and imposing certain limitations on and complications on styling Vaadin applications.
Solution
The entire "theme" concept, with its various APIs, folder structures, and special files, is retired in favor of "just normal stylesheets":
-
The special
frontend/themesfolder, and thecomponentssub-folder for css shadow-DOM injection, is deprecated (but still supported).- Instead, stylesheets can be placed anywhere in the
frontendfolder. - As in earlier versions, stylesheets can import other stylesheets through native css
@importrules.
- Instead, stylesheets can be placed anywhere in the
-
The
@Themeannotation is deprecated (but still supported);- Instead, one or more stylesheets are loaded through an annotation in Flow (e.g.
@CssImport("styles.css")) and mechanisms native to HTML, CSS and React (e.g.@import url("morestyles.css")in CSS). - Developers can choose to apply their own CSS on top of Lumo, the new Aura styles, or neither, by importing (or omitting) the corresponding stylesheet (e.g.
@import("@vaadin/lumo-styles/lumo.css")) - The Light and Dark Lumo variants (and corresponding variants of Aura) can be applied with a single line of CSS (
color-scheme: dark), either statically, or based on the user's system settings.
- Instead, one or more stylesheets are loaded through an annotation in Flow (e.g.
-
The
theme.jsonconfiguration file is deprecated (but still supported, with the exception of thelumoImportsproperty).- Instead of selecting included Lumo modules with the
lumoImportsproperty intheme.json, all Lumo styles can be loaded by importing a single stylesheet (e.g.@import url("@vaadin/lumo-styles/lumo.css")). - Subsets of Lumo and Aura can be loaded via other sub-stylesheets if needed (e.g.
@import url("@vaadin/lumo-styles/colors.css")or@import url("@vaadin/lumo-styles/components/vaadin-button.css")). - Instead of the
cssImportandassetsproperties intheme.json, stylesheets and other frontend assets can be used in stylesheets using the same syntax as seen above. - Instead of the
parentproperty intheme.json, parent themes can simply be loaded as normal stylesheets.
- Instead of selecting included Lumo modules with the
-
The
themeForparameter of the@CssImportannotation (for shadow-DOM injection) is deprecated (but still supported);- Already as of V24, component styling can be done entirely with normal "light DOM" CSS.
-
The special
document.cssfile (for loading styles into the document root in embedded components) is removed as no longer necessary;- Instead,
WebComponentExporterautomatically copies any@font-facedeclarations in embedded stylesheets into the document root. (No other use cases fordocument.cssare needed in modern browsers.)
- Instead,
Example of applying your own CSS on top of Lumo in V25 Flow:
Your Flow application class:
// Loads the stylesheet frontend/my-styles.css
@CssImport("my-styles.css");
The my-styles.css stylesheet:
@import("@vaadin/lumo-styles/lumo.css");
vaadin-button {
background: #ccc;
}
Notes
- This removes the need for theme-specific JS modules, which means that Hilla apps can simply load the npm package for a component instead of the theme-specific module in it.
- The Material theme is no longer supported. No replacement is currently planned.
- Lumo component styles will still be based on shadow-DOM CSS injection in order to avoid breaking changes to existing applications, but they will be loaded like normal stylesheets.
- The shadow-DOM injection mechanisms in the
componentsfolder can still be used by toggling a feature flag and using the legacy@Themeannotation andthemesfolder structure to load a theme the legacy way.
Requirements
- [x] Shadow-DOM CSS injection based on media query (e.g.
@media vaadin-button {...}to load styles into the shadow DOM ofvaadin-button). - [x] Support for loading bundled CSS from an npm package with
@CssImport. - [ ] Lumo refactored
- [ ] to normal CSS stylesheets.
- [ ] to use the
@mediato inject component shadow DOM styles. - [ ] to support light/dark variants through
color-schemeCSS property. - [ ] to be based on the new base component styles
- [ ] Flow API for loading frontend assets (like stylesheets, images, etc) from npm packages (e.g. through additional parameters for the
@NpmPackageannotation). - [ ] Feature flag for enabling shadow DOM CSS injection through the
componentstheme sub-folder. - [ ]
WebComponentExporterautomatically copies@font-facedeclarations into document root. - [x] Custom themes can be packaged into a JAR to be loaded into an application before its own styles.
- [ ]
@Theme,themeForandincludeparameter deprecated. - [ ] Documentation
Nice-to-haves
- [x] Support for loading assets from npm packages with the CSS
url()syntax, for stylesheets and other assets used via CSS. (Otherwise stylesheets from NPM packages, including Lumo and Aura, will need to be done with@CssImportetc.
Risks, limitations and breaking changes
Risks
Nothing specific expected at this point.
Limitations
Material theme will no longer be supported.
Breaking changes
These changes are not expected to be breaking for most Vaadin applications. Below are some cases where small adjustments will be needed:
- Applications without a
@Themeannotation must explicitly load Lumo styles (e.g. by adding a single@CssImport("@vaadin/lumo/lumo.css")annotation). - Applications using the Material theme will need to stay on V24, refactor their styling to be based on Lumo or Aura, or build their own Material theme.
Materials
See PRDs for
Metrics
TBD
Pre-implementation checklist
- [ ] Estimated (estimate entered into Estimate custom field)
- [ ] Product Manager sign-off
- [ ] Engineering Manager sign-off
Pre-release checklist
- [ ] Documented (link to documentation provided in sub-issue or comment)
- [ ] UX/DX tests conducted and blockers addressed
- [ ] Approved for release by Product Manager
Security review
None