您好,登錄后才能下訂單哦!
這篇文章主要講解了“CSS變量的使用問題怎么解決”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“CSS變量的使用問題怎么解決”吧!
1. 小心 !important
與 CSS
變量一起使用 !important
有點詭異,如下面的示范:
p { --color:red !important; color:var(--color); color:blue; }
上面的 p
元素會是什么顏色呢?你會認為是 red
紅色吧,認為按如下代碼執行:
p { color: red !important; color: blue; }
但是,并不是 red
紅色,因為實際執行是這樣:
p { color: red; color: blue; }
在這種情況下,!important
并不是 color
的一部分,而是增加了 --color
變量的特性。規范中指明:
注意:自定義屬性可以包含
!important
,但是會被CSS
解析器自動從屬性中刪除,這將自定義的屬性 important 變成層級。換言之,!important
并不是不會起作用,而是在語法檢查之前就被忽略了。
下面這個例子你會更容易明白:
p { --color: red !important; --color: blue; color: var(--color); }
上面的代碼會賦予 p
元素紅色,解析如下:
我們對 --color
屬性有兩次的聲明,所以我們需要解決其層級的問題。第一次的定義帶有 !important
,所以它的層級相對高
接著 var(--color)
將會應用 red !important
所以我們會得到 color: red
再來看一段代碼:
p{ --color: red !important; --color: blue; color:var(--color); color: pink; <!-- 這里我改寫的顏色值 --> }
按照上面的邏輯,我們最后會得到粉紅色 pink
的段落顏色。
一個很重要的規則是應當將 CSS 變量(自定義屬性)看作普通屬性,而不僅僅是存儲值的變量。
自定義屬性是普通屬性,所以它們可以被定義在任何的元素上,可以使用普通屬性的繼承和聯級規則解決,可以使用
@media
和其他條件規則進行條件處理,可以用于HTML
的style
屬性,可使用CSSDOM
讀取和設置等等。
2. 它們不可以存儲 urls
總有一天你會偶然發現這個常見的限制。
你不能這樣做 ?
:root { --url:"https://picsum.photos/id/1/200/300"; } .box { background:url(var(--url)); }
你應該這樣做 ?
:root { --url:url("https://picsum.photos/id/1/200/300"); } .box { background:var(--url); }
這個限制有關 url()
是怎么解析的。解析起來有點棘手,推薦你到 Stack Overflow Answer 上找答案。正如你所見,我們修復起來很容易,把 url()
整個賦予變量即可。
3. 它們可以無效的值變有效
這也是我喜歡的點之一,也是讓人頭疼的點。
我們以一個基礎的案例入手:
.box { background: red; background: linaer-gradient(red, blue); }
.box
元素將會有一個紅藍漸變的效果,對吧?然而卻是純紅色。嗯,我打錯了 linear-*
。我可以很容易發現這個錯誤,因為瀏覽器劃掉了這一行并啟用了上一行的背景樣式。
現在,讓我們來介紹變量:
.box { --color:red; background: var(--color); background: linaer-gradient(var(--color), blue); }
測試這段代碼,你會發現背景顏色變成了透明。我們的第二個背景顏色并沒有被瀏覽器劃掉,反而是第一個背景樣式被劃掉了。因為第二個背景樣式重寫了第一個。
為什么會發生這樣的事情 ?
當我們使用變量作為屬性,瀏覽器只會在 "計算值時間" 去評估值,因為我們需要首先知道變量的內容。在這種例子中,當瀏覽器做聯級時,會認為屬性值是有效的,之后才會變成無效。
在我們的例子中,瀏覽器做級聯時,認為最后一個聲明是有效的。但是到評估值的時候,最后一個聲明被認定是無效的,所以它被忽略。我們不會回頭查看,因為我們在級聯的時候已經處理過了,所以我們最后會得到一個透明的背景顏色。
你可能認為這種行為不符合邏輯的,但是它確符合邏輯。因為一個值是有效還是無效時基于 CSS
變量的,所以瀏覽器一開始時不能真正知道。
.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 ... */ }
如果一個屬性包含一個或者更多的
var()
函數,而且這些函數都是語法有效的,必須假定整個屬性的語法在解析時有效。當var()
函數被替代后,在“計算值時間”才做語法檢查。
簡單來說:CSS
變量將屬性的狀態作為一個后備,知道我們對其進行評估值。當評估值之后,我們可以說它是有效的或者無效的了。如果它是無效的,那么久太晚了,因為我們不會再回頭使用上一個。
4. 它們可以不被使用單位
大多數的教材或課程都會展示下面的代碼給你:
:root { --p: 10px; } .box { padding: var(--p); }
但是,你也可以這么做:
:root { --p: 10; } .box { padding: calc(var(--p)*1px); }
變量中擁有單位并不是強制的。
5. 他們可以動起來
最初,CSS
變量被定義是沒有動畫屬性的。
Animatable: no
但是,事情發生了變化,我們通過 @property
修飾,CSS
變量可以做一些動畫或者漸變。這個特性目前瀏覽器支持比較低,但是也是時候了解下了。
6. 它們不可以存儲 inherit
值
我們考慮下面的例子:
<div class="box"> <div class="item"></div> </div>
.box { border:2px solid red; } .item { --b:inherit; border:var(--b); }
直覺告訴我們,.item
將會即成父元素的 border
,因為 --b
包含 inherit
,但是并不是。
正如我們在第1點上說到的,我們錯誤認為 CSS
變量會簡單存儲值,然后供我們往后使用,然而并不會。CSS
變量(自定義的屬性)是普通屬性,所以 inherit
會被應用并不會存儲值。
例子:
.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" */ }
正如你所看到的,公共屬性應用,邏輯上才可以繼承 inherit
。
上面的寫法是雞肋的,因為
CSS
變量默認是繼承的。
7. 它們可以是空值
是的,你可以想下面這么做:
.box { --color: ; background:var(--color); }
筆記:
<declatation-value>
聲明值必須代表一個標記,所以變量空值需要有一個空格。比如--foo: ;
是有效的,var(--foo)
將會返回一個空格。--foo:;
是無效的。如下:
.box { --color:; ? background:var(--color); }
這個小技巧可以配合預設特性實現一些想不到的效果。
一個例子你就會明白這個技巧:
.box { background: linear-gradient(blue,transparent) var(--color,red); # 沒有發現--color,取默認值 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>
第一個 box
沒有定義變量,所以預設值被使用
第二個有定義的變量,所以它被使用
最后一個設定了一個空的變量值,所以空值被使用。使用后就好比不需要 var(--color, red)
一樣
空值允許我們移除屬性中 var()
聲明,在一個復雜的值中使用 var()
作用挺大。
8. CSS 變量不是 C++ 變量
很不幸的是,很多開發者趨向于比較 CSS
變量和其他語言的變量,然后在他們邏輯上有一大堆的問題。正是這個原因,我都不想叫他們變量而是自定義屬性,因為他們確實是屬性。
很多人都想這么做:
: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 */ }
以上的示范都不能工作。第一個和第二個都有無效值,因為它們都有嵌套依賴。最后一個例子,padding
和 margin
都是 20px
,因為級聯會獲取第二個 --s: 20px
的變量去應用。
這很不幸,你應該停止用 C++, Javascript, Java
等語言的思維去思考 CSS
變量,因為它們有自己邏輯的自定義屬性。
9. 它們只能從父元素傳遞給子元素
請記住這個黃金規則:CSS 變量總是從父元素(或者說祖先元素)傳遞給子元素,不會從子元素傳遞給父元素或兄弟元素。
:root { --c1: red; --c2: blue; --grad: linear-gradient(var(--c1),var(--c2); } .box { --c1: green; background:var(--grad); }
你可以會認為 .box
背景顏色是 linear-gradient(green, blue)
? 不,背景顏色會是 linear-gradient(red, blue)
。
root
元素是 DOM
元素的最上層,所以它是 box
的祖先元素,我們應用上面的黃金規則知道,子元素的 --c1
是跑不到 linear-gradient(var(--c1),var(--c2)
中的。
10. 它們可以有奇怪的語法
最后一個也是有趣的一個。
你知道你能像下面這樣寫么?
body { --:red; background:var(--); }
很神奇,對吧?是的,CSS
變量可以僅使用兩節虛線定義。
你會認為上面已經很瘋狂了?看下下面這個:
body { --?:red; --?:green; --?:blue; --?:orange; }
是的,你還可以用表情來定義一個變量。
CSS
變量允許你以 --
開頭的任何內容。比如:
body { ---------:red; background:var(---------); }
又比如:
body { --?:red; --?:blue; background:linear-gradient(90deg, var(--?),var(--?)); }
其實上面是這樣的:
當然你不會使用這么稀奇古怪的東西在你的實際項目中,除非你想讓你的老板或合作開發者發瘋
感謝各位的閱讀,以上就是“CSS變量的使用問題怎么解決”的內容了,經過本文的學習后,相信大家對CSS變量的使用問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。