Research / Other Theming Issues

Visual Style Complexity

The visual style of Lumo in particular can be complicated in some cases for not much benefit, aiming for visual flair at the cost of simplicity.

For example, the hover and activation effects on many components (button, checkbox, text input) involve both ::before and ::after elements with transforms and transition. That means it is difficult for theme customizations to utilize those pseudo elements for their own purposes, which usually means that they either hide them completely, or don’t try to override the effects.

Baseline Alignment “Hack”

The way the Lumo theme tries to ensure components align vertically as expected is complex and brittle. We should remove it, and make sure that component alignments are good enough by other means, for example, by relying on the browser more and making it easier to use lower-level building blocks which align without extra effort (deconstruct field components).

Inconsistent Custom Properties

Lumo custom properties are inconsistently named, making it harder than necessary to remember them or remember where they should be used.

The “Theme” Attribute

The proprietary theme attribute is almost the same as the standard class attribute, except that it is copied to “sub-components” (another element with shadow DOM) inside the main component’s shadow DOM.

Using the theme attribute is likely not a big issue for most developers, as copy-pasting code from examples is easy enough, and the exact API naming is perhaps not much of a concern. Styling sub-components is a case that needs a solution, though, so without the theme attribute the class attribute would need to be copied to sub-components.

One aspect where the theme attribute is clearly worse than the standard class attribute is the DOM API for manipulating the values. Adding, removing, and toggling class names is very easy through the classList API, whereas with the theme attribute developers have to manually manipulate a space-separated string value. Though, component variants are most often statically defined and not modified at runtime, so this could be an irrelevant point.

CSS selector performance could be an issue to consider, as class selectors are faster than attribute selectors, especially in Safari using global styles (source).

Theme Implementation

CSS custom property names should follow a consistent naming convention.

The theme tokens and component themes pages contain prototype implementations for those.

Themes for standard HTML elements should be delivered as plain .css files, not wrapped inside JavaScript modules. More complex components will still likely want to package their core theme with the JavaScript module, although I would recommend that additional themes such as “Lumo” or “Material” are maintained in plain .css files, and are opt-in by the user on top of the main component JavaScript import.

Importing CSS from JavaScript files should work via standard API: https://web.dev/css-module-scripts/, although it has the limitation of not supporting nested @import statements. I would assume front-end build tools (webpack, Vite) should handle this use case.