一步到位:三行CSS代碼輕松實(shí)現(xiàn)全網(wǎng)站暗黑模式
本文由 Mads Stoumann 撰寫(xiě)的博文,主要介紹了如何通過(guò)簡(jiǎn)單的三行CSS代碼實(shí)現(xiàn)網(wǎng)站的暗黑模式。該博文提到,<system-color>
關(guān)鍵字一般反映用戶、瀏覽器或操作系統(tǒng)做出的默認(rèn)顏色選擇。這些關(guān)鍵字通常用于瀏覽器的默認(rèn)樣式表。通過(guò)這種方式,我們可以輕松地實(shí)現(xiàn)網(wǎng)站的暗黑模式。
在另一篇博文中,Mads Stoumann詳細(xì)介紹了如何使用SVG和CSS重新創(chuàng)建Apple的暗黑模式圖標(biāo)。這證明了他在此領(lǐng)域的深厚技術(shù)和創(chuàng)新能力。
總的來(lái)說(shuō),這個(gè)網(wǎng)站提供了許多關(guān)于使用CSS和SVG進(jìn)行網(wǎng)站設(shè)計(jì)和開(kāi)發(fā)的有用信息,特別是關(guān)于暗黑模式的實(shí)現(xiàn)。這對(duì)那些希望在自己的網(wǎng)站上實(shí)現(xiàn)暗黑模式的開(kāi)發(fā)者來(lái)說(shuō)是非常有價(jià)值的資源。
下面是正文~~
深色模式是一種設(shè)計(jì)趨勢(shì),網(wǎng)站的配色方案被更改為深色背景,配以淺色文字和元素。它也被稱為夜間模式或黑暗主題。深色模式的目的是減少低光環(huán)境下的眼睛疲勞,節(jié)省移動(dòng)設(shè)備的電池壽命,并創(chuàng)造一個(gè)時(shí)尚現(xiàn)代的美感。
許多熱門(mén)網(wǎng)站和應(yīng)用程序現(xiàn)在都提供了黑暗模式選項(xiàng) —— 如 TailwindCSS:
如果您是開(kāi)發(fā)者,您很可能已經(jīng)知道如何在開(kāi)發(fā)者工具中切換暗黑模式:
如果你想要為操作系統(tǒng)(以及所有支持暗黑模式的應(yīng)用程序)切換暗黑模式,請(qǐng)轉(zhuǎn)到系統(tǒng)設(shè)置。在Mac上,可以在系統(tǒng)設(shè)置>外觀下找到它:
使用系統(tǒng)顏色的深色模式
首先,我們將創(chuàng)建一個(gè)帶有標(biāo)題的簡(jiǎn)單HTML:
<body>
<h1>Hello Darkness, My Old Friend</h1>
</body>
在樣式表中,添加:
body {
color-scheme: light dark;
}
這會(huì)告訴瀏覽器,document 可以接受亮色和暗色的 color-scheme 。
當(dāng)前如果現(xiàn)在指定為 dark 瀏覽器也不會(huì)變成黑色。
這是因?yàn)?nbsp;user-agent 樣式表沒(méi)有設(shè)置任何默認(rèn)顏色。我們可以通過(guò)使用系統(tǒng)顏色快速解決這個(gè)問(wèn)題:
body {
background-color: Canvas;
color: CanvasText;
color-scheme: light dark;
}
僅用3行CSS代碼就能為我們的整個(gè)網(wǎng)站實(shí)現(xiàn)暗黑模式!
下面,我們更深入地了解系統(tǒng)顏色,來(lái)自規(guī)范:
一般來(lái)說(shuō),<system-color>關(guān)鍵字反映了用戶、瀏覽器或操作系統(tǒng)做出的默認(rèn)顏色選擇。由于這個(gè)原因,它們通常在瀏覽器默認(rèn)樣式表中使用。
這是一個(gè)淺色模式演示,在Safari中展示了可用的系統(tǒng)顏色:
如果我們切換到深色模式,某些顏色會(huì)完全改變(就像我們已經(jīng)遇到的 Canvas 和 CanvasText ),而其他顏色只會(huì)稍微改變:
使用系統(tǒng)顏色進(jìn)行黑暗模式是一種簡(jiǎn)化的黑暗模式體驗(yàn)。是的,它會(huì)起作用 — 但是純黑白有點(diǎn)無(wú)聊
我們可以在CSS中使用 color-mix 來(lái)增加趣味性 將 CanvasText (黑色或白色)混入 Canvas (白色或黑色)以獲得 background-color ,反之亦然,用于 color :
body {
background-color: color-mix(in srgb, Canvas, CanvasText 2.5%);
color: color-mix(in srgb, CanvasText, Canvas 15%);
}
這樣看起來(lái)會(huì)更柔和:
從顏色中減去飽和度,是在深色模式中制作顏色變化的一種廣泛使用的方法。
在CSS中使用相對(duì)顏色,我們可以做到這一點(diǎn):
background: hsl(from ActiveText h calc(s - 30%) l);
不幸的是,相對(duì)顏色在任何瀏覽器中都不能與系統(tǒng)顏色一起工作。
注意:系統(tǒng)顏色可以被強(qiáng)制顏色覆蓋(盡管很少使用)——所以不要過(guò)分依賴這種技術(shù)。
我們繼續(xù)學(xué)習(xí)另一種技巧,這將使我們能夠精細(xì)控制我們的暗黑模式顏色。
使用 prefers-color-scheme 媒體查詢
要為亮色和暗色模式指定特定顏色,我建議使用 CSS 自定義屬性,然后使用 prefers-color-scheme 媒體查詢更新這些屬性。
以淺色模式為默認(rèn),我們將顏色添加到 :where(body) -部分,將它們與我們的常規(guī) body -樣式分開(kāi):
/* Properties */
:where(body) {
--background-color: #FFF;
--text-color: #222;
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
然后,對(duì)于暗黑模式,我們將簡(jiǎn)單地更新這些顏色屬性:
@media (prefers-color-scheme: dark) {
:where(body) {
--background-color: hsl(228, 5%, 15%);
--text-color: hsl(228, 5%, 80%);
}
}
但是,如果我們希望用戶根據(jù)自己的需求選擇我們網(wǎng)站的版本,而不是根據(jù)系統(tǒng)設(shè)置呢?
他們可能更喜歡將系統(tǒng)設(shè)置為深色模式,但我們的網(wǎng)站是淺色模式。讓我們創(chuàng)建一個(gè)切換器!如果您訪問(wèn)像 TailwindCSS 這樣的網(wǎng)站,您會(huì)注意到當(dāng)您從 color-scheme-toggler 中選擇“dark”時(shí),會(huì)在 html -節(jié)點(diǎn)上添加一個(gè) dark -類。這是通過(guò) JavaScript 完成的:
創(chuàng)建顏色方案切換器
如果你用過(guò) TailwindCSS ,你會(huì)注意到當(dāng)你從 color-scheme-toggler 中選擇“dark”時(shí),會(huì)在 html -節(jié)點(diǎn)上添加一個(gè) dark -類。這是通過(guò) JavaScript 完成的:
window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
Open Props 正在使用類似的方法,但是更新 data-theme 屬性,然后在兩個(gè)塊中定義屬性:
[data-theme=light] {
--nav-icon: var(--gray-7); /* etc */
}
[data-theme=dark] {
--nav-icon: var(--gray-5); /* etc */
}
使用 CSS
使用一些全新的CSS技術(shù),我們可以在不使用JavaScript的情況下創(chuàng)建一個(gè)切換器。我們將創(chuàng)建一個(gè)具有3種狀態(tài)的切換器:
- Light (forced)
- Auto (system default, could be either light or dark)
- Dark (forced)
首先,一些基本標(biāo)記:
<fieldset>
<label>
<input type="radio" name="color-scheme" id="color-scheme-light" value="0">
Light
</label>
<label>
<input type="radio" name="color-scheme" value="auto" checked>
Auto
</label>
<label>
<input type="radio" name="color-scheme" id="color-scheme-dark" value="1">
Dark
</label>
</fieldset>
在添加了一些基本樣式后(請(qǐng)參閱下面的Codepen演示),它的呈現(xiàn)效果如下:
我們將在html元素中添加一個(gè) --darkmode -屬性和 container-type :
html {
--darkmode: 0;
container-name: root;
container-type: normal;
}
我們使用 @container style() -查詢,因此我們需要將節(jié)點(diǎn)設(shè)置為“container”。
既然我們不想觀察到 inline-size 變化,我們只需添加值 normal 。
如果用戶選擇了一個(gè)“強(qiáng)制”值,我們將更新 --darkmode :
html:has(#color-scheme-light:checked) { --darkmode: 0; }
html:has(#color-scheme-dark:checked) { --darkmode: 1; }
最后,我們將使用容器 style() -查詢來(lái)檢查,如果 --darkmode 設(shè)置為 1 :
@container root style(--darkmode: 1) {
body {
--background-color: hsl(228, 5%, 15%);
--text-color: hsl(228, 5%, 80%);
}
}
注意:@container style() -queries 目前僅在 Chrome 中的 behind-a-flag 下工作,這還是初期階段,所以不要在生產(chǎn)環(huán)境中使用。
現(xiàn)在,在選擇“Dark”之后,我們的切換器(和頁(yè)面)看起來(lái)是這樣的:
存儲(chǔ)狀態(tài)
如果我們想要存儲(chǔ)用戶的選擇,就需要一點(diǎn)JavaScript!
首先,為 <fieldset> 添加一個(gè)標(biāo)識(shí)符:
<fieldset id="colorScheme">
接下來(lái),在JavaScript中:
const colorScheme = document.getElementById('colorScheme')
colorScheme.addEventListener('change', event => {
localStorage.setItem('color-scheme', event.target.value)
})
現(xiàn)在,我們只需要在文檔加載后將屬性設(shè)置為 localStorage -值:
window.addEventListener("load", event => {
const scheme = localStorage.getItem('color-scheme') || 'auto'
if (scheme) {
document.documentElement.style.setProperty('--darkmode', scheme)
}
})
要在切換器中選擇正確的模式,請(qǐng)將此添加到 if -塊:
const selected = [...colorScheme.elements].filter(element => element.value === scheme)
if (selected) selected[0].checked = true;
Toggler
事例:https://codepen.io/stoumann/pen/KKGNbQr
System Colors
https://codepen.io/stoumann/pen/GRYNPzy。