画像を dark mode 対応するメモ
画像をダークモード対応する方法のメモ
結論
- SVG は SVG 内に style でダークモードのスタイルを作成する
- backdroung-image は media query で切り替える
- img タグは
<picture>
を使って切り替える
web サイトでの画像をパターン分けする
画像の種類は2通りに分ける
- SVG 画像
- SVG 以外の画像
webサイトで使う画像はだいたい次のパターンに分けられる
- img タグで配置する画像
1-a. SVG 画像
1-b. SVG 以外の画像 - CSS の background-image で配置する画像
2-a. SVG 画像
2-b. SVG 以外の画像 - inline SVG で配置する SVG 画像
1. SVG 画像の場合
1-a. img タグで配置する SVG 画像
2-a. background-image で配置する SVG 画像
3. inline SVG 画像
1-1. SVG 内に style タグでダークモードの設定をする
SVG はコードなので内部に <style>
タグを書くことができる
CSS の @media (prefers-color-scheme: dark)
でダークモードを判別できるので、 SVG 内の <style>
タグ内にメディアクエリでダークモードの設定を書けば oK
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
.base { fill: #66C3C4; }
.mark { fill: #FFFFFF; }
@media (prefers-color-scheme: dark) {
.base { fill: #66C3C4; }
.mark { fill: #FFFFFF; }
}
</style>
<path class="base" d="..." fill="#66C3C4" />
<path class="mark" d="..." fill="#FFFFFF" />
</svg>
CSS で指定できるので、複数の色が必要な画像に向いている
inline SVG だけでなく、img タグで配した SVG も background-image で読み込んだ SVG も SVG タグ内の style が効く
⚠️ 線を使っている SVG 画像は fill
ではなく stroke
で指定する
1-2. inline SVG の場合は CSS で設定しても良い
アイコンなどの inline SVG は fill="currentColor"
として CSS の color
で色を設定している場合もある。
この場合は SVG 内に style を付けてしまうと汎用性が失われるので CSS で color を変更する方が良い
1-2-1. メディアクエリで color を切り替える
<i class="icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="..." fill="currentColor" />
</svg>
</i>
.icon {
color: #205081;
}
@media (prefers-color-scheme: dark) {
.icon {
color: #f8f5f0;
}
}
1-2-2. CSS カスタムプロパティ(変数) にダークモードの設定をしておく
テーマが決まっているなら使用する色を CSS カスタムプロパティにしておき、予めダークモードのカラー設定をしておけばシンプルにデザインを保てる
<i class="icon">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="..." fill="currentColor" />
</svg>
</i>
:root {
--icon-status-info: #205081;
}
@media (prefers-color-scheme: dark) {
:root {
--icon-status-info: #f8f5f0;
}
}
.icon {
color: var(--icon-status-info);
}
2. background-image の場合
2-b. background-image で配置する SVG 以外の画像
CSS なのでメディアクエリ prefers-color-scheme: dark で背景画像を変える
.content {
background-image:url(/images/path/to/default-image.webp);
}
@media (prefers-color-scheme: dark) {
.content {
background-image:url(/images/path/to/darkmode-image.webp);
}
}
3. img タグの場合
1-a. img タグで配置する SVG 以外の画像
picture / source を使って切り替える
picture / source は source のメディアクエリにマッチしたら、source で指定した画像が表示され、マッチしなければ最後の img タグがそのまま表示される機能
source タグのメディアクエリにダークモードを判定する prefers-color-scheme:dark
を指定することで画像を切り替えることができるようになる
<picture>
<source src="/images/darkmode-image.webp" media="(prefers-color-scheme:dark)" />
<img src="images/default-image.webp" alt="" />
</picture>
srcset を使う場合
img タグは多く場合で srcset
を使い画像サイズをコントロールしていると思う。
その場合も source タグにダークモード用の srcset
を指定するだけで良い
<picture>
<source
srcset="
/images/darkmode-image@300w.webp 300w,
/images/darkmode-image@600w.webp 600w"
media="(prefers-color-scheme:dark)"
/>
<img
src="images/default-image.webp"
srcset="
/images/default-image@300w.webp 300w,
/images/default-image@600w.webp 600w"
alt=""
/>
</picture>
favicon をダークモード対応する
- favicon を SVG で作成する
- SVG 内に style でダークモードのデザインを作成する
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
💡 favicon として SVG が使えないブラウザは svg の方が無視される
HTML は上から読み込まれるので fallback 用のタグを上に書いておく必要がある
1 の方法と同様で SVG 内に style でダークモード用の設定を追加する
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<style>
.base { fill: #fbcb62; }
.icon { fill: #2e2827; }
@media (prefers-color-scheme: dark) {
.base { fill: #2e2827; }
.icon { fill: #fbcb62; }
}
</style>
<path class="base" d="..." fill="#fbcb62"/>
<path class="icon" d="..." fill="#2e2827"/>
</svg>
JavaScript で ダークモードを判定する方法
window.matchMedia
を使ってダークモードかどうかを判定できる
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const isDarkMode = darkModeMediaQuery.matches;
if (isDarkMode) {
// darkmode の場合の処理
} else {
// 通常の処理
}
Discussion