mitorime logomitorime logotype
eyecatch image
作業記録: ダークモードに対応した

重い腰を上げた

ミトリメがダークモードに対応しました。
この記事では例として、端末の設定にかかわらず擬似的にダークモードを再現してお送りします。

技術的制約により一部再現しきれない箇所があるので、そこはご自身の端末でダークモードをオンオフしてお確かめください。うっさい。できねーもんはできねーんじゃ。

いや、本当は対応する気なんてなかったんですが (ライトモードの色彩がいたく気に入っているので) 、夜中布団にくるまって読むときにだいぶ目が痛いのに耐えきれず、とうとう実装した次第です。
本当に対応する気がなかったので、これまでサイト内の各カラー指定は Sass 変数 例: $foo: #baaa12; で行なっていましたが* 、これを機にすべて CSS 変数 例: var(--bar); に統一しました。

註: Sass 変数は、ビルド時に静的な値に置換されるのみで、ブラウザでの実行時になにか動的な挙動を示したりはしない

悩んだとこ

本当に色すぎる。

色を決めるのに1時間以上かけています。モノトーンの3色を新規制定するのに1時間。うっさい。アクセシビリティとかコントラスト比とかいろいろあるんじゃ。

そもそもミトリメで使っているグレーは単調なグラデーションではなく、一色ごとに色調 (Hue のほう) や彩度を微妙に調整しており、今回もその微調整をやりまくりました。だからやりたくなかったんだ。でも、こういうところに宿りますから。神が。

備忘録がてら、やり方を書いておきます。

色彩設計で、明度のみが異なる同色調・同彩度の色を作るとき、わたしは HSL や HSV ではなく LAB で調整を行うことが多いです。
理由はひとつ。LAB が人間の視覚に近くなるように設計されているから。

RGBやCMYKとは異なり、Lab色空間は人間の視覚を近似するよう設計されている。
知覚的均等性を重視しており、L成分値は人間の明度の知覚と極めて近い。
したがって、カラーバランス調整を正確に行うために出力曲線を a および b の成分で表現したり、コントラストの調整のためにL成分を使ったりといった利用が可能である。RGBやCMYKは人間の知覚よりも出力機器の都合が優先されており、これらの変換は編集ソフトの適切なブレンドモードの補助が必須である。

_ Wikipedia/Lab色空間より引用

まあ要は HSL でやるよりパッと見の色合いの調整がラクっちゅーことですね。

基本的には、もともとのグレー (ここの文字色です) から L をガッと下げて、A / B スライダを慎重につんつんし、最後に実際の色合いを見ながら HSL で微妙に彩度を弱めました。無彩色すぎず有彩色すぎないニュートラルな感じを保ちたかったので……
ここのラインを探るのがすごく疲れる。
彩度を 1 / 256 単位で調整する作業を繰り返したので目がバキバキになりました。

ちなみに、こういう作業はふだん iPad 版 Affinity Designer で行なっていますが、最近わたしの iPad Pro 2018 12.9 inch (命名・鼻毛、7歳) のディスプレイが尿液晶でへたってきて音ゲー専用機と化しているため、最近購入した MacBook Air M3 2024 13 inch (命名・オワコンモバイル (終わったコンピュータモバイル)) でやりました。

カラープロファイルは Display P3 を使用しています。

実装

ただ @media (prefers-color-scheme: dark) { { ... } } すればいいってもんじゃないんだな、これが。
さっきも言ったとおり、もともと Sass 変数を使用していたのもありましたが、そこではない。
単に色を置き換えただけではデザイン上ビミョーな箇所がいくつか出てくるんですね。

具体的にはタグとかカテゴリとか、背景色ありの文字を使用しているところ、この記事のように背景色を個別で指定しているページなどです。

前者はあえて Sass 変数のまま色を指定してダークモードの影響を受けないようにしました。仕様を逆手に取った感じ。
それと一部ライトモードとは割り当てる色を変えたり、あえてライトモードの色を指定したり。

後者は Markdown の自動レンダリングではなく記事内で手動でタグを設定して絶対色指定にするとか。

あとは見出しの文字色も白くしています。ライトモードでは見出しも本文もグレーで統一していますが、ダークモードでは黒背景にグレー文字となるので見出しがどこなのか判別しにくい。グレーの色値はライトモードと共通にしたかったので、こういったところでコントラストを調整しました。

CSS の仕様

備忘録としてはここが本編かも。

ミトリメではリンクの下線は文字色と同じグレーを使用していますが、ここを Sass 変数 $foo; から CSS 変数 var(--bar); に変えた瞬間下線が表示されなくなりました。なんでだ。

具体的な記述は以下。

text-decoration: underline solid $light_content;

これを

text-decoration: underline solid var(--content-color);

こうしたら表示されなくなりました。

text-decoration: underline solid; 
text-decoration-color: var(--content-color);

こうしたら表示された。

こたえ

先述のとおり、Sass 変数はビルド時に静的な値にコンパイルされます
つまり Sass 変数で色を指定すれば、ブラウザ側には text-decoration: underline solid #baaa12; のように渡されます。
これはどう見ても色ですね。

ですが、CSS 変数を指定した場合、ブラウザ側では渡された変数 var(--content-color);必ずしも色であると確定 (解決) できず、普通にガン無視されます
しかもブラウザによるらしい。Safari (Mac, iOS) はダメでした。
偏見だけど Safari はこういうとこ弱いよね。

代わりに text-decoration-color: var(--content-color); と記述すれば、ブラウザは一発で色と認識する (というか color プロパティに渡されているので色でしかない) ので、CSS 変数で渡されても問題ない、ということみたいです。
ショートハンドの記述が便利でも、CSS 変数を使うなら一応ロングハンドで分けといた方が無難であると言えそうです。

普通に不便だからやめろよそういうの

註: 一括指定プロパティ text-decoration は、値を書く順番は自由なので、そこは原因ではないっぽい (一応 Mozilla のドキュメントによると line style color thickness の順)