カラーパターンの CSS プロパティと対応するメタタグにより、ダークモードのデフォルトのスタイル設定を改善

color-scheme CSS プロパティと対応するメタタグを使用すると、デベロッパーはユーザー エージェント スタイルシートのテーマ固有のデフォルトにページをオプトインできます。

背景

prefers-color-scheme ユーザー設定メディア機能

prefers-color-scheme ユーザー設定メディア機能を使用すると、デベロッパーはページの見た目を完全に制御できます。ダークモードについて詳しくない場合は、prefers-color-scheme: Hello darkness, my old friend(暗闇よ、我が友よ)という記事をご覧ください。この記事では、素晴らしいダークモード エクスペリエンスの作成について私が知っていることをすべてまとめています。

記事で簡単に触れただけだったパズルのピースの 1 つに、color-scheme CSS プロパティと、同じ名前の対応するメタタグがあります。どちらも、ページをユーザー エージェント スタイルシートのテーマ固有のデフォルト(フォーム コントロール、スクロールバー、CSS システムカラーなど)にオプトインできるようにすることで、デベロッパーの作業を容易にします。同時に、この機能により、ブラウザが独自の変換を適用することも防ぎます。

ブラウザ サポート

prefers-color-scheme

Browser Support

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 67.
  • Safari: 12.1.

Source

color-scheme

Browser Support

  • Chrome: 81.
  • Edge: 81.
  • Firefox: 96.
  • Safari: 13.

Source

ユーザー エージェント スタイルシート

説明を続ける前に、ユーザー エージェント スタイルシートについて簡単に説明します。ほとんどの場合、ユーザー エージェント(UA)という言葉は、ブラウザの言い換えと考えることができます。UA スタイルシートは、ページのデフォルトの外観を決定します。UA スタイルシートは、その名のとおり、問題の UA に依存するものです。Chrome(および Chromium)の UA スタイルシートを見て、FirefoxSafari(および WebKit)と比較してみてください。通常、UA スタイルシートはほとんどの点で一致しています。たとえば、リンクを青色、一般的なテキストを黒色、背景色を白色にするという点は共通していますが、フォーム コントロールのスタイル設定など、重要な(場合によっては煩わしい)違いもあります。

WebKit の UA スタイルシートと、ダークモードに関する処理について詳しく見てみましょう。(スタイルシートで「dark」を全文検索します)。 スタイルシートによって提供されるデフォルトは、ダークモードがオンかオフかによって変化します。たとえば、:matches 疑似クラスと、-apple-system-control-background などの WebKit 内部変数、WebKit 内部プリプロセッサ ディレクティブ #if defined を使用した CSS ルールは次のようになります。

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

上記の color プロパティと background-color プロパティには、標準以外の値がいくつかあります。text-apple-system-control-background も有効な CSS カラーではありません。これらは WebKit 内部のセマンティック カラーです。

CSS には、標準化されたセマンティック システム カラーがあります。これらは、CSS Color Module Level 4 で指定されています。たとえば、Canvas<canvas> タグと混同しないようにしてください)はアプリのコンテンツやドキュメントの背景用ですが、CanvasText はアプリのコンテンツやドキュメントのテキスト用です。この 2 つはセットで、単独で使用すべきではありません。

UA スタイルシートは、独自のシステムカラーまたは標準化されたセマンティック システムカラーを使用して、HTML 要素のデフォルトのレンダリング方法を決定できます。オペレーティング システムがダークモードに設定されている場合、またはダークテーマを使用している場合、CanvasText(または text)は条件付きで白に設定され、Canvas(または -apple-system-control-background)は黒に設定されます。UA スタイルシートは、次の CSS を一度だけ割り当て、ライトモードとダークモードの両方をカバーします。

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

color-scheme CSS プロパティ

CSS Color Adjustment Module Level 1 仕様では、ユーザー エージェントによる自動色調整のモデルと制御が導入されています。これは、ダークモード、コントラスト調整、特定の希望するカラースキームなどのユーザー設定を処理することを目的としています。

ここで定義されている color-scheme プロパティを使用すると、要素はどのカラースキームでレンダリングされるのが適切かを示すことができます。これらの値はユーザーの設定とネゴシエートされ、選択されたカラーパターンが、フォーム コントロールやスクロールバーのデフォルトの色、CSS システムカラーの使用値など、ユーザー インターフェース(UI)に影響します。現在サポートされている値は、以下のとおりです。

  • normal: 要素がカラーパターンを認識していないため、ブラウザのデフォルトのカラーパターンで要素をレンダリングする必要があることを示します。

  • [ light | dark ]+: 要素がリストされたカラースキームを認識して処理できることを示し、それらの間の優先順位を表します。

このリストでは、light は明るい背景色と暗い前景色を持つ明るい配色を表し、dark はその逆の暗い背景色と明るい前景色を持つ配色を表します。

すべての要素について、カラーパターンでレンダリングすると、要素のブラウザ提供の UI で使用される色がカラーパターンの意図と一致するはずです。たとえば、スクロールバー、スペルチェックの下線、フォーム コントロールなどです。

:root 要素では、カラーパターンを使用したレンダリングは、キャンバスのサーフェス色(つまり、グローバルな背景色)、color プロパティの初期値、システムカラーの使用値にも影響を与える必要があり、ビューポートのスクロールバーにも影響を与える必要があります。

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

color-scheme メタタグ

color-scheme CSS プロパティを適用するには、まず CSS をダウンロード(<link rel="stylesheet"> 経由で参照されている場合)して解析する必要があります。ユーザー エージェントが目的のカラースキームでページ背景をすぐにレンダリングできるように、<meta name="color-scheme"> 要素で color-scheme 値を指定することもできます。

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

color-schemeprefers-color-scheme の組み合わせ

メタタグと CSS プロパティ(:root 要素に適用した場合)は最終的に同じ動作になるため、ブラウザが優先スキームをより早く採用できるように、メタタグでカラースキームを指定することを常におすすめします。

絶対ベースライン ページでは追加の CSS ルールは必要ありませんが、一般的には常に color-schemeprefers-color-scheme を組み合わせる必要があります。たとえば、WebKit と Chrome で従来のリンクの青色 rgb(0,0,238) に使用される WebKit 独自の CSS 色 -webkit-link は、黒い背景ではコントラスト比が 2.23:1 と不十分で、WCAG AA と WCAG AAA の両方の要件を満たしていません。

この問題を解決するため、ChromeWebKitFirefox のバグと、HTML 標準のメタ問題をオープンしました。

prefers-color-scheme との相互作用

color-scheme CSS プロパティと、prefers-color-scheme ユーザー設定メディア特性に対応するメタタグの相互作用は、最初はわかりにくいかもしれません。実際、両者は非常にうまく連携しています。最も重要なことは、color-scheme はデフォルトの外観を排他的に決定するのに対し、prefers-color-scheme はスタイル設定可能な外観を決定するということです。これを明確にするため、次のページを想定します。

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

ページのインライン CSS コードでは、一般的なケースでは <fieldset> 要素の background-colorgainsboro に設定し、prefers-color-scheme ユーザー設定メディア特性に従ってユーザーが dark カラースキームを希望する場合は darkslategray に設定します。

<meta name="color-scheme" content="dark light"> 要素により、ページはブラウザに、ダークモードとライトモードをサポートしており、ダークモードを優先することを伝えます。

オペレーティング システムがダークモードに設定されているかライトモードに設定されているかに応じて、ユーザー エージェント スタイルシートに基づいて、ページ全体が暗い背景に明るい文字で表示されるか、その逆になります。段落テキストやページの背景色を変更するために、デベロッパーが提供する追加の CSS は必要ありません

<fieldset> 要素の background-color が、ページ上のデベロッパー提供のインライン スタイルシートのルールに従って、ダークモードが有効かどうかによってどのように変化するかを確認します。gainsboro または darkslategray のいずれかです。

ライトモードのページ。
ライトモード: デベロッパーとユーザー エージェントが指定したスタイル。 ユーザー エージェント スタイルシートに従って、テキストは黒、背景は白になります。インラインのデベロッパー スタイルシートに従って、<fieldset> 要素の background-colorgainsboro になります。
ダークモードのページ。
ダークモード: デベロッパーとユーザー エージェントが指定したスタイル。 ユーザー エージェント スタイルシートに従って、テキストは白、背景は黒になります。インラインのデベロッパー スタイルシートに従って、<fieldset> 要素の background-colordarkslategray になります。

<button> 要素の表示は、ユーザー エージェントのスタイルシートによって制御されます。colorButtonText システムカラーに設定され、background-color と 4 つの border-colorButtonFace システムカラーに設定されます。

ButtonFace プロパティを使用するライトモードのページ。
ライトモード: background-color とさまざまな border-colorButtonFace システムカラーに設定されます。

<button> 要素の border-color がどのように変化するかを確認します。ユーザー エージェントはカラースキームに基づいて ButtonFace を動的に更新するため、border-top-colorborder-bottom-color計算値rgba(0, 0, 0, 0.847)(黒っぽい)から rgba(255, 255, 255, 0.847)(白っぽい)に切り替わります。<button> 要素の color が対応するシステムカラー ButtonText に設定されている場合も同様です。

計算された色の値が ButtonFace と一致することを示しています。
ライトモード: ユーザー エージェント スタイルシートで ButtonFace に設定されている border-top-colorborder-bottom-color の計算値が rgba(0, 0, 0, 0.847) になりました。
ダークモードでも計算された色の値が ButtonFace と一致することを示しています。
ダークモード: ユーザー エージェントのスタイルシートで ButtonFace に設定されている border-top-colorborder-bottom-color の計算値が rgba(255, 255, 255, 0.847) になりました。

デモ

color-scheme が多数の HTML 要素に適用された効果は、Glitch のデモで確認できます。このデモでは、上記の警告で言及されているリンクの色を使用して、WCAG AA と WCAG AAA の違反意図的に示しています。

ライトモードでのデモ。
デモcolor-scheme: light に切り替わりました。
ダークモードでのデモ。
デモcolor-scheme: dark に切り替わりました。 リンクの色で、WCAG AA と WCAG AAA の 違反 を確認します。

謝辞

color-scheme CSS プロパティと対応するメタタグは、Rune Lillesveen によって実装されました。Rune は、CSS Color Adjustment Module Level 1 仕様の共同編集者でもあります。ヒーロー画像: Philippe LeoneUnsplash