新聞中心
前言

十多年的安居網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整安居建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)公司從事“安居網(wǎng)站設(shè)計”,“安居網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
「CSS變量」又叫「CSS自定義屬性」,為什么會突然提起這個很少人用到的東西呢?因為最近在重構(gòu)個人官網(wǎng),不知道為什么突然喜歡用上「CSS變量」,可能其自身隱藏的魅力,讓筆者對它刮目相看。
談到為什么會在CSS中使用變量,下面舉個栗子,估計大家一看就會明白。
- /* 不使用CSS變量 */
- .title {
- background-color: red;
- }
- .desc {
- background-color: red;
- }
- /* 使用CSS變量 */
- :root {
- --bg-color: red;
- }
- .title {
- background-color: var(--bg-color);
- }
- .desc {
- background-color: var(--bg-color);
- }
看完可能會覺得使用「CSS變量」的代碼量多了一點,但是有沒有想到突然某天萬惡的策劃小哥哥和設(shè)計小姐姐說要做一個換膚功能。按照平常的思路,估計有些同學就會按照默認顏色主題增加一份對照的新顏色主題CSS文件。這樣每次新增需求都同時維護幾套主題顏色多麻煩啊。
此時「CSS變量」就派上用場了,提前跟設(shè)計小姐姐規(guī)范好各種需要變換的顏色并通過「CSS變量」進行定義,通過JS批量操作這些定義好的「CSS變量」即可。這也是「變換主題顏色」的一種解決方案之一,好處在于只需寫一套CSS代碼。
- ["red", "blue", "green"].forEach(v => {
- const btn = document.getElementById(`${v}-theme-btn`);
- btn.addEventListener("click", () => document.body.style.setProperty("--bg-color", v));
- });
在此總結(jié)下CSS使用變量的好處:
- 減少樣式代碼的重復性
- 增加樣式代碼的擴展性
- 提高樣式代碼的靈活性
- 增多一種CSS與JS的通訊方式
- 不用深層遍歷DOM改變某個樣式
可能有些同學會問,Sass和Less早就實現(xiàn)了變量這個特性,何必再多此一舉呢??墒羌毾胍幌?,「CSS變量」對比Sass和Less的變量,又有它的過人之處。
- 瀏覽器原生特性,無需經(jīng)過任何轉(zhuǎn)譯就可直接運行
- DOM對象一員,極大便利了CSS與JS之間的聯(lián)系
認識
本來打算用一半篇幅講述「CSS變量」的規(guī)范和用法,但是網(wǎng)上一搜一大把就感覺沒必要了,貼上阮一峰老師寫的教程《CSS變量教程》。同時筆者也對「CSS變量」的細節(jié)地方進行一個整理,方便大家記憶。
- 聲明:--變量名
- 讀?。簐ar(--變量名, 默認值)
- 類型
- 普通:只能用作屬性值不能用作屬性名
- 字符:與字符串拼接 "Hello, "var(--name)
- 數(shù)值:使用calc()與數(shù)值單位連用 var(--width) * 10px
- 作用域
- 范圍:在當前元素塊作用域及其子元素塊作用域下有效
- 優(yōu)先級別:內(nèi)聯(lián)樣式 > ID選擇器 > 類選擇器 = 屬性選擇器 = 偽類選擇器 > 標簽選擇器 = 偽元素選擇器
接下來使用幾個特別的場景展示「CSS變量」的魅力。還是那句話,「一樣東西有使用的場景,那自然就會有它的價值」,那么用的人也會越來越多。
使用場景
其實「CSS變量」有一個特別好用的場景,那就是結(jié)合List元素集合使用。如果不明白這是什么,請繼續(xù)往下看。
- 以下所有演示代碼基于Vue文件,但HTML、CSS和JS分開書寫,為了簡化CSS的書寫而使用Sass進行預處理,方便代碼演示
條形加載條
一個條形加載條通常由幾條線條組成,并且每條線條對應(yīng)一個存在不同時延的相同動畫,通過時間差運行相同的動畫,從而產(chǎn)生加載效果。估計大部分的同學可能會把CSS代碼寫成以下這樣。
- .loading {
- width: 200px;
- height: 200px;
- li {
- border-radius: 3px;
- width: 6px;
- height: 30px;
- background-color: #f66;
- animation: beat 1s ease-in-out infinite;
- & + li {
- margin-left: 5px;
- }
- &:nth-child(2) {
- animation-delay: 200ms;
- }
- &:nth-child(3) {
- animation-delay: 400ms;
- }
- &:nth-child(4) {
- animation-delay: 600ms;
- }
- &:nth-child(5) {
- animation-delay: 800ms;
- }
- &:nth-child(6) {
- animation-delay: 1s;
- }
- }
- }
分析代碼發(fā)現(xiàn),每個
顯然這種方法不靈活也不容易封裝成組件,如果能像JS那樣封裝成一個函數(shù),并根據(jù)參數(shù)輸出不同的樣式效果,那就更棒了。說到這里,很明顯就是為了鋪墊「CSS變量」的開發(fā)技巧了。
對于HTML部分的修改,讓每個
- .strip-loading {
- width: 200px;
- height: 200px;
- li {
- --time: calc((var(--line-index) - 1) * 200ms);
- border-radius: 3px;
- width: 6px;
- height: 30px;
- background-color: #f66;
- animation: beat 1.5s ease-in-out var(--time) infinite;
- & + li {
- margin-left: 5px;
- }
- }
- }
- 源碼鏈接可在文章結(jié)尾處獲取
代碼中的變量--line-index和--time使每個
這就是「CSS變量」的作用范圍所致(在當前元素塊作用域及其子元素塊作用域下有效),因此在.strip-loading的塊作用域下調(diào)用--line-index是無效的。
- /* flex屬性無效 */
- .loading {
- display: flex;
- align-items: center;
- flex: var(--line-index);
- }
通過妙用「CSS變量」,也把CSS代碼從29行縮減到15行,對于那些含有List元素集合越多的場景,效果就更明顯。而且這樣寫也更加美觀更加容易維護,某天說加載效果的時間差不明顯,直接將calc((var(--line-index) - 1) * 200ms)里的200ms調(diào)整成400ms即可。就無需對每個:nth-child(n)進行修改了。
心形加載條
前段時間刷掘金看到陳大魚頭兄的心形加載條,覺得挺漂亮的,很帶感覺。
通過動圖分析,發(fā)現(xiàn)每條線條的背景色和動畫時延不一致,另外動畫運行時的高度也不一致。細心的你可能還會發(fā)現(xiàn),第1條和第9條的高度一致,第2條和第8條的高度一致,依次類推,得到高度變換相同類的公式:對稱index = 總數(shù) + 1 - index。
背景色使用了濾鏡的色相旋轉(zhuǎn)hue-rotate函數(shù),目的是為了使顏色過渡得更加自然;動畫時延的設(shè)置和上面條形加載條的設(shè)置一致。下面就用「CSS變量」根據(jù)看到的動圖實現(xiàn)一番。
- .heart-loading {
- width: 200px;
- height: 200px;
- ul {
- display: flex;
- justify-content: space-between;
- width: 150px;
- height: 10px;
- }
- li {
- --Θ: calc(var(--line-index) / var(--line-count) * .5turn);
- --time: calc((var(--line-index) - 1) * 40ms);
- border-radius: 5px;
- width: 10px;
- height: 10px;
- background-color: #3c9;
- filter: hue-rotate(var(--Θ));
- animation-duration: 1s;
- animation-delay: var(--time);
- animation-iteration-count: infinite;
- }
- .line-1,
- .line-9 {
- animation-name: line-move-1;
- }
- .line-2,
- .line-8 {
- animation-name: line-move-2;
- }
- .line-3,
- .line-7 {
- animation-name: line-move-3;
- }
- .line-4,
- .line-6 {
- animation-name: line-move-4;
- }
- .line-5 {
- animation-name: line-move-5;
- }
- }
- 源碼鏈接可在文章結(jié)尾處獲取
一波操作后就有了下面的效果。和陳大魚頭兄的心形加載條對比一下,顏色、波動曲線和跳動頻率有點不一樣,在暖色調(diào)的蔓延和腎上腺素的飆升下,這是一種心動的感覺。想起自己曾經(jīng)寫的一首詩:我見猶憐,愛不釋手,雅俗共賞,君子好逑。
標簽導航欄
上面通過兩個加載條演示了「CSS變量」在CSS中的運用以及一些妙用技巧,現(xiàn)在通過標簽導航欄演示「CSS變量」在JS中的運用。
JS中主要有3個操作「CSS變量」的API,看上去簡單易記,分別如下:
- 讀取變量:elem.style.getPropertyValue()
- 設(shè)置變量:elem.style.setProperty()
- 刪除變量:elem.style.removeProperty()
先上效果圖,效果中主要是使用「CSS變量」標記每個Tab的背景色和切換Tab的顯示狀態(tài)。
- .tab-navbar {
- display: flex;
- overflow: hidden;
- flex-direction: column-reverse;
- border-radius: 10px;
- width: 300px;
- height: 400px;
- nav {
- display: flex;
- height: 40px;
- background-color: #f0f0f0;
- line-height: 40px;
- text-align: center;
- a {
- flex: 1;
- cursor: pointer;
- transition: all 300ms;
- &.active {
- background-color: #66f;
- font-weight: bold;
- color: #fff;
- }
- }
- }
- div {
- flex: 1;
- ul {
- --tab-index: 0;
- --tab-width: calc(var(--tab-count) * 100%);
- --tab-move: calc(var(--tab-index) / var(--tab-count) * -100%);
- display: flex;
- flex-wrap: nowrap;
- width: var(--tab-width);
- height: 100%;
- transform: translate3d(var(--tab-move), 0, 0);
- transition: all 300ms;
- }
- li {
- display: flex;
- justify-content: center;
- align-items: center;
- flex: 1;
- background-color: var(--bg-color);
- font-weight: bold;
- font-size: 20px;
- color: #fff;
- }
- }
- }
- exportdefault {
- data() {
- return {
- index: 0,
- list: ["#f66", "#09f", "#3c9"]
- };
- },
- methods: {
- select(i) {
- this.index = i;
- this.$refs.tabs.style.setProperty("--tab-index", i);
- }
- }
- };
- 源碼鏈接可在文章結(jié)尾處獲取
在
- 上定義--tab-index表示Tab當前的索引,當點擊按鈕時重置--tab-index的值,就可實現(xiàn)不操作DOM來移動
- 上定義--bg-color表示Tab的背景色,也是一種比較簡潔的模板賦值方式,總比寫
- 要好看。如果多個CSS屬性依賴一個變量賦值,那么使用「CSS變量」賦值到style上就更方便了,那些CSS屬性可在CSS文件里進行計算與賦值,這樣可幫助JS分擔一些屬性計算工作。
當然,這個標簽導航欄也可通過純CSS實現(xiàn),有興趣的同學可看看筆者之前一篇文章里的純CSS標簽導航欄。
懸浮跟蹤按鈕
通過幾個栗子實踐了「CSS變量」在CSS和JS上的運用,相信大家已經(jīng)掌握了其用法和技巧。之前在某個網(wǎng)站看過一個比較酷炫的鼠標懸浮特效,好像也是使用「CSS變量」實現(xiàn)的。筆者憑著記憶也使用「CSS變量」實現(xiàn)一番。
其實思路也比較簡單,先對按鈕進行布局和著色,然后使用偽元素標記鼠標的位置,定義--x和--y表示偽元素在按鈕里的坐標,通過JS獲取鼠標在按鈕上的offsetLeft和offsetLeft分別賦值給--x和--y,再對偽元素添加徑向漸變的背景色,大功告成,一個酷炫的鼠標懸浮跟蹤特效就這樣誕生了。
- .track-btn {
- display: block;
- overflow: hidden;
- border-radius: 100px;
- width: 400px;
- height: 50px;
- background-color: #66f;
- line-height: 50px;
- cursor: pointer;
- font-weight: bold;
- font-size: 18px;
- color: #fff;
- span {
- position: relative;
- }
- &::before {
- --size: 0;
- position: absolute;
- left: var(--x);
- top: var(--y);
- width: var(--size);
- height: var(--size);
- background-image: radial-gradient(circle closest-side, #09f, transparent);
- content: "";
- transform: translate3d(-50%, -50%, 0);
- transition: all 200ms ease;
- }
- &:hover::before {
- --size: 400px;
- }
- }
- exportdefault {
- name: "track-btn",
- methods: {
- move(e) {
- const x = e.pageX - e.target.offsetLeft;
- const y = e.pageY - e.target.offsetTop;
- e.target.style.setProperty("--x", `${x}px`);
- e.target.style.setProperty("--y", `${y}px`);
- }
- }
- };
- 源碼鏈接可在文章結(jié)尾處獲取
其實可結(jié)合鼠標事件來完成更多的酷炫效果,例如動畫關(guān)聯(lián)、事件響應(yīng)等操作。沒有做不到,只有想不到,盡情發(fā)揮你的想象力啦。
之前在CodePen上還看到一個挺不錯的栗子,一個懸浮視差按鈕,具體代碼涉及到一些3D變換的知識??赐暝创a后,按照其思路自己也實現(xiàn)一番,順便對代碼稍加改良并封裝成Vue組件,存放到本課件示例代碼中。感覺錄制的GIF有點別扭,顯示效果不太好,有興趣的同學可下載本課件示例代碼,自己運行看看效果。
兼容
對于現(xiàn)代瀏覽器來說,「CSS變量」的兼容性其實還是蠻好的,所以大家可放心使用。畢竟現(xiàn)在都是各大瀏覽器廠商快速迭代的時刻,產(chǎn)品對于用戶體驗來說是占了很大比重,因此在條件允許的情況下還是大膽嘗新,不要被一些過去的所謂的規(guī)范所約束著。
試問現(xiàn)在還有多少人愿意去維護IE6~IE9的兼容性,如果一個產(chǎn)品的用戶體驗受限于遠古瀏覽器的壓制(可能政務(wù)Web應(yīng)用和金融Web應(yīng)用除外吧),相信這個產(chǎn)品也不會走得很遠。
我們在完成一個產(chǎn)品的過程中,不僅僅是為了完成工作任務(wù),如果在保證進度的同時能花點心思點綴一下,可能會有意外的收獲?!赣眯膶懞妹恳欢未a,才是享受寫代碼的真諦」。
總結(jié)
本文通過循序漸進的方式探討了「CSS變量」的運用和技巧,對于一個這么好用的特性,當然是不能放過啦。其實多多思考,就能把「CSS變量」用在很多場景上。筆者把本文提到的示例統(tǒng)一組成一個Demo,也方便有興趣的同學通過課件示例代碼進行學習,思考一些可能在閱讀本文時沒有注意到的細節(jié)。
- Demo示例:條形加載條、心形加載條、標簽導航欄、懸浮跟蹤按鈕、懸浮視差按鈕
- Demo地址:關(guān)注IQ前端,掃描文章底部二維碼,后臺回復變量,獲取「整套課件示例代碼」
- Demo運行:里面的readme.html有詳細說明,記得看喔
寫到最后,送給大家一個大大的彩蛋,一個暖心彩虹色調(diào)搭配的愛心點贊按鈕。如果你覺得本文寫得棒棒噠,請給筆者一個贊喔,就像下面那樣。當然,彩蛋源碼也在課件示例代碼里啦。想了解更多的CSS開發(fā)技巧,可移步到筆者19年寫的一篇9.2萬閱讀量的爆款文章《靈活運用CSS開發(fā)技巧(66個騷操作案例)》,保證滿足你的眼球。
分享標題:妙用CSS變量,讓你的CSS變得更心動
網(wǎng)頁URL:http://m.fisionsoft.com.cn/article/cdsjjsi.html
- 的位置顯示指定的Tab。不操作DOM而可移動
- 是因為定義了--tab-move,通過calc()計算--tab-index與--tab-move的關(guān)系,從而操控transform: translate3d()來移動
- 。
另外在


咨詢
建站咨詢
