Blog

Toggle between light and dark theme in Vaadin Flow

By  
Marcus Hellberg
Marcus Hellberg
·
On Feb 23, 2023 7:15:00 AM
·

Updated to Vaadin Flow 24 on 2023-02-23

A common question we get from Vaadin developers is how to switch on the dark theme variant dynamically. In this tutorial, I’ll show you how to turn it on permanently, and how to dynamically apply the dark variant to the entire application or only parts of it.

Option 1: Turn on Dark mode permanently

The first and easiest way to switch to the dark theme is setting the Lumo.DARK variant in the @Theme annotation on the application class. 

Application.java
 
// Change the value to match your project
@Theme(value = "my-project-name", variant = Lumo.DARK)
public class Application implements AppShellConfigurator {
//...
}
Setting a dark theme with annotation

Option 2: Change between light and dark theme on the fly

The second option is to allow your users to decide if they want the light or the dark theme variant. To do this, we need to add a button that sets the appropriate Lumo.DARK theme variant on the <html> element in the browser.

MainView.java
public class ThemeView extends VerticalLayout {

public ThemeView() {
var themeToggle = new Checkbox("Dark theme");
themeToggle.addValueChangeListener(e -> {
setTheme(e.getValue());
});

add(themeToggle);
}

private void setTheme(boolean dark) {
        var js = "document.documentElement.setAttribute('theme', $0)";

        getElement().executeJs(js, dark ? Lumo.DARK : Lumo.LIGHT);
    }
}
  1. Get the list of currently applied theme variants

  2. Toggle Lumo.DARK

Option 3: Switch between light and dark theme for a single component

You can also apply the theme change to specific components instead of the entire application. To do that, use the theme list for that component instead of the UI. The change will apply to that component and all its children.

Note
It is only possible to have Lumo.DARK children inside light-themed areas. It is not possible to make a child of a component with a dark theme to use Lumo.LIGHT.
MainView.java
@Route
public class MainView extends VerticalLayout {

public MainView() {
H1 h1 = new H1("Hello darkness");
FormComponent form = new FormComponent();

Button toggleButton = new Button("Toggle dark theme", click -> {
ThemeList themeList = form.getElement().getThemeList();

if (themeList.contains(Lumo.DARK)) {
themeList.remove(Lumo.DARK);
} else {
themeList.add(Lumo.DARK);
}
});

add(
toggleButton,
h1,
form
);
}
}
  1.  

Toggle component theme between light and dark.

Summary

In this tutorial, you learned how to use the dark Lumo theme variant. You can either enable the dark mode permanently with the @Theme annotation’s Lumo.DARK variant or dynamically by adding or removing the theme variant on the UI or component you want to change.

Source code on GitHub.

Marcus Hellberg
Marcus Hellberg
Marcus is the VP of Developer Relations at Vaadin. His daily work includes everything from writing blogs and tech demos to attending events and giving presentations on all things Vaadin and web-related. You can reach out to him on Twitter @marcushellberg.
Other posts by Marcus Hellberg