首頁 > web前端 > css教學 > 主體

關於 CSS 變數的一些你可能不了解的事!

青灯夜游
發布: 2022-04-21 10:34:31
轉載
2689 人瀏覽過

這篇文章帶大家了解一下CSS 變量,介紹下沒人告訴你關於 CSS 變數的那些事。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

關於 CSS 變數的一些你可能不了解的事!

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 和其他條件規則進行條件處理,可以用於HTMLstyle 屬性,可使用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-*。我可以很容易發現這個錯誤,因為瀏覽器劃掉了這一行並啟用了上一行的背景樣式。

關於 CSS 變數的一些你可能不了解的事!

現在,讓我們來介紹變數:

.box {
  --color:red;
  background: var(--color);
  background: linaer-gradient(var(--color), blue);
}
登入後複製

測試這段程式碼,你會發現背景顏色變成了透明。我們的第二個背景顏色並沒有被瀏覽器劃掉,反而是第一個背景樣式被劃掉了。因為第二個背景樣式重寫了第一個。

關於 CSS 變數的一些你可能不了解的事!

為什麼會發生這樣的事情 ?

當我們使用變數作為屬性,瀏覽器只會在 "計算值時間" 去評估值,因為我們需要先知道變數的內容。在這種範例中,當瀏覽器做聯級時,會認為屬性值是有效的,之後才會變成無效。

在我们的例子中,浏览器做级联时,认为最后一个声明是有效的。但是到评估值的时候,最后一个声明被认定是无效的,所以它被忽略。我们不会回头查看,因为我们在级联的时候已经处理过了,所以我们最后会得到一个透明的背景颜色。

你可能认为这种行为不符合逻辑的,但是它确符合逻辑。因为一个值是有效还是无效时基于 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. 它们不可以存储 <span style="font-size: 18px;">inherit</span>

我们考虑下面的例子:

<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); 
}
登入後複製

關於 CSS 變數的一些你可能不了解的事!

这个小技巧可以配合预设特性实现一些想不到的效果。

一个例子你就会明白这个技巧:

.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&#39;s increment by 1px */
}
登入後複製
:root {
  --x: 5px;
  --y: 10px;
  /* let&#39;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 */
}
登入後複製

以上的示范都不能工作。第一个和第二个都有无效值,因为它们都有嵌套依赖。最后一个例子,paddingmargin 都是 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 变量整理了出来。如果有一天你工作中需要这些知识点,你可以回头来看。

英文原文地址:https://dev.to/afif/what-no-one-told-you-about-css-variables-553o

本文是译文,采用意译。

(学习视频分享:web前端

以上是關於 CSS 變數的一些你可能不了解的事!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
css
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板