溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

CSS變量的使用問題怎么解決

發(fā)布時(shí)間:2022-04-21 11:13:47 來(lái)源:億速云 閱讀:169 作者:zzz 欄目:web開發(fā)

這篇文章主要講解了“CSS變量的使用問題怎么解決”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“CSS變量的使用問題怎么解決”吧!

CSS變量的使用問題怎么解決

1. 小心 !important

CSS 變量一起使用 !important 有點(diǎn)詭異,如下面的示范:

p {
  --color:red !important;

  color:var(--color);
  color:blue;
}

上面的 p 元素會(huì)是什么顏色呢?你會(huì)認(rèn)為是 red 紅色吧,認(rèn)為按如下代碼執(zhí)行:

p {
  color: red !important;
  color: blue;
}

但是,并不是 red 紅色,因?yàn)閷?shí)際執(zhí)行是這樣:

p {
  color: red;
  color: blue;
}

在這種情況下,!important 并不是 color 的一部分,而是增加了 --color 變量的特性。規(guī)范中指明:

注意:自定義屬性可以包含 !important ,但是會(huì)被 CSS 解析器自動(dòng)從屬性中刪除,這將自定義的屬性 important 變成層級(jí)。換言之, !important 并不是不會(huì)起作用,而是在語(yǔ)法檢查之前就被忽略了。

下面這個(gè)例子你會(huì)更容易明白:

p {
  --color: red !important;
  --color: blue;
  
  color: var(--color);
}

上面的代碼會(huì)賦予 p 元素紅色,解析如下:

  • 我們對(duì) --color 屬性有兩次的聲明,所以我們需要解決其層級(jí)的問題。第一次的定義帶有 !important ,所以它的層級(jí)相對(duì)高

  • 接著 var(--color) 將會(huì)應(yīng)用 red !important

  • 所以我們會(huì)得到 color: red

再來(lái)看一段代碼:

p{
  --color: red !important;
  --color: blue; 

  color:var(--color);  color: pink; <!-- 這里我改寫的顏色值 -->
}

按照上面的邏輯,我們最后會(huì)得到粉紅色 pink 的段落顏色。

一個(gè)很重要的規(guī)則是應(yīng)當(dāng)將 CSS 變量(自定義屬性)看作普通屬性,而不僅僅是存儲(chǔ)值的變量。

自定義屬性是普通屬性,所以它們可以被定義在任何的元素上,可以使用普通屬性的繼承和聯(lián)級(jí)規(guī)則解決,可以使用 @media 和其他條件規(guī)則進(jìn)行條件處理,可以用于 HTMLstyle 屬性,可使用 CSSDOM 讀取和設(shè)置等等。

2. 它們不可以存儲(chǔ) urls

總有一天你會(huì)偶然發(fā)現(xiàn)這個(gè)常見的限制。

你不能這樣做 ?

:root {
  --url:"https://picsum.photos/id/1/200/300";
}
.box {
  background:url(var(--url));
}

你應(yīng)該這樣做 ?

:root {
  --url:url("https://picsum.photos/id/1/200/300");
}
.box {
  background:var(--url);
}

這個(gè)限制有關(guān) url() 是怎么解析的。解析起來(lái)有點(diǎn)棘手,推薦你到 Stack Overflow Answer 上找答案。正如你所見,我們修復(fù)起來(lái)很容易,把 url() 整個(gè)賦予變量即可。

3. 它們可以無(wú)效的值變有效

這也是我喜歡的點(diǎn)之一,也是讓人頭疼的點(diǎn)。

我們以一個(gè)基礎(chǔ)的案例入手:

.box {
  background: red;
  background: linaer-gradient(red, blue);
}

.box 元素將會(huì)有一個(gè)紅藍(lán)漸變的效果,對(duì)吧?然而卻是純紅色。嗯,我打錯(cuò)了 linear-*。我可以很容易發(fā)現(xiàn)這個(gè)錯(cuò)誤,因?yàn)闉g覽器劃掉了這一行并啟用了上一行的背景樣式。

CSS變量的使用問題怎么解決

現(xiàn)在,讓我們來(lái)介紹變量:

.box {
  --color:red;
  background: var(--color);
  background: linaer-gradient(var(--color), blue);
}

測(cè)試這段代碼,你會(huì)發(fā)現(xiàn)背景顏色變成了透明。我們的第二個(gè)背景顏色并沒有被瀏覽器劃掉,反而是第一個(gè)背景樣式被劃掉了。因?yàn)榈诙€(gè)背景樣式重寫了第一個(gè)。

CSS變量的使用問題怎么解決

為什么會(huì)發(fā)生這樣的事情 ?

當(dāng)我們使用變量作為屬性,瀏覽器只會(huì)在 "計(jì)算值時(shí)間" 去評(píng)估值,因?yàn)槲覀冃枰紫戎雷兞康膬?nèi)容。在這種例子中,當(dāng)瀏覽器做聯(lián)級(jí)時(shí),會(huì)認(rèn)為屬性值是有效的,之后才會(huì)變成無(wú)效。

在我們的例子中,瀏覽器做級(jí)聯(lián)時(shí),認(rèn)為最后一個(gè)聲明是有效的。但是到評(píng)估值的時(shí)候,最后一個(gè)聲明被認(rèn)定是無(wú)效的,所以它被忽略。我們不會(huì)回頭查看,因?yàn)槲覀冊(cè)诩?jí)聯(lián)的時(shí)候已經(jīng)處理過了,所以我們最后會(huì)得到一個(gè)透明的背景顏色。

你可能認(rèn)為這種行為不符合邏輯的,但是它確符合邏輯。因?yàn)橐粋€(gè)值是有效還是無(wú)效時(shí)基于 CSS 變量的,所以瀏覽器一開始時(shí)不能真正知道。

.box {
  --color:10px; /* a "valid" variable */
  background: red; /* a "valid" declaration */
  background:linear-gradient(var(--color),blue); /* a "valid" declaration that will override the first one  */
  /* The result is an "invalid" value ... */ 
}

如果一個(gè)屬性包含一個(gè)或者更多的 var() 函數(shù),而且這些函數(shù)都是語(yǔ)法有效的,必須假定整個(gè)屬性的語(yǔ)法在解析時(shí)有效。當(dāng) var() 函數(shù)被替代后,在“計(jì)算值時(shí)間”才做語(yǔ)法檢查。

簡(jiǎn)單來(lái)說:CSS 變量將屬性的狀態(tài)作為一個(gè)后備,知道我們對(duì)其進(jìn)行評(píng)估值。當(dāng)評(píng)估值之后,我們可以說它是有效的或者無(wú)效的了。如果它是無(wú)效的,那么久太晚了,因?yàn)槲覀儾粫?huì)再回頭使用上一個(gè)。

4. 它們可以不被使用單位

大多數(shù)的教材或課程都會(huì)展示下面的代碼給你:

:root {
 --p: 10px;
}
.box {
  padding: var(--p);
}

但是,你也可以這么做:

:root {
 --p: 10;
}
.box {
  padding: calc(var(--p)*1px);
}

變量中擁有單位并不是強(qiáng)制的。

5. 他們可以動(dòng)起來(lái)

最初,CSS 變量被定義是沒有動(dòng)畫屬性的。

Animatable: no

但是,事情發(fā)生了變化,我們通過 @property 修飾,CSS 變量可以做一些動(dòng)畫或者漸變。這個(gè)特性目前瀏覽器支持比較低,但是也是時(shí)候了解下了。

6. 它們不可以存儲(chǔ) inherit

我們考慮下面的例子:

<div class="box">
  <div class="item"></div>
</div>
.box {
  border:2px solid red;
}
.item {
  --b:inherit;
  border:var(--b);
}

直覺告訴我們,.item 將會(huì)即成父元素的 border,因?yàn)?--b 包含 inherit,但是并不是。

正如我們?cè)诘?點(diǎn)上說到的,我們錯(cuò)誤認(rèn)為 CSS 變量會(huì)簡(jiǎn)單存儲(chǔ)值,然后供我們往后使用,然而并不會(huì)。CSS 變量(自定義的屬性)是普通屬性,所以 inherit 會(huì)被應(yīng)用并不會(huì)存儲(chǔ)值。

例子:

.box {
  --b:5px solid blue; /* we define the variable on the parent */
}
.item {
  --b:inherit; /* the child will inherit the same value so "5px solid blue"*/
  border:var(--b); /* we will have "5px solid blue" */
}

正如你所看到的,公共屬性應(yīng)用,邏輯上才可以繼承 inherit

上面的寫法是雞肋的,因?yàn)?CSS 變量默認(rèn)是繼承的。

7. 它們可以是空值

是的,你可以想下面這么做:

.box {
  --color: ;
  background:var(--color); 
}

筆記:<declatation-value> 聲明值必須代表一個(gè)標(biāo)記,所以變量空值需要有一個(gè)空格。比如 --foo: ; 是有效的,var(--foo) 將會(huì)返回一個(gè)空格。--foo:; 是無(wú)效的。如下:

.box {
  --color:; ?
  background:var(--color); 
}

CSS變量的使用問題怎么解決

這個(gè)小技巧可以配合預(yù)設(shè)特性實(shí)現(xiàn)一些想不到的效果。

一個(gè)例子你就會(huì)明白這個(gè)技巧:

.box {
  background:
   linear-gradient(blue,transparent)
   var(--color,red); # 沒有發(fā)現(xiàn)--color,取默認(rèn)值 red
}
<div class="box">
  I will have `background:linear-gradient(blue,transparent) red;`
</div>
<div class="box" style="--color:green">
  I will have `background:linear-gradient(blue,transparent) green;`
</div>
<div class="box" style="--color: ;">
  I will have `background:linear-gradient(blue,transparent)  ;`
</div>
  • 第一個(gè) box 沒有定義變量,所以預(yù)設(shè)值被使用

  • 第二個(gè)有定義的變量,所以它被使用

  • 最后一個(gè)設(shè)定了一個(gè)空的變量值,所以空值被使用。使用后就好比不需要 var(--color, red) 一樣

空值允許我們移除屬性中 var() 聲明,在一個(gè)復(fù)雜的值中使用 var() 作用挺大。

8. CSS 變量不是 C++ 變量

很不幸的是,很多開發(fā)者趨向于比較 CSS 變量和其他語(yǔ)言的變量,然后在他們邏輯上有一大堆的問題。正是這個(gè)原因,我都不想叫他們變量而是自定義屬性,因?yàn)樗麄兇_實(shí)是屬性。

很多人都想這么做:

:root {
  --p:5px;
  --p:calc(var(--p) + 1px); /* let's increment by 1px */
}
:root {
  --x: 5px;
  --y: 10px;
  /* let's do a variable switch */
  --c: var(--y);
  --y: var(--x);
  --x: var(--c);
}
.box {
  --s: 10px;
  margin:var(--s); /* I want 10px of margin */
  --s: 20px;
  padding:var(--s): /* then 20px of padding */
}

以上的示范都不能工作。第一個(gè)和第二個(gè)都有無(wú)效值,因?yàn)樗鼈兌加星短滓蕾?。最后一個(gè)例子,paddingmargin 都是 20px,因?yàn)榧?jí)聯(lián)會(huì)獲取第二個(gè) --s: 20px 的變量去應(yīng)用。

這很不幸,你應(yīng)該停止用 C++, Javascript, Java 等語(yǔ)言的思維去思考 CSS 變量,因?yàn)樗鼈冇凶约哼壿嫷淖远x屬性。

9. 它們只能從父元素傳遞給子元素

請(qǐng)記住這個(gè)黃金規(guī)則:CSS 變量總是從父元素(或者說祖先元素)傳遞給子元素,不會(huì)從子元素傳遞給父元素或兄弟元素。

:root {
  --c1: red;
  --c2: blue;
  --grad: linear-gradient(var(--c1),var(--c2);
}
.box {
  --c1: green;
  background:var(--grad);
}

你可以會(huì)認(rèn)為 .box 背景顏色是 linear-gradient(green, blue) ? 不,背景顏色會(huì)是 linear-gradient(red, blue)。

root 元素是 DOM 元素的最上層,所以它是 box 的祖先元素,我們應(yīng)用上面的黃金規(guī)則知道,子元素的 --c1 是跑不到 linear-gradient(var(--c1),var(--c2) 中的。

10. 它們可以有奇怪的語(yǔ)法

最后一個(gè)也是有趣的一個(gè)。

你知道你能像下面這樣寫么?

body {
  --:red;
  background:var(--);
}

很神奇,對(duì)吧?是的,CSS 變量可以僅使用兩節(jié)虛線定義。

你會(huì)認(rèn)為上面已經(jīng)很瘋狂了?看下下面這個(gè):

body {
 --?:red;
 --?:green; 
 --?:blue;
 --?:orange;
}

是的,你還可以用表情來(lái)定義一個(gè)變量。

CSS 變量允許你以 -- 開頭的任何內(nèi)容。比如:

body {
  ---------:red;
  background:var(---------);
}

又比如:

body {
  --?:red;
  --?:blue;
  background:linear-gradient(90deg, var(--?),var(--?));
}

其實(shí)上面是這樣的:

CSS變量的使用問題怎么解決

當(dāng)然你不會(huì)使用這么稀奇古怪的東西在你的實(shí)際項(xiàng)目中,除非你想讓你的老板或合作開發(fā)者發(fā)瘋

感謝各位的閱讀,以上就是“CSS變量的使用問題怎么解決”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)CSS變量的使用問題怎么解決這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

css
AI