【SWELL】プラグインなしでダークモードを実装する方法

本記事にはアフィリエイト広告(PR)が含まれています。

SWELLにはダークモードの機能がない。そこで、プラグインを使わずにCSS数行とJavaScriptだけでダークモードを付けてみた。

夜にスマホで読むとき、白い画面はまぶしい。プラグインも試したが、SWELLのマーカーなど一部の装飾と相性が悪く、色の調整も面倒だった。

今回の方法は、sokohakoさんの記事を参考にしている。その記事どおりに入れてみて、つまずいたところや追加で直したところも含めてまとめておく。

目次

仕組み:ページ全体の色を反転させる

やっていることは、CSSの filter でページ全体の色を反転させるだけ。白い背景は黒に、黒い文字は白になる。

そのままだと画像や動画までネガのように反転してしまうので、画像・動画・埋め込みだけもう一度反転させて元の色に戻す。切り替えはJavaScriptで html タグに印を付け外しするだけで、選んだモードはブラウザに保存される。

  • 良いところ:プラグイン不要。色を一つずつ決めなくていい
  • 弱いところ:元々濃い色の部分は逆に明るくなる。一部の装飾は個別に調整が必要

手順1:追加CSSにダークモード用のCSSを貼る

外観 → カスタマイズ → 追加CSS に、次のCSSを貼る。

html[data-mode="dark"] {
  filter: invert(1) hue-rotate(180deg);
}

html[data-mode="dark"] img,
html[data-mode="dark"] video,
html[data-mode="dark"] iframe {
  filter: invert(1) hue-rotate(180deg);
}
  • invert(1):色を完全に反転させる
  • hue-rotate(180deg):色味を元に近づける(青がオレンジになるのを防ぐ)
  • 2つ目のブロック:画像・動画・埋め込み(YouTubeや広告など)をもう一度反転して元に戻す

背景が真っ黒すぎると感じるなら、これも足すと濃いグレーになる。画像には影響しない。

html[data-mode="dark"] body {
  background: #e8e8e8;
}

手順2:JavaScriptを「高度な設定」に貼る

JavaScriptはファイルをアップロードしなくてもよい。SWELLの管理画面にそのまま貼れる。

外観 → カスタマイズ → 高度な設定 → 「bodyタグ終了直前に出力するコード」 に、次のコードを貼る。

<script>
document.addEventListener('DOMContentLoaded', function() {
    const toggleButtons = document.querySelectorAll('.toggle-mode');
    toggleButtons.forEach(function(button) {
        button.addEventListener('click', function() {
            const currentMode = localStorage.getItem('data-mode');
            const newMode = currentMode === 'dark' ? 'light' : 'dark';
            localStorage.setItem('data-mode', newMode);
            applySavedMode();
        });
    });
    applySavedMode();
});

function applySavedMode() {
    const savedMode = localStorage.getItem('data-mode');
    if (savedMode === 'light' || savedMode === 'dark') {
        document.documentElement.setAttribute('data-mode', savedMode);
    }
}
</script>

これだけだと、ダークモードのままページを移動したときに、一瞬白い画面が見えてから暗くなる。それが気になるなら、同じ画面の 「headタグ終了直前に出力するコード」 にもこれを足す。

<script>
(function(){
  var m = localStorage.getItem('data-mode');
  if (m === 'dark') document.documentElement.setAttribute('data-mode', 'dark');
})();
</script>

手順3:ウィジェットに切り替えボタンを置く

ボタンは1つで、押すたびにダークとライトが切り替わる。メニューにはHTMLを置けないので、ウィジェットの「カスタムHTML」ブロックを使う。

外観 → ウィジェット で、次の2か所にカスタムHTMLブロックを置く。

  • PC用:「ヘッダー内部」
  • スマホ用:「スマホ開閉メニュー下」

中身は2か所ともこの1行だけでよい。SWELL標準の電球アイコンが表示される(塗りつぶし版は icon-light-bulb-fill)。

<button class="toggle-mode"><i class="icon-light-bulb"></i></button>

このままだとブラウザ標準のグレーの四角が付くので、追加CSSで消しておく。

.toggle-mode {
  background: transparent;
  border: none;
  padding: 4px;
  font-size: 1.2em;
  color: inherit;
  cursor: pointer;
}

.toggle-mode:hover {
  opacity: 0.6;
}

これでボタンを押すとダークモードになり、もう一度押すと元に戻る。

実際につまずいたところと対処

ボタンを押しても切り替わらない

参考記事には「ボタン2つ版」と「ボタン1つ版」がある。自分はボタンは2つ版、JavaScriptは1つ版を入れていて、押しても何も起きなかった。

JavaScriptは class="toggle-mode" のボタンを探している。ボタンが dark1 / light1 のままだと反応しないので、組み合わせを揃えること。

スマホ表示に「ボタン」が2個残っている

ブラウザの幅を狭めると、ハンバーガーメニューの下に「ボタン」と書かれた四角が2つ出ていた。PC用のウィジェットだけ直して、「スマホ開閉メニュー下」に古いボタンが残っていたのが原因だ。

PCとスマホ、両方のウィジェットを手順3の1行に置き換える。直したのに変わらないときは、SWELL設定の「キャッシュクリア」も試す。

画像がぼやける・白っぽくなる

参考記事では、ページ全体を invert(0.8) にして背景をまろやかにしている。ただ、その上で画像を invert(1) で戻すと、きっちり元に戻らず、画像がグレーがかって霧んだようになる。

全体も invert(1) に揃えると、画像は元の色でくっきり表示される。背景の暗さは、手順1の body の背景色で調整すればよい。

動画が反転したまま

参考記事のCSSは、画像(img)と埋め込み(iframe)しか戻していない。WordPressの動画ブロックは video タグなので、反転したままになる。手順1のCSSでは video も入れてある。

インラインコードの枠が見えない

SWELLのインラインコードは、ほぼ白の背景に薄い枠だ。反転すると背景の黒とほぼ同じ色になって、箱が溶けて見えなくなる。

ダークモードのときだけ、元の色を少し濃くしておく。:not(pre) > を付けると、コードブロックの中には効かない。

html[data-mode="dark"] :not(pre) > code {
  background: #d6d6d6;
  border-color: #a0a0a0;
}

目次の現在地ハイライトが消える

目次で今読んでいる箇所を薄い黄色で光らせている場合、反転すると背景と同じような暗い色になって見えなくなる。これもダークモード用に濃い黄色を指定しておく。クラス名は自分の環境に合わせて変えてほしい。

html[data-mode="dark"] .p-toc__link.mkj-active,
html[data-mode="dark"] .mkj-marker::before {
  background-color: #e8d24a !important;
}

反転なので、元の色を濃くするほど、ダークモードでは明るく目立つ。他の装飾が見づらいときも、同じ考え方で直せる。

まとめ

設定するのは、追加CSS・高度な設定・ウィジェットの3か所だけだ。最後に、追加CSSに入れたものを全部まとめておく。

/* ダークモード本体 */
html[data-mode="dark"] {
  filter: invert(1) hue-rotate(180deg);
}

html[data-mode="dark"] img,
html[data-mode="dark"] video,
html[data-mode="dark"] iframe {
  filter: invert(1) hue-rotate(180deg);
}

/* インラインコード */
html[data-mode="dark"] :not(pre) > code {
  background: #d6d6d6;
  border-color: #a0a0a0;
}

/* 切り替えボタン */
.toggle-mode {
  background: transparent;
  border: none;
  padding: 4px;
  font-size: 1.2em;
  color: inherit;
  cursor: pointer;
}

.toggle-mode:hover {
  opacity: 0.6;
}

設定したら、次の点を確認するとよい。

  • PCとスマホの両方で、ボタンが1個だけ表示されている
  • ダークモードのまま別のページに移動しても、暗いままになっている
  • 画像と動画が元の色で表示されている
  • マーカーやボックスなど、自分がよく使う装飾が読める

細かい配色は自分で決めていないが、夜にスマホで読むには十分快適だ。SWELLでダークモードを付けたい人は試してみてほしい。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次