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

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

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

SWELLには、ダークモードの機能がありません。
そこで今回は、プラグインを使わず、CSS数行とJavaScriptだけでダークモードを付けてみました。

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

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

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

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行だけでOKです。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 のままだと反応しません。ボタンとJavaScriptの組み合わせは必ず揃えること。

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

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

PCとスマホ、両方のウィジェットを手順3の1行に置き換えればOKです。直したのに変わらないときは、**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;
}

※背景色の調整(body)や目次ハイライトの指定は、必要に応じて追加してください。

設定が終わったら、次の点をチェックしておくと安心です。

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

細かい配色まで作り込んだわけではありませんが、夜にスマホで読むには十分快適です。SWELLでダークモードを付けたい方は、ぜひ試してみてください。

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

コメント

コメントする

目次