純CSS一分鐘讓網站擁有暗黑模式切換功能
暗黑模式這個概念最早起源于MacOS系統的Mojave,提供淺色主題和深色主題兩種皮膚供用戶選擇,深色主題就是我們常說的暗黑模式。為了眼睛健康,筆者在手機、平板和電腦上都選擇了暗黑模式。
隨著蘋果官方逐漸要求各大系統平臺都得適配暗黑模式,所以筆者也探索出一種應該是市面上最低成本的網站暗黑模式適配方案。
很多同學可能覺得這個方案只能使用JS實現,其實可使用純CSS實現。
思路很簡單,使用一個按鈕來回切換主題樣式。按鈕未選中則切換到淺色主題,按鈕選中則切換到深色主題??捎?checked和+/~打輔助完成這個任務。
:checked:選項選中的表單元素
+:元素相鄰的同胞元素
~:元素后面的同胞元素
使用<input>模擬按鈕,當按鈕處于選中狀態時觸發:checked,通過+/~帶動后面相鄰的網站主體<div>進入暗黑模式,選中狀態取消時則退出暗黑模式。
切換按鈕
打算設計一個美觀的按鈕,可是沒有特別思路,就打開iPhone,把設置里的切換按鈕用純CSS實現一番。
<input class="ios-switch" type="checkbox"> .btn { border-radius: 31px; width: 102px; height: 62px; background-color: #e9e9eb; } .ios-switch { position: relative; appearance: none; cursor: pointer; transition: all 100ms; @extend .btn; &::before { position: absolute; content: ""; transition: all 300ms cubic-bezier(.45, 1, .4, 1); @extend .btn; } &::after { position: absolute; left: 4px; top: 4px; border-radius: 27px; width: 54px; height: 54px; background-color: #fff; box-shadow: 1px 1px 5px rgba(#000, .3); content: ""; transition: all 300ms cubic-bezier(.4, .4, .25, 1.35); } &:checked { background-color: #5eb662; &::before { transform: scale(0); } &::after { transform: translateX(40px); } } }
尺寸和顏色都是與iPhone切換按鈕一致。思路是使用<input>模擬按鈕,聲明appearance:none將其默認外觀抹去,使用::before模擬背景區域,使用::after模擬點擊區域,在觸發:checked后添加一些小動畫進行修飾,近乎完美地實現了iPhone切換按鈕。
暗黑模式
巧妙地使用filter這個強大的CSS屬性。
html {
filter:grayscale(1);
}
一行代碼全站進入暗黑模式。
html {
filter: invert(1) hue-rotate(180deg);
}
filter的兼容性不差,各位同學可放心使用,還有一些細節地方需注意。
filter是一個非常神奇的屬性,能將Photoshop一些基礎的濾鏡效果應用到網站上。筆者平時非常喜歡使用filter,在筆者的CodePen上有許多純CSS特效都使用了filter,細心的同學可能會發現筆者特別喜歡使用hue-rotate()這個函數結合CSS變量動態生成過渡顏色。
本次的暗黑模式使用到兩個濾鏡函數:invert()、hue-rotate()。
invert():反相,反向輸出圖像著色,值為0%則無變化,值為0~100%則是線性乘子效果,值為100%則完全反轉
hue-rotate():色相旋轉,減弱圖像著色,處理非黑白的顏色,值為0deg則無變化,值為0~360deg則逐漸減弱,值超過360deg則相當繞N圈再計算剩余的值
invert()簡單理解就是黑變白,白變黑,黑白顛倒。hue-rotate()簡單理解就是沖淡顏色。為了確保主題色調不會改變,將色相旋轉聲明為180deg比較合理。
依據上述分析的思路,當按鈕處于選中狀態時使用+/~連帶后面的同胞元素也進入選中狀態。若同胞元素無背景色需聲明background-color:#fff,否則無法讓濾鏡效果起效,為了讓這個同胞元素在使用濾鏡效果時過渡得更自然,聲明transition:all 300ms。
.ios-switch {
...
&:checked {
...
& + .main {
filter: invert(1) hue-rotate(180deg);
}
}
}
.main {
background-color: #fff;
transition: all 300ms;
}
在CodePen上為了更好地展示效果,就使用<iframe>引入我們最愛的搜狐門戶,免費為其增加暗黑模式切換功能