對於需要長時間面對螢幕的開發者或工作者來說,亮白色的介面往往容易帶來視覺疲勞,因此不論是撰寫程式還是閱讀文獻, 「暗色模式(Dark Mode)」 早已成為許多人的預設首選。若使用者在專注工作的過程中切換到 TaskTimer,瞬間的高對比白光可能會讓人感到刺眼與不適。為了打造更貼心、減壓的專注環境,接下來我們要加上切換暗色模式的功能。
1. Bootstrap 5 原生主題屬性:直接透過在 <html> 標籤上切換 data-bs-theme="dark" 或 data-bs-theme="light",讓所有系統元件(Accordion、Modal、Card、Form Select)自動適應暗色視覺。
2. 主題開關(Toggle / Switch):在 Header 的多國語系選單旁,放置一個切換開關。
3. 自動偵測系統偏好:若使用者第一次開啟網頁,優先讀取作業系統/瀏覽器的預設主題(prefers-color-scheme: dark)。
4. 狀態持久化:將使用者手動選擇的主題儲存在 localStorage 中。
在 Header 的右上角工具列(語系切換選單旁邊)加入 Switch 開關:
<div class="form-check form-switch mb-0 d-flex align-items-center gap-2">
<input
class="form-check-input mt-0"
type="checkbox"
role="switch"
id="darkModeToggle"
style="cursor: pointer;"
onchange="toggleDarkMode(this.checked)"
>
<label class="form-check-label user-select-none mb-0" for="darkModeToggle" style="cursor: pointer;">
<span id="themeIcon"></span>
</label>
</div>
theme.js)新增一個theme.js檔案,並在html中載入。
// 優先讀取偏好並套用至 <html>,防止畫面白光閃爍
const savedTheme = localStorage.getItem("app_theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
let currentTheme = savedTheme || (systemPrefersDark ? "dark" : "light");
document.documentElement.setAttribute("data-bs-theme", currentTheme);
// 套用主題與同步 Switch 開關狀態
function applyTheme(theme) {
currentTheme = theme;
localStorage.setItem("app_theme", theme);
document.documentElement.setAttribute("data-bs-theme", theme);
// 同步 Switch 切換按鈕的勾選狀態 (暗色為 checked)
const toggleInput = document.getElementById("darkModeToggle");
if (toggleInput) {
toggleInput.checked = theme === "dark";
}
}
// 暴露全域切換函式給 HTML onchange 觸發
window.toggleDarkMode = function (isDark) {
applyTheme(isDark ? "dark" : "light");
};
// DOM 載入後確認 Switch 按鈕開關位置正確
document.addEventListener("DOMContentLoaded", () => {
applyTheme(currentTheme);
});
<select> 視覺質感我們在之前開發時,子任務狀態使用的是自訂 <select>,在暗色模式下,只需要將 Background 顏色交給 Bootstrap 的主題變數,就能完美融入暗色背景:
// 在產生 statusBadgeHTML 時,加入 form-select 基礎 class:
const statusBadgeHTML = `
<select
class="form-select form-select-sm border-0 ${subBadge.class} rounded-pill me-2 py-0 ps-2 pe-3 fw-bold"
style="width: auto; display: inline-block; cursor: pointer; font-size: 0.75rem; background-size: 8px 8px; background-position: right 0.4rem center;"
onchange="changeSubtaskStatus('${task.id}', '${sub.id}', this.value)"
>
<option value="in_progress" ${subStatus === "in_progress" ? "selected" : ""}>
${langDict?.subtaskInProgress || '進行中'}
</option>
<option value="completed" ${subStatus === "completed" ? "selected" : ""}>
${langDict?.subtaskCompleted || '已完成'}
</option>
</select>
`;

透過 Bootstrap 5 的 data-bs-theme,我們不需要額外撰寫數百行 CSS,就能讓全站組件(Modal、Accordion、Input、Dropdown)快速切換於明亮與暗色模式之間。