如何為我的網站添加黑暗模式
逐步指導,讓您的網站有日夜兩種模式,讓它適用於不同時間的使用。
更新:我現在使用媒體查詢第5級:
prefers-color-scheme
Media Queries Level 5 规範包含了一個新的 prefers-color-scheme
媒體功能。
目前,在所有主要的瀏覽器中都支持這個功能。自 Chrome/Edge 76 版本、Firefox 67 版本和 Safari 12.1 版本之後,甚至包括 iOS Safari。
我們可以利用它來判斷用戶使用的是深色模式還是淺色模式:
1 | @media (prefers-color-scheme: dark) { |
我現在使用它來預設顯示明亮模式的網站,如果系統處於深色模式,則顯示黑暗模式。
如果系統沒有內建黑暗模式(舊版 Windows/macOS 或 Linux), 我建議使用像 Night Eye 這樣的擴展程式。
在 prefers-color-scheme
可用之前如何實現黑暗模式
我最近重新設計了我的網站。這裡有兩張照片供參考:
我在幾乎一年前設計了這個網站,並在設計過程中進行了許多改變,就像我們對待任何一個網站一樣。
最終,我對設計感到厭倦:標題太大,浪費了太多空間,而不是直接顯示內容,等等。
昨晚,我坐下來重新設計了這個網站,並在今天早上完成了重設計:
好多了!內容,最重要的東西,更突出了。
我使用等寬字體(Inconsolata),因為作為一個編程博客,這是一個不錯的字體,儘管由於字體的使用導致可讀性降低和頁面大小增加,但我仍然想在我的網站上使用它。我更喜歡它,因為我的網站是我日常活動的重要組成部分,我希望它是我想要的樣子。
我只錯過了一件事:黑暗模式。當我重新設計時,我考慮了黑暗模式選項。
我是如何做到的?首先,我在側邊欄中添加了一個月亮 Emoji 🌓,作為讓人們從明亮模式切換到黑暗模式的方式。
然後,我添加了一個當其被點擊時運行的 JavaScript 片段。我只是將它直接添加到 HTML 中的 onclick
事件處理程序中,而不做太花哨的處理:
1 | <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 | document.addEventListener('DOMContentLoaded', (event) => { |
現在,如果人們更改模式,他們的選擇將在下次加載頁面時被記住。
然後,我在 CSS 中添加了很多以 body.dark
為前綴的指令,像這樣:
1 | body.dark { |
現在,事情應該已經開始運作了!這是我網站的黑暗模式效果:
我默認將 dark
類添加到 body
元素中,使黑暗模式成為默認模式:
1 | <body class="dark"> |
為什麼這麼做?首先,我更喜歡它。然後,我在 Twitter 上進行了一次投票,人們更喜歡它。
還有一個技術原因,一個非常簡單的原因。我沒有將用戶選擇保存在服務器端,所以在本地存儲可用之前,我無法知道模式。
如果網站是在服務器端生成的,我可以這麼做,但它是一個靜態網站,所以無論誰請求,我都向每個人提供相同的頁面。即使我得到了一個 cookie,我也沒有地方處理它(另一方面,這意味著我的頁面加載更快)。
因此,當有人在我的站點上導航到另一個頁面,或在第二次訪問時首次加載頁面時,我不想顯示一個明亮的頁面,同時確定模式。也許訪問者正在夜間在一個黑暗的房間裡編程。
我寧願在明亮模式下進行:顯示黑暗的頁面幾毫秒,然後再變回白色。