WebView のウェブ コンテンツを暗くする

Android 10 以降では、アプリはダークモードをサポートし、システムテーマに応じてライトモードとダークモードを自動的に切り替えることができます。現在のアプリのテーマに合わせて、WebView のウェブ コンテンツでも、ライト、ダーク、デフォルトのスタイルを使用できます。

WebView の動作は、prefers-color-scheme ウェブ標準と color-scheme ウェブ標準と相互運用されます。可能であれば、アプリで WebView に表示するウェブ コンテンツを作成する場合、ウェブサイトのダークモードを定義し、prefers-color-scheme を実装して、WebView がウェブ コンテンツのテーマをアプリのテーマと一致させられるようにする必要があります。

次の表に、ウェブコンテンツのスタイルとアプリの状態に応じて、WebView がアプリ内のウェブコンテンツをレンダリングする方法を示します。

アプリの条件 prefers-color-scheme を使用するウェブ コンテンツ prefers-color-scheme を使用しないウェブ コンテンツ
アプリがライトモードを使用しており、isLightThemetrue に設定されているか、設定されていません。 WebView は、コンテンツ作成者が定義したライトモードでコンテンツをレンダリングします。 WebView は、コンテンツの作成者が定義したデフォルトのスタイルでコンテンツをレンダリングします。
アプリは、フォースダークを使用して、アプリにアルゴリズムによってダークモードを適用します。 WebView は、コンテンツの作成者が定義したダークモードでコンテンツをレンダリングします。 コンテンツの作成者が許可している場合、WebView はアルゴリズムを使用して生成されたダークモードでコンテンツをレンダリングします。
アプリは isLightThemefalse に設定されたダークモードを使用しており、WebView のアルゴリズムによるダークモードを許可していません WebView は、コンテンツ作成者が定義したダークモードでコンテンツをレンダリングします。 WebView は、コンテンツの作成者が定義したデフォルトのスタイルでコンテンツをレンダリングします。
アプリがダークモードを使用していて、isLightThemefalse に設定されており、アプリが WebView のアルゴリズムによるダークニング許可している WebView は、コンテンツの作成者が定義したダークモードでコンテンツをレンダリングします。 コンテンツ作成者が許可している場合、WebView はアルゴリズムを使用して生成されたダークモードでコンテンツをレンダリングします。

コンテンツ作成者のスタイル設定

アプリの isLightTheme 属性は、アプリのテーマがライトモードかダークモードかを指定します。WebView は常に isLightTheme に従って prefers-color-scheme を設定します。isLightThemetrue であるか指定されていない場合、prefers-color-schemelight です。それ以外の場合は dark です。

つまり、ウェブ コンテンツで prefers-color-scheme が使用され、コンテンツの作成者が許可している場合、コンテンツの作成者が定義したライトモードまたはダークモードが常にアプリのテーマに合わせてウェブ コンテンツに自動的に適用されます。

アルゴリズムによる暗くする

ウェブ コンテンツが prefers-color-scheme を使用していないケースに対応するため、アプリでは、必要に応じて WebView がレンダリングするウェブ コンテンツにダークテーマをアルゴリズムによって適用できるようにすることができます。

アプリでアプリレベルのフォースダークを使用して、アルゴリズムによってアプリにダークモードを適用している場合は、次のセクションで説明するフォースダークを使用してウェブ コンテンツのアルゴリズムによるダークモード化を許可する方法をご覧ください。

アプリがフォースダークを使用していない場合、WebView でアルゴリズムによる暗化を許可するタイミングをアプリで指定する方法は、アプリのターゲット API レベルによって異なります。詳しくは、Android 13 以降をターゲットとするアプリAndroid 12 以前をターゲットとするアプリをご覧ください。

フォースダークを使用してウェブ コンテンツのアルゴリズムによるダーク化を許可する

アプリがアプリレベルのフォースダークを使用している場合、WebView は次の条件が満たされると、アルゴリズムによるダークニングをウェブ コンテンツに適用します。

  • WebView とその親要素は強制ダークを許可します。
  • 現在のアクティビティ テーマはライトとしてマークされ、isLightThemetrue に設定されています。
  • ウェブ コンテンツの作成者はダークニングを明示的に無効にしていません。
  • Android 13(API レベル 33)以降をターゲットとするアプリの場合、ウェブ コンテンツは prefers-color-scheme を使用しません。
  • Android 12(API レベル 32)以下をターゲットとするアプリの場合: WebView の forceDarkMode 設定FORCE_DARK_AUTO に、フォースダーク戦略が DARK_STRATEGY_USER_AGENT_DARKENING_ONLY に設定されている。

WebView とそのすべての親は、View.setForceDarkAllowed() を使用して強制ダークモードを許可できます。デフォルト値は、Android テーマの setForceDarkAllowed() 属性から取得されます。この属性も true に設定する必要があります。

フォースダークモードは、独自のダークモードを提供するアプリの下位互換性を確保するために主に提供されています。アプリでフォースダークを使用している場合は、ダークモードのサポートを追加することをおすすめします。

アルゴリズムによるダークニングを許可する(Android 13 以降をターゲットとするアプリ)

アプリレベルの強制ダークモードを使用しておらず、Android 13(API レベル 33)以降をターゲットとするアプリの場合は、AndroidX の setAlgorithmicDarkeningAllowed() メソッドを使用して true を渡し、WebView でアルゴリズムによるダークモードを許可するように指定します。このメソッドには、以前のバージョンの Android との下位互換性があります。

WebView は、次の条件を満たす場合にアルゴリズムによる暗くする処理を適用します。

  • ウェブ コンテンツで prefers-color-scheme が使用されていない。
  • ウェブ コンテンツの作成者はダークニングを明示的に無効にしていません。

アルゴリズムによるダークニングを許可する(Android 12 以前をターゲットとするアプリ)

アプリレベルの強制ダークモードを使用しておらず、Android 12(API レベル 32)以前をターゲットとするアプリの場合は、FORCE_DARK_ON を使用してアルゴリズムによるダークモードを有効にします。

アプリにライトモードとダークモードを切り替える独自の方法(UI の切り替え可能な要素や時間ベースの自動選択など)がある場合は、FORCE_DARK_ONFORCE_DARK_OFF を併用します。

この機能がサポートされているかどうかを確認するには、WebView オブジェクトを構成する場所(Activity.onCreate など)に次のコード行を追加します。

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...);
}

アプリがシステム設定の変更を検出する場合は、テーマの変更を明示的にリッスンし、FORCE_DARK_ONFORCE_DARK_OFF の状態を使用して WebView に適用する必要があります。

次のコード スニペットは、テーマの形式を変更する方法を示しています。

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;
    }
}

ダークモードの処理をカスタマイズする

AndroidX の ForceDarkStrategy API を使用して、特定の WebView にダークモードを適用する方法を制御することもできます。この API は、フォースダークが FORCE_DARK_ON または FORCE_DARK_AUTO に設定されている場合にのみ適用されます。

API を使用すると、アプリでウェブテーマの暗化またはユーザー エージェントの暗化のいずれかを使用できます。

  • ウェブテーマのダークモード: ウェブ デベロッパーは @media (prefers-color-scheme: dark) を適用して、ダークモードでのウェブページの外観を制御できます。WebView は、これらの設定に従ってコンテンツをレンダリングします。ウェブテーマの暗化の詳細については、仕様をご覧ください。
  • ユーザー エージェントのダークモード: WebView はウェブページの色を自動的に反転します。ユーザー エージェントの暗くする機能を使用する場合、@media (prefers-color-scheme: dark) クエリは false と評価されます。

2 つの戦略のどちらを選択するかは、次の API を使用して指定します。

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...);
}

サポートされている戦略オプションは次のとおりです。

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: デフォルトのオプションです。ほとんどのブラウザでは <meta name="color-scheme" content="dark light"> タグは省略可能ですが、Android WebView のデフォルト モードでは、ウェブページの prefers-color-scheme メディアクエリを尊重するメタタグが必要です。WebView は DARK_STRATEGY_WEB_THEME_DARKENING_ONLY モードで使用できます。この場合、タグが省略されていても、WebView は常にメディアクエリを適用します。

    ただし、デフォルトの構成で WebView でコンテンツが正しくレンダリングされるように、<meta name="color-scheme" content="dark light"> タグをウェブサイトに追加することをおすすめします。

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: 「ユーザー エージェントによるダークニング」と呼ばれるもので、WebView はウェブページのダークニングを無視し、自動ダークニングを適用します。

prefers-color-scheme メディアクエリでカスタマイズしたファーストパーティ ウェブ コンテンツをアプリに表示する場合は、DARK_STRATEGY_WEB_THEME_DARKENING_ONLY を使用して WebView でカスタムテーマが使用されるようにすることをおすすめします。

ダークテーマが適用される例については、GitHub の WebView デモをご覧ください。