溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用CSS變量實現(xiàn)心動效果

發(fā)布時間:2021-10-29 16:49:06 來源:億速云 閱讀:96 作者:iii 欄目:web開發(fā)

本篇內(nèi)容介紹了“怎么使用CSS變量實現(xiàn)心動效果”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

 前言

「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變量」的代碼量多了一點(diǎn),但是有沒有想到突然某天萬惡的策劃小哥哥和設(shè)計小姐姐說要做一個換膚功能。按照平常的思路,估計有些同學(xué)就會按照默認(rèn)顏色主題增加一份對照的新顏色主題CSS文件。這樣每次新增需求都同時維護(hù)幾套主題顏色多麻煩啊。

此時「CSS變量」就派上用場了,提前跟設(shè)計小姐姐規(guī)范好各種需要變換的顏色并通過「CSS變量」進(jìn)行定義,通過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使用變量的好處:

  •  減少樣式代碼的重復(fù)性

  •  增加樣式代碼的擴(kuò)展性

  •  提高樣式代碼的靈活性

  •  增多一種CSS與JS的通訊方式

  •  不用深層遍歷DOM改變某個樣式

可能有些同學(xué)會問,Sass和Less早就實現(xiàn)了變量這個特性,何必再多此一舉呢??墒羌?xì)想一下,「CSS變量」對比Sass和Less的變量,又有它的過人之處。

  •  瀏覽器原生特性,無需經(jīng)過任何轉(zhuǎn)譯就可直接運(yùn)行

  •  DOM對象一員,極大便利了CSS與JS之間的聯(lián)系

認(rèn)識

本來打算用一半篇幅講述「CSS變量」的規(guī)范和用法,但是網(wǎng)上一搜一大把就感覺沒必要了,貼上阮一峰老師寫的教程《CSS變量教程》。同時筆者也對「CSS變量」的細(xì)節(jié)地方進(jìn)行一個整理,方便大家記憶。

  •  聲明:--變量名

  •  讀?。簐ar(--變量名, 默認(rèn)值)

  •  類型

    •   普通:只能用作屬性值不能用作屬性名

    •   字符:與字符串拼接 "Hello, "var(--name)

    •   數(shù)值:使用calc()與數(shù)值單位連用 var(--width) * 10px

  •  作用域

    •   范圍:在當(dāng)前元素塊作用域及其子元素塊作用域下有效

    •   優(yōu)先級別:內(nèi)聯(lián)樣式 > ID選擇器 > 類選擇器 = 屬性選擇器 = 偽類選擇器 > 標(biāo)簽選擇器 = 偽元素選擇器

接下來使用幾個特別的場景展示「CSS變量」的魅力。還是那句話,「一樣?xùn)|西有使用的場景,那自然就會有它的價值」,那么用的人也會越來越多。

使用場景

其實「CSS變量」有一個特別好用的場景,那就是結(jié)合List元素集合使用。如果不明白這是什么,請繼續(xù)往下看。

以下所有演示代碼基于Vue文件,但HTML、CSS和JS分開書寫,為了簡化CSS的書寫而使用Sass進(jìn)行預(yù)處理,方便代碼演示

條形加載條

一個條形加載條通常由幾條線條組成,并且每條線條對應(yīng)一個存在不同時延的相同動畫,通過時間差運(yùn)行相同的動畫,從而產(chǎn)生加載效果。估計大部分的同學(xué)可能會把CSS代碼寫成以下這樣。

怎么使用CSS變量實現(xiàn)心動效果

<ul class="strip-loading flex-ct-x">      <li v-for="v in 6" :key="v"></li> </ul>
.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),每個<li>只是存在animation-delay不同,而其余代碼則完全相同,換成其他類似的List元素集合場景,那豈不是有10個<li>就寫10個:nth-child。

顯然這種方法不靈活也不容易封裝成組件,如果能像JS那樣封裝成一個函數(shù),并根據(jù)參數(shù)輸出不同的樣式效果,那就更棒了。說到這里,很明顯就是為了鋪墊「CSS變量」的開發(fā)技巧了。

對于HTML部分的修改,讓每個<li>擁有一個自己作用域下的「CSS變量」。對于CSS部分的修改,就需要分析哪些屬性是隨著index遞增而發(fā)生規(guī)律變化的,對規(guī)律變化的部分使用「CSS變量」表達(dá)式代替即可。

<ul class="strip-loading flex-ct-x">      <li v-for="v in 6" :key="v" :style="`--line-index: ${v}`"></li>  </ul>
.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使每個<li>擁有一個屬于自己的作用域。例如第2個<li>,--line-index的值為2,--time的計算值為200ms,換成第3個<li>后這兩個值又會不同了。

這就是「CSS變量」的作用范圍所致(在當(dāng)前元素塊作用域及其子元素塊作用域下有效),因此在.strip-loading的塊作用域下調(diào)用--line-index是無效的。

/* flex屬性無效 */  .loading {      display: flex;      align-items: center;      flex: var(--line-index);  }

通過妙用「CSS變量」,也把CSS代碼從29行縮減到15行,對于那些含有List元素集合越多的場景,效果就更明顯。而且這樣寫也更加美觀更加容易維護(hù),某天說加載效果的時間差不明顯,直接將calc((var(--line-index) - 1) * 200ms)里的200ms調(diào)整成400ms即可。就無需對每個:nth-child(n)進(jìn)行修改了。

心形加載條

前段時間刷掘金看到陳大魚頭兄的心形加載條,覺得挺漂亮的,很帶感覺。

怎么使用CSS變量實現(xiàn)心動效果

通過動圖分析,發(fā)現(xiàn)每條線條的背景色和動畫時延不一致,另外動畫運(yùn)行時的高度也不一致。細(xì)心的你可能還會發(fā)現(xiàn),第1條和第9條的高度一致,第2條和第8條的高度一致,依次類推,得到高度變換相同類的公式:對稱index = 總數(shù) + 1 - index。

背景色使用了濾鏡的色相旋轉(zhuǎn)hue-rotate函數(shù),目的是為了使顏色過渡得更加自然;動畫時延的設(shè)置和上面條形加載條的設(shè)置一致。下面就用「CSS變量」根據(jù)看到的動圖實現(xiàn)一番。

<div class="heart-loading flex-ct-x">      <ul style="--line-count: 9">          <li v-for="v in 9" :key="v" :class="`line-${v}`" :style="`--line-index: ${v}`"></li>      </ul>  </div>
.heart-loading {      width: 200px;      height: 200px;      ul {          display: flex;          justify-content: space-between;          width: 150px;          height: 10px;      }      li {          --&Theta;: 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(--&Theta;));          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ǎn)不一樣,在暖色調(diào)的蔓延和腎上腺素的飆升下,這是一種心動的感覺。想起自己曾經(jīng)寫的一首詩:我見猶憐,愛不釋手,雅俗共賞,君子好逑。

怎么使用CSS變量實現(xiàn)心動效果

標(biāo)簽導(dǎo)航欄

上面通過兩個加載條演示了「CSS變量」在CSS中的運(yùn)用以及一些妙用技巧,現(xiàn)在通過標(biāo)簽導(dǎo)航欄演示「CSS變量」在JS中的運(yùn)用。

JS中主要有3個操作「CSS變量」的API,看上去簡單易記,分別如下:

  •  讀取變量:elem.style.getPropertyValue()

  •  設(shè)置變量:elem.style.setProperty()

  •  刪除變量:elem.style.removeProperty()

先上效果圖,效果中主要是使用「CSS變量」標(biāo)記每個Tab的背景色和切換Tab的顯示狀態(tài)。

怎么使用CSS變量實現(xiàn)心動效果

<div class="tab-navbar">      <nav>          <a v-for="(v, i) in list" :key="v" :class="{ active: index === i }" @click="select(i)">標(biāo)題{{i + 1}}</a>      </nav>      <div>          <ul ref="tabs" :style="`--tab-count: ${list.length}`">              <li v-for="(v, i) in list" :key="v" :style="`--bg-color: ${v}`">內(nèi)容{{i + 1}}</li>          </ul>      </div>  </div>
.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é)尾處獲取

在<ul>上定義--tab-index表示Tab當(dāng)前的索引,當(dāng)點(diǎn)擊按鈕時重置--tab-index的值,就可實現(xiàn)不操作DOM來移動<ul>的位置顯示指定的Tab。不操作DOM而可移動<ul>是因為定義了--tab-move,通過calc()計算--tab-index與--tab-move的關(guān)系,從而操控transform: translate3d()來移動<ul>。

另外在<li>上定義--bg-color表示Tab的背景色,也是一種比較簡潔的模板賦值方式,總比寫<li :style="backgroundColor: ${color}">要好看。如果多個CSS屬性依賴一個變量賦值,那么使用「CSS變量」賦值到style上就更方便了,那些CSS屬性可在CSS文件里進(jìn)行計算與賦值,這樣可幫助JS分擔(dān)一些屬性計算工作。

當(dāng)然,這個標(biāo)簽導(dǎo)航欄也可通過純CSS實現(xiàn),有興趣的同學(xué)可看看筆者之前一篇文章里的純CSS標(biāo)簽導(dǎo)航欄。

懸浮跟蹤按鈕

通過幾個栗子實踐了「CSS變量」在CSS和JS上的運(yùn)用,相信大家已經(jīng)掌握了其用法和技巧。之前在某個網(wǎng)站看過一個比較酷炫的鼠標(biāo)懸浮特效,好像也是使用「CSS變量」實現(xiàn)的。筆者憑著記憶也使用「CSS變量」實現(xiàn)一番。

其實思路也比較簡單,先對按鈕進(jìn)行布局和著色,然后使用偽元素標(biāo)記鼠標(biāo)的位置,定義--x和--y表示偽元素在按鈕里的坐標(biāo),通過JS獲取鼠標(biāo)在按鈕上的offsetLeft和offsetLeft分別賦值給--x和--y,再對偽元素添加徑向漸變的背景色,大功告成,一個酷炫的鼠標(biāo)懸浮跟蹤特效就這樣誕生了。

怎么使用CSS變量實現(xiàn)心動效果

<a class="track-btn pr tac" @mousemove="move">      <span>妙用CSS變量,讓你的CSS變得更心動</span>  </a>
.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é)合鼠標(biāo)事件來完成更多的酷炫效果,例如動畫關(guān)聯(lián)、事件響應(yīng)等操作。沒有做不到,只有想不到,盡情發(fā)揮你的想象力啦。

之前在CodePen上還看到一個挺不錯的栗子,一個懸浮視差按鈕,具體代碼涉及到一些3D變換的知識??赐暝创a后,按照其思路自己也實現(xiàn)一番,順便對代碼稍加改良并封裝成Vue組件,存放到本課件示例代碼中。感覺錄制的GIF有點(diǎn)別扭,顯示效果不太好,有興趣的同學(xué)可下載本課件示例代碼,自己運(yùn)行看看效果。

兼容

對于現(xiàn)代瀏覽器來說,「CSS變量」的兼容性其實還是蠻好的,所以大家可放心使用。畢竟現(xiàn)在都是各大瀏覽器廠商快速迭代的時刻,產(chǎn)品對于用戶體驗來說是占了很大比重,因此在條件允許的情況下還是大膽嘗新,不要被一些過去的所謂的規(guī)范所約束著。

試問現(xiàn)在還有多少人愿意去維護(hù)IE6~IE9的兼容性,如果一個產(chǎn)品的用戶體驗受限于遠(yuǎn)古瀏覽器的壓制(可能政務(wù)Web應(yīng)用和金融Web應(yīng)用除外吧),相信這個產(chǎn)品也不會走得很遠(yuǎn)。

“怎么使用CSS變量實現(xiàn)心動效果”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

css
AI