見出し画像

【Vuetify3】テーマのlight or darkをOSに同期させる方法


はじめに


こんにちは、SHIFTのITソリューション部に所属している Tanaka です。
今回は Vuetifyのテーマを、システムのモードに合わせて動的に切り替える方法を紹介しようと思います。
言い換えれば、OS側のダーク or ライトモードの設定をアプリに適用する機能です。

この機能がない場合、

  1. 切り替え用ボタンをアプリ上に設置する

  2. ユーザー側で拡張機能をインストールする

といった解決策がありますが、いずれにせよユーザーは暗い画面を望んでいるのに画面が眩しい状態が生じ、ユーザー側が解決のためにリソースを割くことになります。↓

きっかけ


普段GoogleなどのWebサービスを使っていると、「ダーク・ライト・デバイスに合わせる」といったようにテーマの設定ができるのをよく目にします。

「テーマをデバイスに合わせる、というのは裏でどういった仕組みになっているんだろう?」、「この機能、自分でも実装できるのかな?」と思い立ち、やってみたというのが本稿執筆の経緯です。

サンプルコード


VuetifyのdefaultThemeは'auto'オプションを提供していないので、この機能は独自実装する必要があります。
ただし独自と言っても、ごくごく簡単な実装で実現できます。

環境

Vue: 3.4.0
Vuetify: 3.5.0

元のコード

./src/plugins/vuetify.js

import '@mdi/font/css/materialdesignicons.css';
import 'vuetify/styles';

import { createVuetify } from 'vuetify';

export default createVuetify({
	theme: {
		defaultTheme: 'dark'
	}
});

(今回の主題)テーマの自動設定を有効にしたコード

./src/plugins/vuetify.js

import '@mdi/font/css/materialdesignicons.css';
import 'vuetify/styles';

import { createVuetify } from 'vuetify';

// 追加ポイント1. ここでダークモードであるかどうかを判定
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

export default createVuetify({
	theme: {
		defaultTheme: isDarkMode ? 'dark' : 'light' // 追加ポイント2. isDarkModeに応じてVuetifyのテーマを切り替え
	}
});

スクリーンショット

サンプルコード・キーワードの解説


const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

ここで、OSがダークモードに設定されているかどうかのブール値がisDarkModeに代入されます。
各キーワードを解説していきます。

window

windowオブジェクトは、ブラウザのグローバルオブジェクトであり、画面上に表示されている全オブジェクトの親オブジェクトです。
様々なインスタンスプロパティ・メソッドが用意されており、ウィンドウの情報を参照したり、操作したりできます。
例えば、以下のコードで画面にアラートを表示させることができます。

window.alert('Alert');

.matchMedia()

.matchMedia()メソッドは、windowオブジェクトのインスタンスメソッドの一つで、指定した特定のメディアクエリ文字列についてのMediaQueryListオブジェクトを返します。

MediaQueryListオブジェクトには、メディアクエリ文字列についての情報が入っています。

といってもイメージがつかないかと思いますので、例を挙げます。

例えば、以下のようにコードを書くと、

console.log(window.matchMedia('(prefers-color-scheme: dark)'));

次のようなオブジェクトが返ってきます。

{ media: '(prefers-color-scheme: dark)', matches: true, onchange: null }

(prefers-color-scheme: dark)について、以下のような情報が入っていることが確認できます。

  • メディアクエリ文字列は'(prefers-color-scheme: dark)'だよ

  • その文字列に現在マッチした状態だよ

  • メディアクエリの状態が変わったときに呼び出される処理は設定されていないよ

prefers-color-scheme

prefers-color-schemeは、ユーザーのシステム設定に基づいて、ユーザーがライト or ダークモードのどちらを好むかを示すCSSメディアクエリです。

これにより、ウェブサイトはユーザーの設定に応じてテーマを自動的に切り替えることができます。

matches

matchesプロパティは、MediaQueryListオブジェクトのプロパティの一つです。

このプロパティは、指定されたメディアクエリが現在のウェブページに一致するかどうかを示すブール値を返します。

サンプルコードの解説に戻ります。

export default createVuetify({
	theme: {
		defaultTheme: isDarkMode ? 'dark' : 'light'
	}
});

ここで、OSの設定に基づいてVuetifyのテーマが設定されます。
isDarkModeがtrueの場合、つまりOSがダークモードに設定されている場合はdefaultThemeを'dark'に設定し、それ以外の場合は'light'に設定します。

おわりに


今回の記事では、Vuetifyのテーマを、システムのモードに合わせて動的に切り替える方法を紹介しました。
この記事が読者の皆様の一助になれば幸いです。

もっと知りたい方はこちら

筆者の過去の記事


執筆者プロフィール:Atsuhito Tanaka
株式会社SHIFT ITソリューション部所属。現在はデリバリ改革部で、テックブーストプロジェクトに参画中。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplashDaryan Shamkhali