tbsmcd.net
Dark mode
index, archives, tags, search, profile

blog ダークモード対応(2)OS のモードに対応する方法

Series: blogダークモード対応

  1. 2022-11-25 blog ダークモード対応(2)OS のモードに対応する方法
  2. 2022-11-24 blog ダークモード対応(1)やりたいこと・やるべきことの整理

この記事で書くこと

CSS だけで OS のダークモードに追従する方法

 CSS のメディア特性 prefers-color-scheme を使う。

ref. https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-color-scheme

@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: white;
  }
}

JavaScript で OS のダークモードに追従する方法

 JavaScript でも同様にモードを取得できる。

ref. https://developer.mozilla.org/ja/docs/Web/API/Window/matchMedia

if (matchMedia('(prefers-color-scheme: dark)').matches) {
  // ダークモードのとき
} else {
  // ダークモードではないとき
}

ユーザ指定のカラースキームに対応する方法

 以下は checkbox で対応する場合。

<input type="checkbox" id="cb-dark-theme"> Dark them
const cbDark = document.getElementById("cb-dark-theme");
const setDark = () => {
    document.body.classList.add("dark-theme");
    cbDark.checked = true;
};
const setLight = () => {
    document.body.classList.remove("dark-theme");
    cbDark.checked = false;
}
cbDark.addEventListener("change", (e) => {
    if (e.target.checked) {
        setDark();
    } else {
        setLight();
    }
});

.dark-theme {
  color: #ffffff;
  opacity: 0.9;
  background: $dark_base_color;

通常の JavaScript と同じくイベントを捕捉したら良い。ダークカラースキームのときに .dark-theme を追加し、ライトカラースキームのときに削除しているが、 CSS の書き方によってはライトカラースキームのときに .light-theme を追加するようにしても良いだろう。

状態の保持方法

 checkbox で設定した状態はページ遷移したら保持できないので localStoragesessionStorage を使う。単にページ遷移しても保持したい場合は sessionStorage で良く、ブラウザを閉じても保持したい場合は localStorage を使う。

cbDark.addEventListener("change", (e) => {
    if (e.target.checked) {
        setDark();
        localStorage.setItem("selectedTheme", "dark");
    } else {
        setLight();
        localStorage.setItem("selectedTheme", "light");
    }
})

実際に行ったこと

 前回書いたように

としたいので、

とした。

const cbDark = document.getElementById("cb-dark-theme");
const setDark = () => {
    document.body.classList.add("dark-theme");
    cbDark.checked = true;
};
const setLight = () => {
    document.body.classList.remove("dark-theme");
    cbDark.checked = false;
}
document.addEventListener("DOMContentLoaded", (event) => {
    const selectedTheme = localStorage.getItem("selectedTheme");
    if (selectedTheme == "dark") {
        setDark();
    } else if (selectedTheme == "light") {
        setLight();
    } else {
        const pcs = window.matchMedia("(prefers-color-scheme: dark)"); 
        if (pcs.matches) {
            setDark();
        } else {
            setLight();
        }
    }
});
cbDark.addEventListener("change", (e) => {
    if (e.target.checked) {
        setDark();
        localStorage.setItem("selectedTheme", "dark");
    } else {
        setLight();
        localStorage.setItem("selectedTheme", "light");
    }
});

続く。

Tags: CSS JavaScript