
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でダークモードを付けたい人は試してみてほしい。
コメント