攝影 | Eliott Reynajavascript
最近讀到一篇文章《Everything you need to know about CSS Variables》,讓我對 CSS 變量有了新的認識。下面將整理出來的跟本身感悟的地方與你們分享,但願能幫助到對 CSS 變量還只知其一;不知其二的同窗。css
咱們回憶 CSS 變量的使用方式:html
span {
/* 局部變量 --color */
--color: gold;
color: var(--color);
}
複製代碼
聲明 CSS 變量的時候,發現跟使用普通屬性是同樣的,這裏說的「同樣」是指:使用的位置同樣,而且使用的方式也同樣。java
只不過跟普通屬性相比,CSS 變量多了兩個連字符 --
做爲前綴,本質上就是個屬性。並且這類屬性都是開發者本身起的,屬性值也是咱們設置的,天然就是「自定義屬性」了。瀏覽器
不過特殊的地方在於,咱們可使用 var()
函數解析出這類屬性的屬性值:ide
color: var(--color);
/* 至關於 */
color: gold;
複製代碼
還有一點,CSS 變量既然是屬性,那麼就能夠像行內樣式那樣使用:函數
<span style="--color: gold; color: var(--color);">這段文本是金色的</span>
複製代碼
文章後面「使用 JS 操做 CSS 變量」一節,就是基於此種寫法實現的。以後會講到,我們先繼續往下看。ui
全局變量是這樣聲明的:spa
:root {
--color: gray;
}
複製代碼
:root
僞類命中的是文檔根元素 <html>
,也就說3d
:root {
--color: gray;
}
/* 至關於 */
html {
--color: gray;
}
複製代碼
根元素是文檔的最頂層元素,在它下面聲明的變量就是全局變量。對應的,不是全局的變量就是局部變量。
<style> :root { /* 全局變量 --color */ --color: gray; } p { /* 局部變量 --color */ --color: gold; color: var(--color); } </style>
這段文本是灰色的,<span>這段文本是金色的</span>
複製代碼
與 JS 做用域相似的是,局部變量會覆蓋全局中的同名變量。所以上面 <span>
裏的文本是金色的。
var()
解析出來的結果只能做爲屬性值使用下面這樣寫是不行的:
.mt-20px {
--mt: margin-top;
var(--mt): 20px; /* × 這種寫法是錯誤的 */
}
複製代碼
咱們想要多是這種結果:margin-top: 20px
,但觀察發現,瀏覽器並不會解析 var(--mt)
,並且提示這是一個未知屬性名。
下面這樣寫就沒有問題了:
.mt-20px {
--20px: 20px;
margin-top: var(--20px); /* √ 這樣寫就沒問題了 */
}
複製代碼
var()
的回退值(fallback)var()
功能符,還接受第二個參數,表示一個回退值——當變量不能成功解析時,就會使用這個回退值。
.header {
color: var(--header-color, blue);
}
複製代碼
上面代碼中,若是 --header-color
沒有聲明的話,就會使用回退值 blue
,做用有點相似於 JS 函數中的參數默認值。
calc()
作數學運算若是聲明的變量值中包含數學運算,就要包裝在 calc()
函數中。不然是無效運算。
像下面這種寫法就不對:
.font-40px {
--size: 20px * 2; /* × 錯誤的寫法 */
font-size: var(--size);
}
複製代碼
在瀏覽器中觀察,不會看見顯式的報錯,但 font-size
的最終解析值還是默認的 16px
。
這種錯誤寫法在瀏覽器中並不會顯式報錯
`font-size` 的最終的解析值還是 `16px`
須要這樣寫:
.font-40px {
--size: calc(20px * 2); /* √ 正確的寫法 */
font-size: var(--size);
}
複製代碼
calc()
函數的引入,爲在 CSS 中進行各類不一樣單位的混合數值運算(加、減、乘、除),帶來了極大的便捷:
.example {
/* 加 */
width: calc(100% + 1em);
/* 減 */
width: calc(100% - 80px);
/* 乘 */
width: calc(100% * .5);
/* 除 */
width: calc(100% / 6);
}
複製代碼
這裏拋磚引玉,更多的使用細節能夠查看 MDN 上的文檔。
JS 操做 CSS 變量的原理,是使用 DOM 對象的 style
屬性,它是一個 CSSStyleDeclaration
類型的對象。
咱們以前可能作過這樣的操做:
document.body.style.color = 'gold'
複製代碼
color
是標準屬性,能夠直接使用這種方式設置。CSS 變量則屬於非標準屬性,使用這種方法就不會起做用:
// × 錯誤的寫法,由於 --color 並非標準屬性
document.body.style['--color'] = 'gold'
複製代碼
但 CSSStyleDeclaration
上提供了一個 setProperty()
方法,能夠用來設置非標準屬性。語法以下:
style.setProperty(propertyName, value, priority);
所以,咱們能夠這麼作:
document.body.style.setProperty('--color', 'gold');
複製代碼
執行結果以下:
這樣,我們就能經過 JS 操做 CSS 變量了。
CSS 變量的使用,在必定程度上改變了咱們書寫、組織代碼的形式。其原理在於,咱們可以修改已有變量的值。
下面我舉兩個比較有表明性的案例:
咱們有四個主題色的按鈕,在不一樣的場景下使用。使用之前的寫法,是經過覆蓋屬性的方式實現的:
.btn {
color: #333;
background-color: #eee;
border: 0;
padding: .5rem;
cursor: pointer;
}
.btn-success {
color: #fff;
background-color: green;
}
.btn-error {
color: #fff;
background-color: red;
}
.btn-warning {
background-color: orange;
}
複製代碼
若是使用變量,就不須要覆蓋屬性,直接修改變量值便可。
.btn {
color: var(--btn-color, #333);
background-color: var(--btn-bg-color, #eee);
border: 0;
padding: .5rem;
}
.btn-success {
--btn-color: #fff;
--btn-bg-color: green;
}
.btn-error {
--btn-color: #fff;
--btn-bg-color: red;
}
.btn-warning {
--btn-bg-color: orange;
}
複製代碼
demo 地址查看這裏:codepen.io/zhangbao/pe…
先看看最終的效果圖:
demo 地址:codepen.io/zhangbao/pe…
實現原理是這樣的:咱們在拖拉 Range Input 的時候,獲取當前的 value 值,設置爲變量 --slider
的值,.color-boxes
使用了此變量設置自身的 Y 軸偏移度。
涉及到的核心代碼以下:
CSS:
.color-boxes {
transform: perspective(500px) rotateY( calc(var(--slider) * 1deg));
}
複製代碼
JS
const range = document.querySelector('.booth-slider')
range.addEventListener('input', handleSlider)
function handleSlider (e) {
document.documentElement.style.setProperty('--slider', e.target.value)
}
複製代碼
嗯,很神奇。
本篇文章是我在看了一篇技術文章後總結的知識點,並加上了本身的一些感悟。若是看完後幫到了你,我將感到萬分榮幸!😁
(完)