CSS/CSS3中的原生變數var詳解

来源:http://www.cnblogs.com/moqiutao/archive/2017/10/26/7735124.html
-Advertisement-
Play Games

使用語法 首先我們先來看一個例子:html代碼: css代碼: 實現效果: 結果是該DOM元素背景變成了黑色。 CSS中原生的變數定義語法是:--*,變數使用語法是:var(--*),其中*表示我們的變數名稱。關於命名這個東西,各種語言都有些顯示,例如CSS選擇器不能是數字開頭,JS中的變數是不能直 ...


使用語法

首先我們先來看一個例子:
html代碼:

<div class="element">這是一段文字</div>

css代碼:

.element {
  width:200px;
  height:200px;
  --main-bg-color: #000;
  color:#fff;
  background-color: var(--main-bg-color);
}

實現效果:

結果是該DOM元素背景變成了黑色。

CSS中原生的變數定義語法是:--*,變數使用語法是:var(--*),其中*表示我們的變數名稱。關於命名這個東西,各種語言都有些顯示,例如CSS選擇器不能是數字開頭,JS中的變數是不能直接數值的,但是,在CSS變數中,這些限制通通沒有,例如:

:root{
    --main-bg-color: #000;
}
.element {
    background-color: var(--main-bg-color);
}

註意:變數名稱不能包含$,[,^,(,%等字元,普通字元局限在只要是“數字[0-9]”“字母[a-zA-Z]”“下劃線_”和“短橫線-”這些組合,但是可以是中文,日文或者韓文,例如:

.element {
  width:200px;
  height:200px;
  --黑色: #000;
  color:#fff;
  background-color: var(--黑色);
}

css變數完整語法:
CSS變數使用的完整語法為:var( [, ]? ),用中文表示就是:var( <自定義屬性名> [, <預設值 ]? ),也即是如果我們沒有定義變數名稱,那麼就會使用後面的值作為其預設屬性值。
如下:

.element {
    background-color: var(--new-bg-color,#EE0000);
}

得到的結果當然是後面顏色的值的背景。

我們來看一下如果變數名稱不合法會出現什麼結果,看下麵例子:

body {
  --color: 20px;
  background-color: #369;
  background-color: var(--color, #cd0000);
}

請問,此時<body>的背景色是?

  • A. transparent
  • B. 20px
  • C. #369
  • D. #cd0000

答案是:A. transparent
CSS變數中,果發現變數值是不合法的,例如上面背景色顯然不能是20px,則使用背景色的預設值,也就是預設值代替,於是,上面CSS等同於:

body {
    --color: 20px;
    background-color: #369;
    background-color: transparent;
}

css變數在js中的應用

看如下例子,html代碼:

<div id="jsDom">這是一段文字</div>

css代碼:

#jsDom {
    --my-varwidth: 200px;
    background-color: #000;
    color:#fff;
    width:var(--my-varwidth);
    height:200px;
}

js代碼:

var element = document.getElementById('jsDom');
var curWidth = getComputedStyle(element).getPropertyValue("--my-varwidth");
console.log(curWidth); //200px

//設置過後該DOM元素的寬度變為了300px
element.style.setProperty("--my-varwidth", '300px');

如果樣式是寫到行間呢?那麼進行如下操作:
html代碼:

<div id="jsDom" style="--my-varwidth:400px;width:var(--my-varwidth);">這是一段文字</div>

js代碼:

var element = document.getElementById('jsDom');
var curWidth = element.style.getPropertyValue("--my-varwidth");
console.log(curWidth); //400px

瀏覽器相容

瀏覽器的相容如圖所示:

到目前位置IE11也不支持該css變數。

說到這兒感覺這個css變數也是很強大的,那麼它跟預處理器比較,你覺得哪個更好?下麵講一下預處理器的劣勢。

預處理器劣勢

預處理器變數不是實時的

也許令新手驚訝的是,預處理器局限性最常見的情況是Sass無法在媒體查詢中定義變數或使用@extend。

$gutter: 1em;
@media (min-width: 30em) {
     $gutter: 2em; 
} 
 .Container { 
     padding: $gutter; 
 }

上面代碼將編譯為:

.Container { 
     padding: 1em;
 }

上面結果可以看出來,媒體查詢塊被丟棄,變數賦值被忽略。

由於無法在匹配@media規則的基礎上改變變數,所以唯一的選擇是為每個媒體查詢分配一個唯一的變數,並單獨編寫每個變體。

預處理器變數不能級聯

每當使用變數,作用域的問題就不可避免的出現。這個變數應該設置為全局變數嗎?是否應該限定其範圍為文件或模塊?是否應該限制在塊中?

由於CSS最終目的是為HTML添加樣式,事實證明還有另一種有效的方法給變數限定作用域:DOM元素。但由於預處理器不在瀏覽器中運行並且無法看到標記,它們不能這樣做。

假設有一個網站,面對偏好較大文字的用戶,就向<html>元素添加類user-setting-large-text。當設置了這個類時,應當應用較大的$font-size變數賦值:

$font-size: 1em;
.user-setting-large-text {
    $font-size: 1.5em;
} 
body { 
    font-size: $font-size; 
}

但同樣,就像上面的媒體塊示例,Sass完全忽略了該變數的賦值,這意味著這是不可能發生的。編譯後的代碼如下:

body { 
    font-size: 1em;
}

預處理器變數不繼承

雖然繼承嚴格說來是級聯的一部分,之所以把它單獨分出來講,是因為多次想調用這個特性卻不得。

假設一種情況,要在DOM元素上基於其父元素應用的顏色而設置樣式:

.alert {
    background-color: lightyellow;
}
.alert.info {
    background-color: lightblue;
}
.alert.error {
    background-color: orangered;
}

.alert button {
    border-color: darken(background-color, 25%);
}

上面的代碼並不是有效的Sass(或CSS),但你應該明白它想達到什麼目的。

最後一句聲明試圖在<button>元素從父元素.alert元素繼承的background-color屬性使用Sassdarken函數。如果類infoerror已經加在了.alert上(或如果background-color已通過JavaScript或用戶樣式設置),button元素能據此作出相應的響應。

顯然這在Sass中行不通,因為預處理器不知道DOM結構,但希望你清楚的認識到為什麼這類東西是有用的。

調用一個特定的用例:出於可訪問性的原因,在繼承了DOM屬性上運行顏色函數是極其方便的。例如,確保文本始終可讀,並充分與背景顏色形成鮮明對比。 有了自定義屬性和新的CSS顏色函數,很快這將成為可能。

預處理器變數不可互操作

這是預處理器相對明顯的一個缺點,提到它是因為我覺得它重要。如果你正使用PostCSS來構建網站,想使用只能通過Sass實現主題化的第三方組件,那你真是不走運了。

跨不同的工具集或CDN上托管的第三方樣式表共用預處理器變數是不可能(或至少不容易)的。

原生的CSS自定義屬性可以與任何CSS預處理器或純CSS文件一起使用。反之則不然。

下麵給一個css變數在媒體查詢中的使用:

:root {
    --gutter: 1.5em;
}

@media (min-width: 30em) {
    :root {
        --gutter: 2em;
    }
}
@media (min-width: 48em) {
    :root {
        --gutter: 3em;
    }
}

如果是預處理器這樣寫就無效了。

參考

Using CSS custom properties (variables)
小tips:瞭解CSS/CSS3原生變數var
我為什麼對原生CSS變數感到興奮


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、概念 用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。 二、模式動機 當已有一個對像,暫且稱之為原型對象,需要一個新的對像,該對像和已有的原型對像具有相同的類型,且裡面的屬性大部分相同,或者只有個別不同時,這時就可以用原型模式,克隆原型對像,產生一個新的對像,並對新的對像屬性進行適 ...
  • 前幾天我寫了幾篇關於ELK日誌收集,存儲和分析的文章: ELK系列~NLog.Targets.Fluentd到達如何通過tcp發到fluentd ELK系列~Nxlog日誌收集加轉發(解決log4日誌換行導致json轉換失敗問題) ELK系列~log4-nxlog-Fluentd-elasticse ...
  • 一:觀察者模式簡單介紹 觀察者模式又稱為發佈-訂閱模式(publish/subscribe),該模式定義了一種,一對多的依賴關係,讓多個觀察者同時監聽一個主題對像,這個主題對像在狀態發生改變時,會通知所有的觀察者對像更新(執行業務邏輯)。示意圖如下: 觀察者角色介紹: 1:抽像主題角色(Subjec ...
  • 題目1:幾個同事為了在上班期間偷偷看休息,做點其他的事情,就和小秘偷偷聯繫了一下,如果老闆回來了,就麻煩小秘偷偷通知一聲,這樣方便大家及時變更自己的工作狀態。 分析: 根據題目分析,首先明確,肯定會有兩個類:小秘類和同事類,分別描述與記錄兩種類型的人和行為。 需要註意的是:小秘與同事構建聯繫的時候, ...
  • 經驗與實踐 前兩篇文章里我們介紹了nxlog的日誌收集和轉發《ELK系列~Nxlog日誌收集加轉發(解決log4日誌換行導致json轉換失敗問題)》,今天我們主要總結一下,在與log4和fluentd及elasticsearch配合工作時需要註意的幾個點,這幾個點也是我們經常遇到的坑,希望可以幫到大 ...
  • 設計模式(0)簡單工廠模式 設計模式(1)單例模式(Singleton) 設計模式(2)工廠方法模式(Factory Method) 設計模式(3)抽象工廠模式(Abstract Factory) 設計模式(4)建造者模式/生成器模式(Builder) 源碼地址 0 原型模式簡介 0.0 原型模式定 ...
  • Php常見錯誤提示 一、Fatal error: Call to undefined function……函數不存在,可能的原因:系統不存在這個函數且你也沒自定義 二、syntax error, unexpected T_STRING, expecting……嚴重語法錯誤,例如syntax erro ...
  • 本文章將會繼承上一篇文章,主要講通過工具來進行日誌的收集與發送,《ELK系列~NLog.Targets.Fluentd到達如何通過tcp發到fluentd》 Nxlog是一個日誌收集工具,它將系統日誌,或者指定的日誌文件,統配符文件找到,然後加工,最後發送到目標位置。而目標位置有很多種,如文件系統, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...