/

如何為我的網站添加黑暗模式

如何為我的網站添加黑暗模式

逐步指導,讓您的網站有日夜兩種模式,讓它適用於不同時間的使用。

更新:我現在使用媒體查詢第5級:prefers-color-scheme

Media Queries Level 5 规範包含了一個新的 prefers-color-scheme 媒體功能。

目前,在所有主要的瀏覽器中都支持這個功能。自 Chrome/Edge 76 版本、Firefox 67 版本和 Safari 12.1 版本之後,甚至包括 iOS Safari。

我們可以利用它來判斷用戶使用的是深色模式還是淺色模式:

1
2
3
4
5
6
7
8
9
10
11
12
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
@media (prefers-color-scheme: light) {
body {
background-color: white;
color: black;
}
}

我現在使用它來預設顯示明亮模式的網站,如果系統處於深色模式,則顯示黑暗模式。

如果系統沒有內建黑暗模式(舊版 Windows/macOS 或 Linux), 我建議使用像 Night Eye 這樣的擴展程式。

prefers-color-scheme 可用之前如何實現黑暗模式

我最近重新設計了我的網站。這裡有兩張照片供參考:

舊首頁

舊文章頁面

我在幾乎一年前設計了這個網站,並在設計過程中進行了許多改變,就像我們對待任何一個網站一樣。

最終,我對設計感到厭倦:標題太大,浪費了太多空間,而不是直接顯示內容,等等。

昨晚,我坐下來重新設計了這個網站,並在今天早上完成了重設計:

新首頁

新文章頁面

好多了!內容,最重要的東西,更突出了。

我使用等寬字體(Inconsolata),因為作為一個編程博客,這是一個不錯的字體,儘管由於字體的使用導致可讀性降低和頁面大小增加,但我仍然想在我的網站上使用它。我更喜歡它,因為我的網站是我日常活動的重要組成部分,我希望它是我想要的樣子。

我只錯過了一件事:黑暗模式。當我重新設計時,我考慮了黑暗模式選項。

我是如何做到的?首先,我在側邊欄中添加了一個月亮 Emoji 🌓,作為讓人們從明亮模式切換到黑暗模式的方式。

然後,我添加了一個當其被點擊時運行的 JavaScript 片段。我只是將它直接添加到 HTML 中的 onclick 事件處理程序中,而不做太花哨的處理:

1
2
3
<p>
<a href="#" onclick="localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')" title="Dark/light">Dark/light</a>
</p>

這是在 onclick 中運行的 JavaScript 代碼:

1
localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')

這有點複雜,但基本上我檢查 本地存儲 中的 mode 屬性是否為 ‘dark’(如果尚未設置,則默認為 ‘dark’),並將相反的值設置到本地存儲中。

然後我將 dark 類分配給 body HTML 元素,這樣我們就可以使用 CSS 來為網頁設計黑暗模式。

當 DOM 加載完成時,另一個腳本會運行,檢查模式是否為黑暗。如果是黑暗模式,它會向 body HTML 元素添加 dark 類:

1
2
3
document.addEventListener('DOMContentLoaded', (event) => {
((localStorage.getItem('mode') || 'dark') === 'dark') ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')
})

現在,如果人們更改模式,他們的選擇將在下次加載頁面時被記住。

然後,我在 CSS 中添加了很多以 body.dark 為前綴的指令,像這樣:

1
2
3
4
5
6
7
8
9
body.dark {
background-color: rgb(14,20,10);
color: #fff;
}
body.dark code[class\*=language-],
body.dark table tbody>tr:nth-child(odd)>td,
body.dark table tbody>tr:nth-child(odd)>th {
background: #282c34
}

現在,事情應該已經開始運作了!這是我網站的黑暗模式效果:

黑暗首頁

黑暗文章頁面

我默認將 dark 類添加到 body 元素中,使黑暗模式成為默認模式:

1
2
3
<body class="dark">
...
</body>

為什麼這麼做?首先,我更喜歡它。然後,我在 Twitter 上進行了一次投票,人們更喜歡它。

投票

還有一個技術原因,一個非常簡單的原因。我沒有將用戶選擇保存在服務器端,所以在本地存儲可用之前,我無法知道模式。

如果網站是在服務器端生成的,我可以這麼做,但它是一個靜態網站,所以無論誰請求,我都向每個人提供相同的頁面。即使我得到了一個 cookie,我也沒有地方處理它(另一方面,這意味著我的頁面加載更快)。

因此,當有人在我的站點上導航到另一個頁面,或在第二次訪問時首次加載頁面時,我不想顯示一個明亮的頁面,同時確定模式。也許訪問者正在夜間在一個黑暗的房間裡編程。

我寧願在明亮模式下進行:顯示黑暗的頁面幾毫秒,然後再變回白色。