はじめに
ブラウザにダークモードが搭載されるようになった!
CSSで、ダークモード時の Media Query が記述できる!
Can I use... Support tables for HTML5, CSS3, etc
→JSでは取得できないの...??探してもあまり見つからないし....
いろいろ試行錯誤した結果、取得する方法を発見(?)したので、紹介しようと思います。
条件
-
CSSで、Media Query "
prefers-color-scheme
" が記述できる
2019.12.22現在、最新版Firefox, Chrome, Safari, Operaは使用できます。Edgeは残念ながら...
Can I use... Support tables for HTML5, CSS3, etc -
JSで、
getComputedStyle
とgetPropertyValue
を使用できる
モダンブラウザすべてに対応しています。
(ユーザーがJSを「実行しない」にしていなければ)取得できます。
考え方
- JSでは現在、「直接の」判定はできない。
- しかし、CSS変数は取得できる。
- Media Query で、CSS変数の値を変えることが可能。
...ということは...??
- Media Query で CSS変数を定義
- JSでCSS変数を取得し、値によって判定が可能
実装
今回記述したコードは、GitHubにあげておりますので、併せてごらんください。
a01sa01to/DarkmodeGetter_js
=====
1. CSS変数を定義
/* ライトモードの時、CSS変数 isDarkmode は存在しない */
html{ ... }
@media (prefers-color-scheme: dark){
/* ダークモードの時 */
html{
--isDarkmode: True;
....
}
}
prefers-color-scheme - CSS: カスケーディングスタイルシート | MDN
変数名や値などは、競合しないように適宜変えても構いません。
=====
2. CSS変数を取得
/* 1. <html> に変数を設定したので、まずは <html> を取得する */
const htmlTag = document.querySelector("html");
// -> <html lang=...> ..... </html>
/* 2. CSSプロパティの取得 */
const comStyle = getComputedStyle(htmlTag);
// -> CSSStyleDeclaration {0: ... }
/* 3. 変数の取得 */
const cssVariable = comStyle.getPropertyValue('--isDarkmode');
// -> "True"(ダークモード)・""(ライトモード)
// ライトモードは、変数を指定していないため、空の文字列が返される
もちろん、わざわざ上記のように書かずとも、1行で記述可能です。
getComputedStyle(document.querySelector("html")).getPropertyValue('--isDarkmode');
1.でCSS変数を変更した場合は、こちらも変更する必要があります。
=====
3. 判定
/* 2 のコードの続き。"cssVariable" が定義されている前提 */
const isDarkmode = !!cssVariable;
// これでも同じ
const isDarkmode = Boolean(cssVariable);
ライトモードでは、cssVariable == ""
なので、Falsy です。
そのため、 isDarkmode
は false
を返します。
ダークモードでは、 cssVariable == "True"
→ Truthy なので、 true
を返します。
Truthy - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
Falsy - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
=====
以上により、ブラウザがダークモードかを取得することができました!
もっと簡単な方法(2022/01/22追記)
もっと簡単な方法がありました。
window.matchMedia('(prefers-color-scheme: dark)').matches
これにより、CSSのメディアクエリ @media (prefers-color-scheme: dark)
に合致しているかどうかを判定できるため、
結果としてダークモードかどうかを判別することができるというわけです。
変更をリアルタイムに検知する方法(2022/01/22追記)
ライトモード・ダークモードの変更をリアルタイムに検知する方法を以下の記事にしました
併せてご覧ください!