【Laravel】Darkモードの設定方法
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
Laravel で Dark モードを設定する方法についてまとめました。
経緯
Laravel では、Breeze などのスターターキットを入れる際に、
Would you like dark mode support?
というように、ダークモードの有無について聞かれます。
試しに Yes にしてみても特に見た目に変化が無かったので、調べてみることにしました。
このダークモードは TailwindCSS の使用を前提としている
tailwind.config.js で設定
TailwindCSS は、設定ファイルでダークモードの使用を設定することができます。
export default {
content: [
"./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php",
"./storage/framework/views/*.php",
"./resources/views/**/*.blade.php",
],
theme: {
extend: {
fontFamily: {
sans: ["Figtree", ...defaultTheme.fontFamily.sans],
},
},
},
plugins: [forms],
darkMode: "class", //追記 or media
}
タグにdark
というクラスを与えるとダークモードになる
このように、<html>
に dark クラスが付与されている時ダークモードになります。
つまり、ダークモードの切り替えはこのクラスを Toggle で付けたり、外したりすることで実装することができます。
<html class="dark">
<body>
略
</body>
</html>
dark:
を prefix にするとダークモード時のスタイルになる
dark:bg-black
のように、dark:
を prefix にすることでダークモード用のスタイルを設定できます。
<html class="dark">
<body>
<div
class="bg-gray-50 dark:bg-black text-black/50 dark:text-white/50"
></div>
</body>
</html>
Tailwind を使わない場合
もし、Tailwind を使わない場合、SASS などを使ってネスト構文で書くと分かりやすいかもしれないです。
/* ダークモード用スタイル */
.dark {
body {
background-color: #000;
color: #fff;
h1 {
color: #ccc;
}
a {
color: lightblue;
&:hover {
text-decoration: underline;
color: #00ffff;
}
}
}
}
実装方法
tailwind.config.js に追記
plugins: [forms],
darkMode: "class", //追記 or media
ここでmedia
を選択すると、ユーザーのデバイスの設定に依存したダークモード or ライトモードの設定になります。
今回は、class
を設定し、この media を初期モードにして、そこからトグルさせる仕組みで実装します。
モード切り替え用の JS の作成
resources/js/
├── app.js
├── darkmode.js //これを作成する
├── bootstrap.js
darkmode.js
// ダークモードにするボタン
var toggleDarkModeIcon = document.getElementById("js__toggle_dark_mode_icon")
// ライトモードにするボタン
var toggleLightModeIcon = document.getElementById("js__toggle_light_mode_icon")
// 画面読み込み時の初期状態
const colorMode = localStorage.getItem("color-mode")
if (
colorMode === "dark" ||
((!colorMode || colorMode.trim() === "") && //ローカルストレージに保存無い(ライトモードじゃ無い)
window.matchMedia("(prefers-color-scheme: dark)").matches) //デバイスの設定がdark
) {
toggleLightModeIcon.classList.remove("hidden") //ダークモード時、表示
if (!colorMode || colorMode.trim() === "") {
localStorage.setItem("color-mode", "dark")
}
} else {
toggleDarkModeIcon.classList.remove("hidden") //ライトモード時、表示
if (!colorMode || colorMode.trim() === "") {
localStorage.setItem("color-mode", "light")
}
}
//カラーモードの切り替え、ローカルストレージで状態管理
function toggleColorMode() {
toggleDarkModeIcon.classList.toggle("hidden")
toggleLightModeIcon.classList.toggle("hidden")
//状態の変更と、htmlにdarkクラスの付け外し
if (localStorage.getItem("color-mode") === "light") {
document.documentElement.classList.add("dark")
localStorage.setItem("color-mode", "dark")
} else {
document.documentElement.classList.remove("dark")
localStorage.setItem("color-mode", "light")
}
}
export default toggleColorMode
app.js に追記
import "./bootstrap"
//追記
import toggleColorMode from "./darkmode"
//追記
document
.getElementById("js__toggle_color_mode_btn")
.addEventListener("click", toggleColorMode)
切り替えボタンの表示
適当な場所に以下のようなコードで実装できます。
id が同じであれば、他のアイコン使ったり文字で表現しても動きます。
<button id="js__toggle_color_mode_btn" type="button" class="text-sm p-2.5">
<svg
id="js__toggle_dark_mode_icon"
class="hidden w-4 h-4"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"
></path>
</svg>
<svg
id="js__toggle_light_mode_icon"
class="hidden w-4 h-4 text-white"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
fill-rule="evenodd"
clip-rule="evenodd"
></path>
</svg>
</button>
まとめ
ダークモードとライトモードの切り替えができるようになりました。
あとは、CSS か Tailwind で丁寧に両方の表示を整えるだけですね。
ダークモードの有無について聞いてくれるのに、ただ HTML のクラスにダークモード用のクラスが追加されているだけだったとは。
実質、1つの画面で2つのカラー調整が必要になるということなので、よっぽどの理由がない限り付けない機能なんじゃないかと思います。
ダークモードが必要なサービスってどんなものがあるんでしょうか?長時間見る、映像系?
特に理由ないのに暇なデザイナーにダークモードを付けようと言われたことがありますが、なんの課題に対してその機能つける必要があるのか全く説明もないので暇人が余計な仕事を作る典型例だなぁと感じたことはあります。
気になったので実装してみたシリーズでした。誰かの参考になれば幸いです。