In Android 10 and higher, an app can support a Dark theme and automatically change between light and dark app themes according to the system theme. To match the current app theme, web content in WebView can also use light, dark, or default styling.
WebView's behavior interoperates with the
prefers-color-scheme
and
color-scheme
web standards. Whenever possible, if you author the web content that you want
your app to display in WebView, you should define a dark theme for your
website and
implement prefers-color-scheme
so that WebView can match the web content's
theme to your app's theme.
The following table describes how WebView renders web content in your app, depending on the web content's styling and your app's conditions:
App conditions | Web content that uses prefers-color-scheme |
Web content that doesn't use prefers-color-scheme |
---|---|---|
App is using a light theme with
isLightTheme
set to true or not set. |
WebView renders the content with the light theme that the content author has defined. | WebView renders the content with the default styling defined by the content author. |
App is using Force Dark to algorithmically apply a dark theme to the app. | WebView renders the content with the dark theme that the content author has defined. | If allowed by the content author, WebView renders the content with a dark theme that is generated using an algorithm. |
App is using a dark theme with
isLightTheme
set to false and the app doesn't allow algorithmic
darkening for WebView. |
WebView renders the content with the dark theme that the content author has defined. | WebView renders the content with the default styling defined by the content author. |
App is using a dark theme with
isLightTheme
set to false and the app does allow
algorithmic darkening for WebView. |
WebView renders the content with the dark theme that the content author has defined. | If allowed by the content author, WebView renders the content with a dark theme that is generated using an algorithm. |
Content-author styling
An app's
isLightTheme
attribute
indicates if the app's theme is light or dark. WebView always sets
prefers-color-scheme
according to isLightTheme
. If isLightTheme
is true
or not specified, then prefers-color-scheme
is light
; otherwise, it is
dark
.
This means that if the web content uses prefers-color-scheme
and the content
author allows it, the light or dark theme defined by the content author
is always automatically applied to the web content to match the app's theme.
Algorithmic darkening
To cover cases where web content doesn't use
prefers-color-scheme
,
your app can allow WebView, when necessary, to algorithmically apply a dark
theme to web content that it renders.
If your app is using the app-level Force Dark to algorithmically apply a dark theme to your app, see the following section that describes how to allow algorithmic darkening for web content with Force Dark.
If your app is not using Force Dark, how your app specifies when to allow algorithmic darkening in WebView depends on your app's target API level. See the following sections for apps targeting Android 13 or higher and apps targeting Android 12 or lower for details.
Allow algorithmic darkening for web content with Force Dark
If your app is using the app-level Force Dark, WebView applies algorithmic darkening to web content if the following conditions are met:
- The WebView and its parent elements allow Force Dark.
- The current activity theme is marked as light with
isLightTheme
set totrue
. - The web content author doesn't explicitly disable darkening.
- For apps targeting Android 13 (API level 33) or higher, the web content
doesn't use
prefers-color-scheme
. - For apps targeting Android 12 (API level 32) or lower: The app has set
WebView's
forceDarkMode
setting toFORCE_DARK_AUTO
and has set their Force Dark strategy toDARK_STRATEGY_USER_AGENT_DARKENING_ONLY
.
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 mode is provided primarily for backward-compatibility in apps that don't provide their own dark theme. If your app uses Force Dark, we recommend adding support for a dark theme.
Allow algorithmic darkening (apps targeting Android 13 or higher)
For apps that aren't using app-level Force Dark and target Android 13 (API level
33) or higher, use the AndroidX
setAlgorithmicDarkeningAllowed()
method and pass in true
to specify that a WebView should allow algorithmic
darkening. This method has backward compatibility with previous Android
versions.
WebView then applies algorithmic darkening if the following conditions are met:
- The web content doesn't use
prefers-color-scheme
. - The web content author doesn't explicitly disable darkening.
Allow algorithmic darkening (apps targeting Android 12 or lower)
For apps that aren't using app-level Force Dark and target Android 12 (API level
32) or lower, use
FORCE_DARK_ON
to allow algorithmic darkening.
Use FORCE_DARK_ON
together with
FORCE_DARK_OFF
if your app provides its own method for switching between light and dark themes,
such as a toggleable element in the UI or an automatic time-based selection.
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(...); }
If your app relies on detecting changes to system preferences, your app should
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
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { Configuration.UI_MODE_NIGHT_YES -> { WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_ON) } Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> { WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_OFF) } else -> { // } } }
Java
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) { case Configuration.UI_MODE_NIGHT_YES: WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_ON); break; case Configuration.UI_MODE_NIGHT_NO: case Configuration.UI_MODE_NIGHT_UNDEFINED: WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_OFF); break; } }
Customize dark theme handling
You can also use the
ForceDarkStrategy API
in AndroidX 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, your app can use either web theme darkening or user-agent darkening:
- Web theme darkening: Web developers might apply
@media (prefers-color-scheme: dark)
to control web page appearance in 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 tofalse
.
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 the<meta name="color-scheme" content="dark light">
tag as optional, Android WebView's default mode requires the meta tag to honor the web page'sprefers-color-scheme
media queries. You can use WebViews withDARK_STRATEGY_WEB_THEME_DARKENING_ONLY
mode, in which case WebView always applies media queries even if the tag is omitted.However, we recommend web developers add
<meta name="color-scheme" content="dark light">
tag to their websites to ensure that 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 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