Aura: Change Individual Parts to Light/Dark Mode

I am currently implementing dark/light theme variants with Aura, based on company design tokens and custom styling.

My current setup looks like this:

  • tokens.css defines base tokens such as color scales, spacing, typography, radius, etc.
  • theme.css maps these tokens to semantic variables like surface, text, background, accent,error, success, etc. for both light and dark variants
  • styles.css uses these semantic variables to override Aura defaults
  • tailwind-custom.css also consumes the semantic variables from theme.css and is used for utility-based styling with Tailwind

So the idea is:

tokens → semantic theme variables → Aura overrides + Tailwind usage

Now I am facing the following problem.

I want to style a specific part of the application, for example only the drawer (without the navbar), with dark mode styling, while the rest of the application stays in light mode.

Additionally, if the whole application is already in dark mode, I still want full control over rendering specific sections explicitly in light or dark mode.

In the Vaadin Create 2025 presentation Aura & new theming in Vaadin 25 around minute 29, it is mentioned that individual sections can be rendered in light or dark mode independently.

Question 1

How can I render a specific area (for example Drawer, VerticalLayout, or another container) in a fixed color scheme independently from the global theme?

The goal is to render that section always in dark or always in light mode without redefining all theme-specific variables again for that area.

What is the recommended Aura-compatible approach for this?

Question 2

Does the following theme structure align with current Vaadin 25 + Aura best practices, or should this generally be structured differently?

src/main/resources/META-INF/resources/

├── tokens.css
│ Base design tokens
│ (color scales, spacing, typography, radius, shadows, etc.)

├── theme.css
│ Semantic theme variables
│ (surface, text, background, accent, interaction states)
│ mapped from tokens for light/dark variants

├── styles.css
│ Aura variable overrides
│ and global application styling

src/main/frontend/

└── tailwind-custom.css
for utility styling

Example css

tokens.css

:root {
    --my-neutral-0: #ffffff;
    --my-neutral-50: #f8fafc;
    --my-neutral-900: #111827;

    --my-accent-400: #818cf8;
    --my-accent-500: #4f46e5;
}

theme.css

:root {
    --my-background-color: var(--my-neutral-50);
    --my-accent-color: var(--my-accent-500);

    color-scheme: light;
}

:root[theme~="dark"] {
    --my-background-color: var(--my-neutral-900);
    --my-accent-color: var(--my-accent-400);

    color-scheme: dark;
}

styles.css

html {
    --aura-background-color-light: var(--my-background-color);
    --aura-background-color-dark: var(--my-background-color);
    --aura-accent-color-light: var(--my-accent-color);
    --aura-accent-color-dark: var(--my-accent-color);
    --aura-app-layout-inset: 0px;;
}

tailwind-custom.css

@theme {
    --color-background: var(--my-background-color);
    --color-accent: var(--my-accent-color);
}

Is this a reasonable structure, or is there a more standard/recommended approach for Aura in Vaadin 25?

Regarding:

In the Vaadin Create 2025 presentation Aura & new theming in Vaadin 25 around minute 29, it is mentioned that individual sections can be rendered in light or dark mode independently.

It looks like scoped color scheme support is limited to the App Layout component’s content area, and notifications. This documentation sections explains how to configure those: How to use color properties of the Aura theme in Vaadin.

AFAIK there is no support to modify the color scheme of arbitrary elements so that it automatically recalculates all dependent colors to respect the custom scheme on that level.

If you think that you have a specific use case for this, feel free to open a feature request here: Issues · vaadin/web-components · GitHub

Currently reviewing a docs update related to this, and it now mentions additional ways to use a scoped color scheme. The list of selectors that allow changing the color scheme is this one: web-components/packages/aura/src/color.css at c8681c44ee581fe51958ca1ae306e8f0d55c6353 · vaadin/web-components · GitHub

So it’s supported on a number of Vaadin components and with some CSS classes, however all of these classes modify the accent color as a side effect from what I see.

Edit: Looks like this combination should do it:

  • Add aura-accent-color class
  • Apply color-scheme: dark style
  • Apply background: var(--aura-background-color) to get correct background color

Thanks for the question! I appreciate any interest there is towards Aura and CSS in general :slight_smile:

At the time of Vaadin Create last year, Aura did allow you to set the color-scheme at any point in the DOM hierarchy. Unfortunately, due to rendering performance issues (mainly with <vaadin-grid> or components with a lot of elements), we had to register some of the base style custom properties with the native CSS <color> type (see source), which alters how the light-dark() colors are evaluated on the nodes.

The color value is evaluated on certain nodes in the DOM (the selector list where the property is defined dictates that), and the computed color value is then inherited by child nodes. Changing the color scheme on the child elements doesn’t change the inherited color value. The color scheme needs to be changed on a node that matches one of the selectors where the color properties are declared (see the color.css source Sascha linked).

Regarding your stylesheet structure, it looks fine otherwise, but you shouldn’t use [theme~="dark"] to redefine the semantic tokens for the dark color scheme. Aura relies on the native color-scheme property and therefore the use of the native light-dark() function to choose between the correct color between light and dark modes.

To also make it possible to redefine Aura’s color-scheme-specific properties (i.e., -light and -dark suffixed ones), you either need similar semantic tokens in your theme.css, or you use the “raw” values from your tokens.css stylesheet.

For example:

theme.css

:root {
  --my-background-color-light: var(--my-neutral-50);
  --my-background-color-dark: var(--my-neutral-900);
  --my-background-color: light-dark(var(--my-background-color-light), var(--my-background-color-dark));
}

styles.css

:root {
  --aura-background-color-light: var(--my-background-color-light);
  --aura-background-color-dark: var(--my-background-color-dark);
}

Or:
styles.css

:root {
  --aura-background-color-light: var(--my-neutral-50);
  --aura-background-color-dark: var(--my-neutral-900);
}

You can still have a [theme~="dark"] { color-scheme: dark; } rule in your stylesheet to override the color scheme, but like we already pointed out, that has limited usability, unfortunately.

The workaround Sascha outlined should work, with one addition: you also need to set the text color with color: var(--vaadin-text-color).

For example, to override a vertical layout to always use the dark color scheme:

<vaadin-vertical-layout class="aura-accent-color dark"></vaadin-vertical-layout>
.dark {
  color-scheme: dark;
  background: var(--aura-background-color);
  color: var(--vaadin-text-color);
}

The aura-accent-color classname does have the side effect of overriding the --aura-accent-color properties back to the global defaults/initial value. We can consider adding a classname to Aura that recomputes the color values but doesn’t have other side effects.