【Flowbite】使用 JavaScript 和 Tailwind.css 實現Dark Mode

2023/08/24閱讀時間約 11 分鐘

今天在練習寫網頁時,剛好要來有做到Dark Mode 的功能,那順便來記錄一下做法~

首先要先知道Dark Mode的運作原理。是如何知道你現在是Light Mode還是Dark Mode呢?

raw-image

😀就是這邊拉~當你按下按鈕時,javascript 的toggle()去為<html>增加dark標籤。

在知道原理後,我們要如何去實作“在一個標籤中同時有兩個模式的CSS”,這邊以Tailwind.css做示範

<body class="bg-white text-black dark:bg-darkBlue dark:text-white"
>123</html>

先設定好原本的CSS,在額外設定dark: Dark Mode 的樣式就好拉~

那其實這也沒什麼,但有一個問題就是,怎麼製作觸發的按鈕。我一開始還以為要全部手尻(汗),但後來才發現其實Tailwind有幫我們做好了(佛心公司~佛心公司~🥰)

頁面連結

raw-image

那這邊就有明明白白地跟你說拉~

  1. Toggle dark mode by checking user preference in the <head> tag of your HTML (將下面這段代碼放在head標籤)
<script>
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark')
}
</script>
  1. 最棒的地方來了,他直接提供現成的button SVG,直接複製貼上就行拉~
Create a <button> element that can be interacted with to manually change the theme color:
<button id="theme-toggle" type="button" class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5">
<svg id="theme-toggle-dark-icon" class="hidden w-5 h-5" 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="theme-toggle-light-icon" class="hidden w-5 h-5" 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>

啊就給他複製到你的網頁,他會長這樣:

raw-image
raw-image
  1. Add the following JavaScript inside your main file to handle the click events on the <button> element 再新增一個JavaScript檔,將下列內容貼近去,並將其JavaScript檔引入html
var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');

// Change the icons inside the button based on previous settings
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
themeToggleLightIcon.classList.remove('hidden');
} else {
themeToggleDarkIcon.classList.remove('hidden');
}

var themeToggleBtn = document.getElementById('theme-toggle');

themeToggleBtn.addEventListener('click', function() {

// toggle icons inside button
themeToggleDarkIcon.classList.toggle('hidden');
themeToggleLightIcon.classList.toggle('hidden');

// if set via local storage previously
if (localStorage.getItem('color-theme')) {
if (localStorage.getItem('color-theme') === 'light') {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
} else {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
}

// if NOT set via local storage previously
} else {
if (document.documentElement.classList.contains('dark')) {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
} else {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
}
}

});

這邊可以稍微留意一下,步驟一根步驟三的內容其實大同相似,差別是在於:

第一步是提供給一開始渲染網站時,是否要轉成Dark Mode 的依據,那這個依據會取決於localStorage是否有Dark Mode 的紀錄。

第三步的代碼,在更改Dark Mode的同時,也會更新localStorage,那假入筆者手殘「啪」一聲,關掉原本的網頁,再重新開啟時,就會保留原本Dark Mode的依據。




3會員
10內容數
留言0
查看全部
發表第一個留言支持創作者!