CCSS自定義屬性怎樣實(shí)現(xiàn)主題切換砌们?

在本教程中杆麸,我們將使用 CSS自定義屬性(也稱為CSS變量)來(lái)為簡(jiǎn)單的HTML頁(yè)面實(shí)現(xiàn)主題切換。 我們將創(chuàng)建暗黑和明亮的示例主題浪感,然后編寫JavaScript 以在用戶單擊按鈕時(shí)在兩者之間切換昔头。

就像在典型的編程語(yǔ)言中一樣,變量用于保存或存儲(chǔ)值影兽。 在CSS中揭斧,它們通常用于存儲(chǔ)顏色,字體名稱峻堰,字體大小讹开,長(zhǎng)度單位等。然后可以在樣式表中的多個(gè)位置引用和重用它們茧妒。 大多數(shù)開(kāi)發(fā)人員都會(huì)引用 “CSS變量” 萧吠,但官方名稱是 自定義屬性。

CSS自定義屬性可以修改可在整個(gè)樣式表中引用的變量。 以前贷腕,只有使用Sass等CSS預(yù)處理器才能實(shí)現(xiàn)這一點(diǎn)邻遏。

理解 :root 和 var()

在創(chuàng)建動(dòng)態(tài)主題示例之前怠褐,讓我們了解自定義屬性的基本基礎(chǔ)知識(shí)圃酵。

自定義屬性 是一個(gè)名稱以兩個(gè)連字符( - )開(kāi)頭的屬性悦施,如 --foo虐呻。 定義后可以使用 var() 引用的變量牧氮。 讓我們考慮這個(gè)例子:

CSS 代碼:

:root {? --bg-color: #000;? --text-color: #fff;}

在:root選擇器中定義自定義屬性意味著它們可以作用于全局文檔中所有元素琼腔。:root是一個(gè)CSS偽類,它匹配文檔的根元素 – <html>元素踱葛。它類似于 html 選擇器丹莲,但具有更高的優(yōu)先級(jí)。

您可以在文檔中的任何位置訪問(wèn) :root 中的自定義屬性的值:

CSS 代碼:

div {? color: var(--text-color);? background-color: var(--bg-color);}

您還可以在CSS變量中包含回退值尸诽。例如:

CSS 代碼:

div {? color: var(--text-color, #000);? background-color: var(--bg-color, #fff);}

如果未定義自定義屬性甥材,則使用其回退值代替。

除了?:root?或?html?選擇器之外的CSS選擇器內(nèi)定義的自定義屬性使變量可用于匹配元素及其子元素性含。

CSS自定義屬性與預(yù)處理器變量

諸如 Sass 之類的CSS預(yù)處理器通常用于輔助前端Web開(kāi)發(fā)洲赵。預(yù)處理器的其中一個(gè)有用功能就包括變量。但是Sass變量和CSS自定義屬性之間有什么區(qū)別商蕴?

CSS自定義屬性在現(xiàn)代瀏覽器中進(jìn)行本機(jī)解析叠萍。 預(yù)處理器變量需要編譯到標(biāo)準(zhǔn)CSS文件中,并且所有變量都轉(zhuǎn)換為值绪商。

JavaScript可以訪問(wèn)和修改自定義屬性苛谷。 預(yù)處理程序變量編譯一次,只有它們的最終值在客戶端上可用格郁。

編寫一個(gè)簡(jiǎn)單的HTML頁(yè)面

讓我們從為項(xiàng)目創(chuàng)建一個(gè)文件夾開(kāi)始:

BASH 代碼:

$ mkdir css-variables-theming

接下來(lái)抄腔,在項(xiàng)目的文件夾中添加一個(gè)?index.html?文件:

BASH 代碼:

$ cd css-variables-theming$ touch index.html

并添加以下內(nèi)容:

HTML 代碼:

Title

?
? ? ?
? ?

What is Lorem Ipsum?

? ?

Lorem Ipsum is simply dummy text of the printing and typesetting industry...

? Copyright 2018

我們使用?<nav>?標(biāo)簽添加一個(gè)導(dǎo)航欄,頁(yè)腳和容器?<div>?理张,容器中包含一個(gè)按鈕(用于在明暗主題之間切換)和一些虛擬?Lorem Ipsum?文本赫蛇。

為我們的HTML頁(yè)面編寫基本CSS

現(xiàn)在讓我們?yōu)轫?yè)面添加樣式。在?<head>?中使用內(nèi)聯(lián)?<style>?標(biāo)記的同一文件中添加以下CSS樣式:

HTML 代碼:

* {? margin: 0;}html{? height: 100%;}body{? height: 100%;? font-family: -apple-system, BlinkMacSystemFont“Segoe UI”, “Roboto”, “Oxygen”, “Ubuntu”, “Cantarell”, “Fira Sans”, “Droid Sans”, “Helvetica Neue”,sans-serif;? ? display: flex;? flex-direction: column;}nav{? background: hsl(350, 50%, 50%);? padding: 1.3rem;? color: hsl(350, 50%, 10%);}.container{? flex: 1;? background:hsl(350, 50%, 95%);? padding: 1rem;}p.content{? padding: 0.7rem;? font-size: 0.7rem;? color: hsl(350, 50%, 50%);}.container h2.title{? padding: 1rem;? color: hsl(350, 50%, 20%);}footer{? background: hsl(350, 93%, 88%);? padding: 1rem;}input[type=button] {? color:hsl(350, 50%, 20%);? padding: 0.3rem;? font-size: 1rem;}

CSS3 HSL(色調(diào)雾叭,飽和度悟耘,亮度)表示法用于定義顏色。 色調(diào)是色環(huán)上的角度织狐,示例使用350表示紅色暂幼。 通過(guò)更改飽和度(顏色百分比)和亮度(百分比),所有頁(yè)面顏色都使用不同的變化移迫。

使用HSL旺嬉,我們只需更改色調(diào)值,即可輕松嘗試主題的不同主色厨埋。 我們還可以使用CSS變量作為色調(diào)值邪媳,并通過(guò)更改樣式表中的單個(gè)值或使用JavaScript動(dòng)態(tài)更改顏色主題來(lái)切換顏色主題。

這是頁(yè)面的屏幕截圖:

我們將這個(gè)例子放到在線的 CodePen 中演示:

讓我們使用CSS變量來(lái)保存頁(yè)面中所有顏色的色調(diào)值。在 <style> 標(biāo)記頂部的 :root 選擇器中添加一個(gè)全局CSS變量:

CSS 代碼:

:root{? --main-hue : 350;}

接下來(lái)雨效,我們用 -main-hue 變量替換 hsl() 顏色中的所有硬編碼350值迅涮。例如,這是導(dǎo)航選擇器:

CSS 代碼:

nav{? background: hsl(var(--main-hue) , 50%, 50%);? padding: 1.3rem;? color: hsl(var(--main-hue), 50%, 10%);}

現(xiàn)在徽龟,如果要指定除紅色以外的其他顏色叮姑,則只需將相應(yīng)的值指定給 --main-hue 即可。這里有一些例子:

CSS 代碼:

:root{? --red-hue: 360;? --blue-hue: 240;? --green-hue: 120;? --main-hue : var(--red-hue);}

我們?yōu)榧t色据悔,藍(lán)色和綠色定義了三個(gè)自定義屬性传透,然后將 --red-hue 變量分配給--main-hue。

這是一個(gè)屏幕截圖极颓,其中包含不同值的頁(yè)面 --main-hue :

CSS自定義屬性提供了幾個(gè)好處:

可以在單獨(dú)位置定義值旷祸。

可以適當(dāng)?shù)孛撝狄詭椭S護(hù)和可讀性。

可以使用JavaScript動(dòng)態(tài)更改該值讼昆。 例如托享,--main-hue 可以設(shè)置為0到360之間的任何值。

使用JavaScript從一組預(yù)定義值或用戶提交的hue值(它應(yīng)該在0到360之間)動(dòng)態(tài)設(shè)置 --main-hue 的值浸赫,我們可以為用戶提供許多彩色主題的可能性闰围。

以下代碼行將 --main-hue 的值設(shè)置為240(藍(lán)色):

JavaScript 代碼:

document.documentElement.style.setProperty('--main-hue', 240);

查看以下 CodePen ,其顯示了一個(gè)完整示例既峡,允許您在紅色羡榴,藍(lán)色和綠色之間動(dòng)態(tài)切換主題:

他是頁(yè)面的截圖:

添加CSS暗黑主題

現(xiàn)在讓我們?yōu)檫@個(gè)頁(yè)面提供一個(gè)暗黑的主題。 為了更好地控制不同實(shí)體的顏色运敢,我們需要添加更多變量校仑。

通過(guò)頁(yè)面的樣式,我們可以在:root中定義對(duì)應(yīng)顏色的自定義屬性后传惠,用變量替換不同選擇器中的所有HSL顏色:

CSS 代碼:

:root{? /*...*/? --nav-bg-color: hsl(var(--main-hue) , 50%, 50%);? --nav-text-color: hsl(var(--main-hue), 50%, 10%);? --container-bg-color: hsl(var(--main-hue) , 50%, 95%);? --content-text-color: hsl(var(--main-hue) , 50%, 50%);? --title-color: hsl(var(--main-hue) , 50%, 20%);? --footer-bg-color: hsl(var(--main-hue) , 93%, 88%);? --button-text-color: hsl(var(--main-hue), 50%, 20%);}

使用了自定義屬性的適當(dāng)名稱迄沫。 例如, --nav-bg-color 是指導(dǎo)航背景的顏色卦方,而 --nav-text-color 是指導(dǎo)航前景/文本的顏色羊瘩。

現(xiàn)在復(fù)制 :root 選擇器及其內(nèi)容,但添加一個(gè)暗黑屬性值的主題:

CSS 代碼:

:root[theme='dark']{? /*...*/}

如果將具有dark值的 theme 屬性添加到 <html> 元素盼砍,則會(huì)激活此主題尘吗。

我們現(xiàn)在可以手動(dòng)插入這些變量的值,通過(guò)減少 HSL 顏色的亮度值來(lái)提供暗主題浇坐,或者我們可以使用其他技術(shù)睬捶,例如常用的 invert() 和 brightness() 等CSS濾鏡調(diào)整圖像的渲染,但也可以與任何其他元素一起使用近刘。

將以下代碼添加到 :root[theme='dark']:

CSS 代碼:

:root[theme='dark'] {? --red-hue: 360;? --blue-hue: 240;? --green-hue: 120;? --main-hue: var(--blue-hue);? --nav-bg-color: hsl(var(--main-hue), 50%, 90%);? --nav-text-color: hsl(var(--main-hue), 50%, 10%);? --container-bg-color: hsl(var(--main-hue), 50%, 95%);? --content-text-color: hsl(var(--main-hue), 50%, 50%);? --title-color: hsl(--main-hue, 50%, 20%);? --footer-bg-color: hsl(var(--main-hue), 93%, 88%);? --button-text-color: hsl(var(--main-hue), 50%, 20%);? filter: invert(1) brightness(0.6);}

invert() 過(guò)濾器反轉(zhuǎn)所選元素中的所有顏色(在這種情況下每個(gè)元素都會(huì)應(yīng)用)擒贸。 可以用百分比或數(shù)字指定反轉(zhuǎn)值臀晃。 值 100% 或 1 將完全反轉(zhuǎn)元素的色調(diào),飽和度和亮度值酗宋。

brightness() 濾鏡使元素更亮或更暗积仗。 值為 0 會(huì)導(dǎo)致完全黑色的元素疆拘。

invert() 濾鏡使一些元素非常明亮蜕猫。 通過(guò)設(shè)置 brightness(0.6) 來(lái)降低這些要求。

暗黑主題哎迄,不同程度的色調(diào):

使用JavaScript切換主題

現(xiàn)在回右,當(dāng)用戶點(diǎn)擊 Dark / Light 按鈕時(shí),我們現(xiàn)在使用JavaScript在暗黑和高亮主題之間切換漱挚。 在 index.html 中翔烁,使用以下代碼在結(jié)束 </body> 之前添加內(nèi)聯(lián) <script> :

JavaScript 代碼:

const toggleBtn = document.querySelector("#toggle-theme");toggleBtn.addEventListener('click', e => {? console.log("Switching theme"); if(document.documentElement.hasAttribute('theme')){? ? document.documentElement.removeAttribute('theme');? } else{? ? document.documentElement.setAttribute('theme', 'dark');? }});

document.documentElement 引用文檔的根DOM元素 – 即 <html> 元素。 此代碼使用 .hasAttribute() 方法檢查 theme 屬性是否存在旨涝,如果該屬性不存在則添加 dark 值蹬屹,從而導(dǎo)致切換到暗黑主題。 否則白华,它會(huì)刪除該屬性慨默,從而切換到高亮主題。

使用JavaScript更改CSS自定義屬性

使用JavaScript弧腥,我們可以訪問(wèn)自定義屬性并動(dòng)態(tài)更改其值厦取。 在我們的示例中,我們對(duì)亮度值進(jìn)行了硬編碼管搪,但它可以動(dòng)態(tài)更改虾攻。 首先,在 Dark / Light 按鈕旁邊的 HTML 頁(yè)面中添加 slider input:

HTML 代碼:

slider 從?1?開(kāi)始更鲁,允許用戶將其減小到?0.3?霎箍,步長(zhǎng)為?0.1?。

接下來(lái)澡为,在:root[theme='dark']中為暗度值添加一個(gè)自定義屬性朋沮,初始值為1?:

CSS 代碼:

:root[theme='dark']{ /*...*/? --theme-darkness: 1;}

將?brightness?濾鏡更改為此自定義屬性而不是硬編碼值:

CSS 代碼:

filter: invert(1) brightness(var(--theme-darkness));

最后,添加以下代碼以將?--theme-darkness?的值與 slider 值同步:

JavaScript 代碼:

const darknessSlider = document.querySelector("#darknessSlider");darknessSlider.addEventListener('change', (e)=>{ const val = darknessSlider.value? document.documentElement.style.setProperty('--theme-darkness', val);});

我們正在監(jiān)聽(tīng)滑塊的?change?事件缀壤,并使用?setProperty()?方法相應(yīng)地設(shè)置?--theme-darkness?的值樊拓。

我們還可以將?brightness?濾鏡應(yīng)用于高亮主題。 在?:root?選擇器的頂部添加?--theme-darkness?自定義屬性:

CSS 代碼:

:root{ /*...*/? --theme-darkness: 1;}

然后在同一選擇器的底部添加?brightness?濾鏡:

CSS 代碼:

:root{ /*...*/? filter: brightness(var(--theme-darkness));}

您可以在以下在線的 CodePen 中演示中找到此示例的完整代碼:

這是最后一個(gè)例子的暗黑主題的截圖:

這個(gè)是高亮主題的截圖:

結(jié)論

在本教程中塘慕,我們已經(jīng)了解了如何使用CSS自定義屬性來(lái)創(chuàng)建主題并在它們之間動(dòng)態(tài)切換筋夏。 我們使用了HSL配色方案,它允許我們指定具有色調(diào)图呢,飽和度和亮度值的顏色以及CSS濾鏡(invert 和brightness)以創(chuàng)建淺色主題的暗色版本条篷。

來(lái)源:https://www.sitepoint.com/css-theming-custom-properties-javascript/

如果您在web學(xué)習(xí)的過(guò)程中遇到難題骗随,歡迎關(guān)注微信公眾號(hào)【筑夢(mèng)前端】,大家一起交流解決赴叹!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸿染,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乞巧,更是在濱河造成了極大的恐慌涨椒,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绽媒,死亡現(xiàn)場(chǎng)離奇詭異蚕冬,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)是辕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門囤热,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人获三,你說(shuō)我怎么就攤上這事旁蔼。” “怎么了疙教?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵棺聊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我松逊,道長(zhǎng)躺屁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任经宏,我火速辦了婚禮犀暑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烁兰。我一直安慰自己耐亏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布沪斟。 她就那樣靜靜地躺著广辰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪主之。 梳的紋絲不亂的頭發(fā)上择吊,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音槽奕,去河邊找鬼几睛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛粤攒,可吹牛的內(nèi)容都是我干的所森。 我是一名探鬼主播囱持,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼焕济!你這毒婦竟也來(lái)了纷妆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晴弃,失蹤者是張志新(化名)和其女友劉穎掩幢,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肝匆,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粒蜈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年顺献,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旗国。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡注整,死狀恐怖能曾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肿轨,我是刑警寧澤寿冕,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站椒袍,受9級(jí)特大地震影響驼唱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驹暑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一玫恳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧优俘,春花似錦京办、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至叶雹,卻和暖如春财饥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背折晦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工钥星, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筋遭。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓打颤,卻偏偏與公主長(zhǎng)得像暴拄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子编饺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容