ブラウザのカラースキームによってWhiteplainの明暗を切り替わるようにしました


Chrome 78で試験的にWebページにダークモードを強制する機能が実装されたというニュースから、prefers-color-schemeというブラウザのカラースキームによってスタイルを切り替えるメディアクエリがあることを知りました。HugoのテーマWhiteplain暗色版を作ったときから、自動で切り替わるといいのに…とは思っていたので、このメディアクエリを使って明色と暗色が切り替わるようにしました。

Chrome 78公開。未対応ページを強制ダークモード化、保存したパスワードの安全度確認機能など搭載 - Engadget 日本版

prefers-color-scheme - CSS: カスケーディングスタイルシート | MDN

明色または暗色のままにする

ユーザの環境によらず明色または暗色のままにする場合は、Whiteplain Light / Whiteplain Darkthemesディレクトリに入れて、config.tomlwhiteplainの左側に併記します。

ちなみにwhiteplain-lightは今回新しく作りました。

1
2
#theme = ["whiteplain-light", "whiteplain"]
theme = ["whiteplain-dark", "whiteplain"]

ただし、上記のChrome 78のForce Darkが有効な場合は、Whiteplain Lightを指定しても自動で暗色にされます。。。

Chrome 78のForce Darkについて

Chrome 78のForce Dark Mode for Web Contentsは、prefers-color-schemeメディアクエリのブラケット内のカラー指定は変更しませんが、それ以外は暗色化します。

Whiteplainの場合、構造系のCSSと色系のCSSがごちゃまぜになっていたので、Whiteplain Darkを作ったときは色系のCSSだけパッチを当てる感じで実現しました。今回はその暗色CSSパッチをprefers-color-scheme: darkメディアクエリで自動適用するようにしただけなので、明色のCSSはprefers-color-schemeのブラケットで囲われていません。このため、Force Darkの対象となってしまいます。

CSSファイルのインポート

構造系のCSSと色系のCSSを分離して、prefers-color-scheme: lightだろうがprefers-color-scheme: darkだろうが明色のCSSを読み込むようにしてやればいいと思ったのですが、一つのCSSファイルは二度読み込まれることがない(?)ため、下記の例だとダークモードの時に色系Style全く効かなくなってしまいます。

さらに、下記の例では、prefers-color-schemeに対応してないブラウザ(例えばIE)でもcolor-light.cssが適用されません。IEを考慮すると明色か暗色をprefers-color-schemeブラケットの外に置く必要があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@import url(./structure.css);

@media (prefers-color-scheme: light) {
  @import url(./color-light.css);
}

@media (prefers-color-scheme: dark) {
  /* color-light.cssは上でインポート済みなので、インポートされない?=ダークモードで色系Styleが適用されない */
  @import url(./color-light.css);
}

あっちを立てればこっちが立たずって感じです。。。

まぁ、現時点でForce Darkは試験機能なので、あまり考えなくていいんですけど。

ToDo