CSS變量

2017年三月,微軟Edge 瀏覽器將支持 CSS 變量洋丐。(實(shí)測普通用戶安裝Windows后豪诲,不會升級版本,Edge的版本在18以下不支持CSS變量,啥時候中國用戶才能拋棄IE啊~~~)

這個重要的 CSS 新功能达椰,所有主要瀏覽器已經(jīng)都支持了翰蠢。本文全面介紹如何使用它,你會發(fā)現(xiàn)原生 CSS 從此變得異常強(qiáng)大啰劲。

一梁沧、變量的聲明

聲明變量的時候,變量名前面要加兩根連詞線(--)蝇裤。


body {
  --foo: #7F583F;
  --bar: #F7EFD2;
}

上面代碼中廷支,body選擇器里面聲明了兩個變量:--foo--bar频鉴。

它們與colorfont-size等正式屬性沒有什么不同恋拍,只是沒有默認(rèn)含義垛孔。所以 CSS 變量(CSS variable)又叫做"CSS 自定義屬性"(CSS custom properties)。因?yàn)樽兞颗c自定義的 CSS 屬性其實(shí)是一回事施敢。

你可能會問似炎,為什么選擇兩根連詞線(--)表示變量?因?yàn)?code>$foo被 Sass 用掉了悯姊,@foo被 Less 用掉了羡藐。為了不產(chǎn)生沖突,官方的 CSS 變量就改用兩根連詞線了悯许。

各種值都可以放入 CSS 變量仆嗦。


:root{
  --main-color: #4d4e53;
  --main-bg: rgb(255, 255, 255);
  --logo-border-color: rebeccapurple;

  --header-height: 68px;
  --content-padding: 10px 20px;

  --base-line-height: 1.428571429;
  --transition-duration: .35s;
  --external-link: "external link";
  --margin-top: calc(2vh + 20px);
}

變量名大小寫敏感,--header-color--Header-Color是兩個不同變量先壕。

二瘩扼、var() 函數(shù)

var()函數(shù)用于讀取變量。


a {
  color: var(--foo);
  text-decoration-color: var(--bar);
}

var()函數(shù)還可以使用第二個參數(shù)垃僚,表示變量的默認(rèn)值集绰。如果該變量不存在,就會使用這個默認(rèn)值谆棺。


color: var(--foo, #7F583F);

第二個參數(shù)不處理內(nèi)部的逗號或空格栽燕,都視作參數(shù)的一部分。


var(--font-stack, "Roboto", "Helvetica");
var(--pad, 10px 15px 20px);

var()函數(shù)還可以用在變量的聲明改淑。


:root {
  --primary-color: red;
  --logo-text: var(--primary-color);
}

注意碍岔,變量值只能用作屬性值,不能用作屬性名朵夏。


.foo {
  --side: margin-top;
  /* 無效 */
  var(--side): 20px;
}

上面代碼中蔼啦,變量--side用作屬性名,這是無效的仰猖。

三捏肢、變量值的類型

如果變量值是一個字符串,可以與其他字符串拼接饥侵。


--bar: 'hello';
--foo: var(--bar)' world';

利用這一點(diǎn)鸵赫,可以 debug(例子)。


body:after {
  content: '--screen-category : 'var(--screen-category);
}

如果變量值是數(shù)值爆捞,不能與數(shù)值單位直接連用奉瘤。


.foo {
  --gap: 20;
  /* 無效 */
  margin-top: var(--gap)px;
}

上面代碼中,數(shù)值與單位直接寫在一起,這是無效的盗温。必須使用calc()函數(shù)藕赞,將它們連接。


.foo {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}

如果變量值帶有單位卖局,就不能寫成字符串斧蜕。


/* 無效 */
.foo {
  --foo: '20px';
  font-size: var(--foo);
}

/* 有效 */
.foo {
  --foo: 20px;
  font-size: var(--foo);
}

四、作用域

同一個 CSS 變量砚偶,可以在多個選擇器內(nèi)聲明批销。讀取的時候,優(yōu)先級最高的聲明生效染坯。這與 CSS 的"層疊"(cascade)規(guī)則是一致的均芽。

下面是一個例子


<style>
  :root { --color: blue; }
  div { --color: green; }
  #alert { --color: red; }
  * { color: var(--color); }
</style>

<p>藍(lán)色</p>
<div>綠色</div>
<div id="alert">紅色</div>

上面代碼中单鹿,三個選擇器都聲明了--color變量掀宋。不同元素讀取這個變量的時候,會采用優(yōu)先級最高的規(guī)則仲锄,因此三段文字的顏色是不一樣的劲妙。

這就是說,變量的作用域就是它所在的選擇器的有效范圍儒喊。


body {
  --foo: #7F583F;
}

.content {
  --bar: #F7EFD2;
}

上面代碼中镣奋,變量--foo的作用域是body選擇器的生效范圍,--bar的作用域是.content選擇器的生效范圍怀愧。

由于這個原因侨颈,全局的變量通常放在根元素:root里面,確保任何選擇器都可以讀取它們掸驱。


:root {
  --main-color: #06c;
}

五肛搬、響應(yīng)式布局

CSS 是動態(tài)的,頁面的任何變化毕贼,都會導(dǎo)致采用的規(guī)則變化。

利用這個特點(diǎn)蛤奢,可以在響應(yīng)式布局的media命令里面聲明變量鬼癣,使得不同的屏幕寬度有不同的變量值。


body {
  --primary: #7F583F;
  --secondary: #F7EFD2;
}

a {
  color: var(--primary);
  text-decoration-color: var(--secondary);
}

@media screen and (min-width: 768px) {
  body {
    --primary:  #F7EFD2;
    --secondary: #7F583F;
  }
}

六啤贩、兼容性處理

對于不支持 CSS 變量的瀏覽器待秃,可以采用下面的寫法。


a {
  color: #7F583F;
  color: var(--primary);
}

也可以使用@support命令進(jìn)行檢測痹屹。


@supports ( (--a: 0)) {
  /* supported */
}

@supports ( not (--a: 0)) {
  /* not supported */
}

七章郁、JavaScript 操作

JavaScript 也可以檢測瀏覽器是否支持 CSS 變量。


const isSupported =
  window.CSS &&
  window.CSS.supports &&
  window.CSS.supports('--a', 0);

if (isSupported) {
  /* supported */
} else {
  /* not supported */
}

JavaScript 操作 CSS 變量的寫法如下。


// 設(shè)置變量
document.body.style.setProperty('--primary', '#7F583F');

// 讀取變量
document.body.style.getPropertyValue('--primary').trim();
// '#7F583F'

// 刪除變量
document.body.style.removeProperty('--primary');

這意味著暖庄,JavaScript 可以將任意值存入樣式表聊替。下面是一個監(jiān)聽事件的例子,事件信息被存入 CSS 變量培廓。


const docStyle = document.documentElement.style;

document.addEventListener('mousemove', (e) => {
  docStyle.setProperty('--mouse-x', e.clientX);
  docStyle.setProperty('--mouse-y', e.clientY);
});

那些對 CSS 無用的信息惹悄,也可以放入 CSS 變量。


--foo: if(x > 5) this.width = 10;

上面代碼中肩钠,--foo的值在 CSS 里面是無效語句泣港,但是可以被 JavaScript 讀取。這意味著价匠,可以把樣式設(shè)置寫在 CSS 變量中当纱,讓 JavaScript 讀取。

所以踩窖,CSS 變量提供了 JavaScript 與 CSS 通信的一種途徑拌汇。

PS.實(shí)測內(nèi)容為自己親身測試吠冤,主要內(nèi)容轉(zhuǎn)自阮一峰博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涧团,更是在濱河造成了極大的恐慌,老刑警劉巖掐隐,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窥淆,死亡現(xiàn)場離奇詭異,居然都是意外死亡滤灯,警方通過查閱死者的電腦和手機(jī)坪稽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鳞骤,“玉大人窒百,你說我怎么就攤上這事≡ゾ。” “怎么了篙梢?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長美旧。 經(jīng)常有香客問我渤滞,道長,這世上最難降的妖魔是什么榴嗅? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任妄呕,我火速辦了婚禮,結(jié)果婚禮上嗽测,老公的妹妹穿的比我還像新娘绪励。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布疏魏。 她就那樣靜靜地躺著停做,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蠢护。 梳的紋絲不亂的頭發(fā)上雅宾,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音葵硕,去河邊找鬼眉抬。 笑死,一個胖子當(dāng)著我的面吹牛懈凹,可吹牛的內(nèi)容都是我干的蜀变。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼介评,長吁一口氣:“原來是場噩夢啊……” “哼库北!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起们陆,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤寒瓦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坪仇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杂腰,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年椅文,在試婚紗的時候發(fā)現(xiàn)自己被綠了喂很。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡皆刺,死狀恐怖少辣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情羡蛾,我是刑警寧澤漓帅,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站痴怨,受9級特大地震影響煎殷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腿箩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劣摇。 院中可真熱鬧珠移,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浓瞪,卻和暖如春懈玻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乾颁。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工涂乌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人英岭。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓湾盒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诅妹。 傳聞我的和親對象是個殘疾皇子罚勾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355