On devices running Android 10 (API level 29) and higher, app users can set the
device to light theme or dark
theme at the OS level. WebView
applies these themes according to a ForceDark
setting,
which can have three states:
FORCE_DARK_AUTO
,
FORCE_DARK_ON
,
and
FORCE_DARK_OFF
.
You can use the FORCE_DARK_ON
and FORCE_DARK_OFF
states when your application provides its own
method for switching, such as a toggle in the UI or an automatic time-based
selection. See DayNight theme for another use case that requires
you to provide a toggle UI element.
To check whether the feature is supported, add the following lines of code
wherever you configure your WebView object, such as in Activity#onCreate
:
Kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { WebSettingsCompat.setForceDark(...) }
Java
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { WebSettingsCompat.setForceDark(...); }
Use FORCE_DARK_AUTO mode
FORCE_DARK_AUTO
mode is applied if the following conditions are met:
- The WebView and its parent elements allow force dark.
- The current activity theme is marked as light.
WebView and all its parents can allow force dark using
View.setForceDarkAllowed()
.
The default value is taken from the setForceDarkAllowed()
attribute of the
Android theme, which must also be set to true
.
FORCE_DARK_AUTO
mode is provided primarily for backward-compatibility in apps
that don't provide their own dark theme. We recommend using AppCompat.DayNight
to explicitly support a dark theme. Listen for theme changes and toggles between
FORCE_DARK_ON
and FORCE_DARK_OFF
, such as when using Theme.Material.Light
.
<style name="AppDayNightTheme" parent="Theme.AppCompat.DayNight">
<item name="android:forceDarkAllowed">true</item>
<item name="android:isLightTheme">true</item>
</style>
Use DayNight themes
DayNight
themes
require you to use the FORCE_DARK_ON
and FORCE_DARK_OFF
Webkit states, and
to provide explicit theme-changing functionality, such as through a toggle UI
element or time-based switching. If your app relies on the system preference,
you must explicitly listen for theme changes and apply these to WebView with
FORCE_DARK_ON
and FORCE_DARK_OFF
states.
The following code snippet shows how to change the theme format.
Kotlin
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { Configuration.UI_MODE_NIGHT_YES -> { //enable force dark } Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> { //disable force dark } else -> { // } }
Java
switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) { case Configuration.UI_MODE_NIGHT_YES: // enable force dark break; case Configuration.UI_MODE_NIGHT_NO: case Configuration.UI_MODE_NIGHT_UNDEFINED: // disable force dark break; }
Customize dark theme
To provide the dark experience in all cases, by default WebView tries to determine whether a web page provides dark mode by itself and applies automatic darkening otherwise.
WebView can't differentiate based solely on the presence of the media query, so
it needs a color-scheme
meta tag with dark
value as indication that a web
page has its own dark theme. To prevent double-darkening (that is, applying
color inversion on top of media query customization) WebView evaluates
@media (prefers-color-scheme: dark)
to false in this mode.
The ForceDarkStrategy
API,
exposed only within AndroidX, allows you to control how darkening is applied to
a given WebView. This API is applicable only if force dark is set to
FORCE_DARK_ON
or FORCE_DARK_AUTO
.
Using the API, you can choose between web theme darkening and user-agent darkening:
- Web theme darkening: Web developers might apply
@media (prefers-color-scheme: dark)
to control web page appearance in the dark mode. WebView renders content according to these settings. For more about web theme darkening, see the specification. - User-agent darkening: the WebView automatically inverts colors of the web
page. If you use user-agent darkening, the
@media (prefers-color-scheme: dark)
query evaluates to false.
To choose between the two strategies, use the following API:
Kotlin
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { WebSettingsCompat.setForceDarkStrategy(...) }
Java
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { WebSettingsCompat.setForceDarkStrategy(...); }
The supported strategy options are:
DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING
: This is the default option. While most browsers treat thecolor-scheme
meta tag as optional, Android WebView in default mode requires a meta tag to honor the web page'sprefers-color-scheme
media queries. You may optionally use WebViews withDARK_STRATEGY_WEB_THEME_DARKENING_ONLY
mode, in which case WebView will always apply media queries.However, we recommend web developers add
color-scheme
meta tag to their websites to ensure that their content renders correctly in WebViews with the default configuration.DARK_STRATEGY_USER_AGENT_DARKENING_ONLY
: Called user-agent darkening, the WebView ignores any web page darkening and applies automatic darkening.
If your app shows first-party web content that you've customized with the
prefers-color-scheme
media query, we recommend
DARK_STRATEGY_WEB_THEME_DARKENING_ONLY
to ensure WebView uses the custom theme.
For an example of dark theme applied, see the WebView demo on GitHub