整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JavaScript的變量提升

          JavaScript的變量提升

          果是第一次學(xué)習(xí)JavaScript,或許你會(huì)對(duì)此感到疑惑:在JavaScript中,變量只有全局變量和局部變量?jī)煞N,而不像C語(yǔ)言和Java語(yǔ)言,還有塊變量。

          其實(shí),只要你知道了JavaScript的變量提升,就理解了變量的作用域。

          1、有點(diǎn)不可思議的變量未定義

          下面是一個(gè)包含JavaScript的完整HTML文檔:

          <!DOCTYPE html>
          <html>
          <head>
          <title>var001</title>
          <meta charset="utf-8" />
          <script>
          var theMesage="value of global";
          function showMessage(){
          alert(theMessage);
          var theMessage="value of local";
          alert(theMessage);
          }
          </script>
          </head>
          
          <body>
          <button onclick="showMessage();" >顯示信息</button>
          </body>
          </html>

          當(dāng)使用瀏覽器打開(kāi)該文檔后,界面展示如下:

          當(dāng)點(diǎn)擊按鈕后,先顯示下面的警告框:

          點(diǎn)擊告警框的“確定”按鈕后,再顯示下面的警告框:

          讓人不可思議的是,第一次彈出的警告框,theMessage變量的值竟然是undefined!

          2、變量未定義的原因

          初一看JavaScript代碼,我們會(huì)認(rèn)為第一次警告框顯示的信息應(yīng)該是“value of global”,因?yàn)閠heMessage變量的值就是“value of global”。

          其實(shí)在瀏覽器內(nèi)部,showMessage函數(shù)中的語(yǔ)句:

          var theMessage="value of local";

          經(jīng)歷了兩次變換,第一次變換,將這條語(yǔ)句變?yōu)閮蓷l語(yǔ)句:

          var theMessage;
          theMessage="value of local";

          這兩條語(yǔ)句,一條是變量聲明語(yǔ)句,用于生成變量;第二條是賦值語(yǔ)句,用于為變量賦值。

          第二次變換,就是將變量聲明語(yǔ)句上浮到函數(shù)體的頂部,因此,最終執(zhí)行之前的showMessage函數(shù),是這個(gè)樣子:

          function showMessage(){
          var theMessage;
          alert(theMessage);
          theMessage="value of local";
          alert(theMessage);
          }

          看到showMessage函數(shù)的最終形式,你會(huì)立即明白:theMessae變量沒(méi)有被賦值就使用了,當(dāng)然是undefined。原來(lái)如此!

          3、語(yǔ)句塊內(nèi)定義的變量,外部竟然可以使用

          下面也是一個(gè)包含JavaScript的完整HTML文檔:

          <!DOCTYPE html>
          <html>
          <head>
          <title>var002</title>
          <meta charset="utf-8" />
          <script>
          function showMessage(){
          var theMessage="";
          for (var i=1; i<5; i++)
          {
          theMessage=theMessage + " " + i;
          }
          theMessage=theMessage + " " + i*100;
          alert(theMessage);
          }
          </script>
          </head>
          
          <body>
          <button onclick="showMessage();" >顯示信息</button>
          </body>
          </html>

          看到這樣的HTML文件,這樣的JavaScript函數(shù),有經(jīng)驗(yàn)的C程序員或者Java程序員,會(huì)立即喊出來(lái):“程序錯(cuò)了,在for塊之外,i不能被使用!”,實(shí)際上,HTML文件被瀏覽器打開(kāi)后,展示如下:

          點(diǎn)擊“顯示信息”按鈕,出現(xiàn)下面的警告框:

          程序竟然正常運(yùn)行了!

          4、程序正常運(yùn)行的原因

          上面的程序正常運(yùn)行的原因,也是變量提升,下面的語(yǔ)句:

          var i=1;

          也是經(jīng)過(guò)兩次變換,最終,showMessage函數(shù)在運(yùn)行前,被變換成這樣了:

          function showMessage(){
          var theMessage;
          var i;
          theMessage="";
          for (i=1; i<5; i++)
          {
          theMessage=theMessage + " " + i;
          }
          theMessage=theMessage + " " + i*100;
          alert(theMessage);
          }

          這樣的代碼,肯定可以正常運(yùn)行了。

          5、變量提升知識(shí)點(diǎn)的總結(jié)

          在JavaScript中,上面的變換方式,被稱(chēng)為變量提升。其實(shí),變量提升,就是變量聲明上浮,一直上浮到全局或者函數(shù)體的頂部。

          在前面:

          本文將和各位老鐵一起探索如何使用CSS變量來(lái)降低復(fù)雜布局和交互的代碼編寫(xiě)難度,并使其更易于維護(hù)。這里即將分享兩篇該系列的文章,本篇是分享css變量的探索應(yīng)用的各種用例。

          進(jìn)入文章前,我們先看下圖,一張網(wǎng)站常用的響應(yīng)式信息圖表布局圖,當(dāng)然實(shí)現(xiàn)的方式很多,如果我告訴您一個(gè)CSS聲明會(huì)在以下圖像中對(duì)寬屏情況(左測(cè))和第二個(gè)(右測(cè))之間產(chǎn)生差異,用一個(gè)CSS聲明實(shí)現(xiàn)在寬屏幕的情況下對(duì)奇數(shù)項(xiàng)和偶數(shù)項(xiàng)進(jìn)行區(qū)分,從而來(lái)實(shí)現(xiàn)下面效果,你會(huì)不會(huì)覺(jué)得有點(diǎn)驚喜?

          或者僅僅一個(gè)CSS聲明就能區(qū)別下面的壓縮和擴(kuò)展的情況?

          有點(diǎn)意思吧,接下來(lái),我們就一起探索CSS變量在復(fù)雜布局和交互的一些小運(yùn)用。關(guān)于CSS變量是什么以及如何開(kāi)始使用它們的文章已經(jīng)很多了,所以我們不會(huì)在這里深入討論。我們將直接深入了解CSS變量為什么對(duì)實(shí)現(xiàn)這些情況和其他情況有用,然后我們將進(jìn)一步詳細(xì)解釋如何實(shí)現(xiàn)各種情況。我們將從頭編寫(xiě)一個(gè)實(shí)際示例,一步一步地編寫(xiě),最后,您將通過(guò)使用相同技術(shù)的更多演示獲得一些引人注目的東西。所以讓我們開(kāi)始吧!(ps:本文樣式都是scss編寫(xiě))

          為什么CSS變量很有用

          對(duì)我而言,CSS變量的最大優(yōu)點(diǎn)是它們以邏輯,數(shù)學(xué)和輕松的方式為事物的樣式打開(kāi)了大門(mén)。看下面這個(gè)陰陽(yáng)圖,其實(shí)是使用loader元素的兩個(gè)偽元素創(chuàng)建兩個(gè)半部分

          旋轉(zhuǎn)?符號(hào),兩個(gè)半的大小逐漸增大和減小。我們使用相同的 background , border-color , transform-origin 和 animation-delay 值兩半。這些值都取決于 --i 最初設(shè)置為 0 兩半(偽元素)的開(kāi)關(guān)變量,但隨后我們將其更改 1 為后半部分( :after 偽元素),從而動(dòng)態(tài)修改所有這些屬性的計(jì)算值。

          如果沒(méi)有CSS變量,我們將不得不再次在:after偽元素上設(shè)置所有這些屬性(border-color、transform-origin、background、anima -delay),并可能出現(xiàn)一些錯(cuò)誤,甚至忘記設(shè)置其中一些屬性。

          一般情況下切換的工作原理

          一、在零和非零值之間切換

          在陰陽(yáng)加載器的特定情況下,我們?cè)趦砂耄▊卧兀┲g改變的所有屬性對(duì)于開(kāi)關(guān)的一個(gè)狀態(tài)變?yōu)榱阒刀鴮?duì)于另一個(gè)狀態(tài)變?yōu)榉橇阒怠?/p>

          如果我們希望當(dāng)開(kāi)關(guān)關(guān)閉( --i: 0 )時(shí)我們的值為零,而當(dāng)開(kāi)關(guān)打開(kāi)()時(shí)我們的值為非零 --i:1,那么我們將它與開(kāi)關(guān)值( var(--i) )相乘。這樣,如果我們的非零值應(yīng)該是 30deg ,我們有一個(gè)角度值,我們有:

          • 當(dāng)開(kāi)關(guān) 關(guān)閉
          • ( --i: 0 )時(shí), calc(var(--i)*30deg) 計(jì)算到 0*30deg=0deg
          • 當(dāng)開(kāi)關(guān) 打開(kāi)
          • ( --i: 1 )時(shí), calc(var(--i)*30deg) 計(jì)算到 1*30deg=30deg

          您可以看到以下所示的概念:

          在零和非零值之間切換(現(xiàn)場(chǎng)演示,由于 calc() 不處理角度值而沒(méi)有Edge支持)

          對(duì)于裝載機(jī)的特定情況下,我們使用HSL值 border-color 和 background-color 。HSL代表色調(diào),飽和度,亮度,并且可以借助于雙錐體(其由粘合在一起的基部的兩個(gè)錐體組成)在視覺(jué)上最佳地表示。

          色調(diào)圍繞著雙色調(diào), 0° 相當(dāng)于 360° 在兩種情況下都給我們一個(gè)紅色

          飽和度從 0% 雙錐的垂直軸到 100% 雙錐面上。當(dāng)飽和度 0% (在雙錐的垂直軸上)時(shí),色調(diào)不再重要;對(duì)于同一水平面上的所有色調(diào),我們得到完全相同的灰色。“相同水平面”是指具有相同的亮度,其沿垂直軸雙錐增加,從去 0% 在黑色雙圓錐體的頂點(diǎn),以 100% 在白色雙圓錐體的頂點(diǎn)。當(dāng)亮度是 0% 或者 100% ,色調(diào)和飽和度都不再重要時(shí) - 我們總是得到黑色亮度值 0% 和白色亮度值 100% 。因?yàn)槲覀冎恍枰谏桶咨覀兊?符號(hào),色調(diào)和飽和度是不相關(guān)的,所以我們清除它們,然后之間進(jìn)行切換黑色,并白色通過(guò)切換之間的亮度 0% 和 100% 。

          .yin-yang {
           &:before, &:after {
           --i: 0;
           /* lightness of border-color when 
           * --i: 0 is (1 - 0)*100%=1*100%=100% (white)
           * --i: 1 is (1 - 1)*100%=0*100%=0% (black) */
           border: solid $d/6 hsl(0, 0%, calc((1 - var(--i))*100%));
           /* x coordinate of transform-origin when 
           * --i: 0 is 0*100%=0% (left) 
           * --i: 1 is 1*100%=100% (right) */
           transform-origin: calc(var(--i)*100%) 50%;
           /* lightness of background-color when 
           * --i: 0 is 0*100%=0% (black) 
           * --i: 1 is 1*100%=100% (white) */
           background: hsl(0, 0%, calc(var(--i)*100%));
           /* animation-delay when
           * --i: 0 is 0*-$t=0s 
           * --i: 1 is 1*-$t=-$t */
           animation: s $t ease-in-out calc(var(--i)*#{-$t}) infinite alternate;
           }
           &:after { --i: 1 }
          }
          
          

          但是,如果我們想要在開(kāi)關(guān)關(guān)閉( --i: 0 )時(shí)具有非零值而在開(kāi)關(guān)打開(kāi)時(shí)具有另一個(gè)不同的非零值( --i: 1 )呢?

          一、在兩個(gè)非零值之間切換

          假設(shè)我們希望一個(gè)元素在開(kāi)關(guān)關(guān)閉時(shí)具有灰色 background ( #ccc ),在開(kāi)關(guān)打開(kāi)時(shí) --i: 0

          具有橙色 background ( #f90 )( --i: 1 )。我們要做的第一件事是從十六進(jìn)制切換到更易于管理的格式,如 rgb() 或 hsl() 。我們可以通過(guò)使用諸如Lea Verou的CSS Colors之類(lèi)的工具或通過(guò)DevTools手動(dòng)完成此操作。如果我們 background 在元素上有一個(gè)集合,我們可以通過(guò) Shift 按住鍵來(lái)循環(huán)瀏覽格式,同時(shí)單擊DevTools中值前面的正方形(或圓圈)。這適用于Chrome和Firefox,但它似乎不適用于Edge。

          更妙的是,如果我們使用無(wú)禮的話,我們可以提取成分 red() / green() / blue()hue() /

          saturation() / lightness() 函數(shù)。雖然 rgb() 可能是更為人所知的格式,但我更傾向于 hsl()因?yàn)槲野l(fā)現(xiàn)它更直觀,而且通過(guò)查看代碼,我更容易了解視覺(jué)效果。因此,我們使用以下函數(shù)提取

          hsl() 兩個(gè)值的等價(jià)物的三個(gè)組成部分( $c0: #ccc 當(dāng)開(kāi)關(guān)關(guān)閉 $c1: #f90 時(shí)和開(kāi)關(guān)打開(kāi)時(shí)):

          $c0: #ccc;
          $c1: #f90;
          $h0: round(hue($c0)/1deg);
          $s0: round(saturation($c0));
          $l0: round(lightness($c0));
          $h1: round(hue($c1)/1deg);
          $s1: round(saturation($c1));
          $l1: round(lightness($c1))
          
          

          請(qǐng)注意,我們已經(jīng)四舍五入的結(jié)果hue(),saturation()并lightness()作為他們可能返回大量的小數(shù),我們要保持我們生成的代碼干凈。我們還將hue()函數(shù)的結(jié)果除以1deg,因?yàn)樵谶@種情況下返回值是度值,而Edge僅支持CSS hsl()函數(shù)內(nèi)的無(wú)單位值。通常,在使用Sass時(shí),我們可以使用度數(shù)值,而不僅僅是hsl()函數(shù)內(nèi)部hue的單位值,因?yàn)镾ass將其視為Sass hsl()函數(shù),它被編譯為hsl()具有無(wú)單位色調(diào)的CSS 函數(shù)。但是在這里,我們內(nèi)部有一個(gè)動(dòng)態(tài)CSS變量,因此Sass將此函數(shù)視為CSShsl() 沒(méi)有編譯成其他任何東西的函數(shù),因此,如果hue有一個(gè)單元,則不會(huì)從生成的CSS中刪除它。

          現(xiàn)在我們有:

          • 如果開(kāi)關(guān)關(guān)閉(--i: 0),我們background是 hsl($h0, $s0, $l0)
          • 如果開(kāi)關(guān)打開(kāi)(--i: 1),我們background是 hsl($h1, $s1, $l1)

          我們可以將我們的兩個(gè)背景寫(xiě)成:

          • 如果開(kāi)關(guān)關(guān)閉( --i: 0 ), hsl(1*$h0 + 0*$h1, 1*$s0 + 0*$s1, 1*$l0 + 1*$l1)
          • 如果開(kāi)關(guān)打開(kāi)( --i: 1 ), hsl(0*$h0 + 1*$h1, 0*$s0 + 1*$s1, 0*$l0 + 1*$l1)

          在這里,我們記--j的互補(bǔ)值--i(當(dāng)--i是0,--j是1,當(dāng)--i是1,--j是0)。

          上述公式適用于在任意兩個(gè)HSL值之間切換。但是,在這種特殊情況下,我們可以簡(jiǎn)化它,因?yàn)楫?dāng)開(kāi)關(guān)關(guān)閉時(shí)我們有一個(gè)純灰色(--i: 0)。

          考慮到RGB模型,純灰度值具有相等的紅色,綠色和藍(lán)色值。 當(dāng)考慮HSL模型時(shí),色調(diào)是無(wú)關(guān)緊要的(我們的灰色看起來(lái)對(duì)于所有色調(diào)都是相同的),飽和度總是0%只有亮度很重要,決定了我們的灰色是多么亮或暗。 在這種情況下,我們可以始終保持非灰色值的色調(diào)(我們對(duì)“on”情況所具有的色調(diào)$h1)。

          由于任何灰度值(我們對(duì)“關(guān)閉”情況所具有的)的飽和度 $s0始終是0%,將其乘以0或者1總是給出我們0%。因此,考慮到var(--j)*#{$s0}我們的公式中的術(shù)語(yǔ)總是如此0%,我們可以放棄它,我們的飽和公式減少到“on”情況$s1和switch變量飽和之間的乘積--i。 這使得輕盈成為我們?nèi)匀恍枰獞?yīng)用完整配方的唯一組成部分

          --j: calc(1 - var(--i));
          background: hsl($h1, 
           calc(var(--i)*#{$s1}), 
           calc(var(--j)*#{$l0} + var(--i)*#{d1l}))
          
          

          以上內(nèi)容可在此演示中進(jìn)行測(cè)試。 類(lèi)似地,假設(shè)我們想要font-size一些文本2rem在我們的開(kāi)關(guān)關(guān)閉(--i: 0)和10vw開(kāi)關(guān)打開(kāi)(--i: 1)時(shí)。應(yīng)用相同的方法,我們有:

          font-size: calc((1 - var(--i))*2rem + var(--i)*10vw)
          
          

          觸發(fā)切換

          一、基于元素的切換

          這意味著某些元件和其他元件的開(kāi)關(guān)關(guān)閉。例如,這可以通過(guò)奇偶校驗(yàn)來(lái)確定。假設(shè)我們希望所有偶數(shù)元素都旋轉(zhuǎn)并且具有橙色background而不是初始灰色元素

          .box {
           --i: 0;
           --j: calc(1 - var(--i));
           transform: rotate(calc(var(--i)*30deg));
           background: hsl($h1, 
           calc(var(--i)*#{$s1}), 
           calc(var(--j)*#{$l0} + var(--i)*#{$l1}));
           
           &:nth-child(2n) { --i: 1 }
          }
          
          

          由項(xiàng)目奇偶校驗(yàn)觸發(fā)的切換(實(shí)時(shí)演示,由于calc()不適用于角度值而在Edge中不能完全正常工作)

          在奇偶校驗(yàn)的情況下,我們?yōu)槊扛粢粋€(gè)項(xiàng)目(:nth-child(2n))打開(kāi)開(kāi)關(guān),但我們也可以為前七個(gè)項(xiàng)目(:nth-child(7n)),前兩個(gè)項(xiàng)目(:nth-child(-n + 2)),為除了第一個(gè)和最后兩個(gè)(:nth-child(n + 3):nth-last-child(n + 3))之外的所有項(xiàng)目打開(kāi)它。我們也可以僅針對(duì)標(biāo)題或僅針對(duì)具有特定屬性的元素進(jìn)行翻轉(zhuǎn)。

          二、狀態(tài)切換

          這意味著當(dāng)元素本身(或父元素或其先前的兄弟元素之一)處于一種狀態(tài)時(shí)關(guān)閉開(kāi)關(guān),而當(dāng)它是另一種狀態(tài)時(shí)關(guān)閉。在上一節(jié)的交互式示例中,在檢查或取消選中元素之前的復(fù)選框時(shí),交換機(jī)被翻轉(zhuǎn)。我們還可以使用白色鏈接,在聚焦或懸停時(shí)可以放大并變成橙色:

          $c: #f90;
          $h: round(hue($c)/1deg);
          $s: round(saturation($c));
          $l: round(lightness($c));
          a {
           --i: 0;
           transform: scale(calc(1 + var(--i)*.25));
           color: hsl($h, $s, calc(var(--i)*#{$l} + (1 - var(--i))*100%)); 
           &:focus, &:hover { --i: 1 }
          }
          
          

          因?yàn)閣hite任何hsl()具有亮度100%(色調(diào)和飽和度都無(wú)關(guān)緊要)的值,我們可以通過(guò)始終保持:focus/ :hover狀態(tài)的色調(diào)和飽和度并且僅改變亮度來(lái)簡(jiǎn)化事物。

          由狀態(tài)變化觸發(fā)的切換(現(xiàn)場(chǎng)演示,由于功能calc()內(nèi)部不支持的值,Edge中功能不全scale())

          三、基于媒體查詢的切換

          另一種可能性是切換由媒體查詢觸發(fā),例如,當(dāng)方向改變時(shí)或從一個(gè)視口范圍轉(zhuǎn)到另一個(gè)視口范圍時(shí)。 比方說(shuō),我們有white一個(gè)標(biāo)題font-size的1rem最高320px,但隨后變?yōu)槌壬?c)和font-size變5vw,并開(kāi)始與視縮放width。

          h5 {
           --i: 0;
           color: hsl($h, $s, calc(var(--i)*#{$l} + (1 - var(--i))*100%));
           font-size: calc(var(--i)*5vw + (1 - var(--i))*1rem);
           @media (min-width: 320px) { --i: 1 }
          }
          
          

          從頭開(kāi)始編寫(xiě)一個(gè)更復(fù)雜的例子-搜索

          我們?cè)谶@里剖析的例子是本文開(kāi)頭展示的擴(kuò)展搜索

          ps:從可用性的角度來(lái)看,在網(wǎng)站上設(shè)置這樣的搜索框可能不是最好的主意,因?yàn)槿藗兺ǔF谕阉骺蚝竺娴陌粹o觸發(fā)搜索,而不是關(guān)閉搜索欄,但它仍然是一個(gè)有趣的編碼練習(xí),這就是為什么我選擇在這里剖析它。

          首先,我的想法是僅使用表單元素來(lái)完成它。

          因此,HTML結(jié)構(gòu)如下所示:

          <input id='search-btn' type='checkbox'/>
          <label for='search-btn'>Show search bar</label>
          <input id='search-bar' type='text' placeholder='Search...'/>
          
          

          我們?cè)谶@里做的最初是隱藏文本input,然后在選中復(fù)選框之前將其顯示出來(lái) - 讓我們深入了解它是如何工作的! 首先,我們使用基本重置并flex在我們input和label元素的容器上設(shè)置布局。在我們的例子中,這個(gè)容器是body,但也可能是另一個(gè)元素。我們也絕對(duì)定位復(fù)選框并將其移出視線(視口外)。

          *, :before, :after {
           box-sizing: border-box;
           margin: 0;
           padding: 0;
           font: inherit
          }
          html { overflow-x: hidden }
          body {
           display: flex;
           align-items: center;
           justify-content: center;
           margin: 0 auto;
           min-width: 400px;
           min-height: 100vh;
           background: #252525
          }
          [id='search-btn'] {
           position: absolute;
           left: -100vh
          }
          
          

          我們把復(fù)選框label變成一個(gè)大的綠色圓形按鈕,并使用一個(gè)大的負(fù)數(shù)值移動(dòng)它的文本內(nèi)容的視線text-indent和overflow: hidden。

          $btn-d: 5em; /* 同上 */[for='search-btn'] {
           overflow: hidden;
           width: $btn-d;
           height: $btn-d;
           border-radius: 50%;
           box-shadow: 0 0 1.5em rgba(#000, .4);
           background: #d9eb52;
           text-indent: -100vw;
           cursor: pointer;
          }
          
          

          接下來(lái),我們通過(guò)以下方式修改實(shí)際搜索欄:

          • 給它明確的維度
          • 提供 background 正常狀態(tài)
          • background 為其聚焦?fàn)顟B(tài)定義不同的光暈
          • 使用 border-radius 相當(dāng)于其一半的左側(cè)角落 height
          • 清理占位符一點(diǎn)
          $btn-d: 5em;
          $bar-w: 4*$btn-d;
          $bar-h: .65*$btn-d;
          $bar-r: .5*$bar-h;
          $bar-c: #ffeacc;/* 同上 */
          [id='search-bar'] {
           border: none;
           padding: 0 1em;
           width: $bar-w;
           height: $bar-h;
           border-radius: $bar-r 0 0 $bar-r;
           background: #3f324d;
           color: #fff;
           font: 1em century gothic, verdana, arial, sans-serif;
           &::placeholder {
           opacity: .5;
           color: inherit;
           font-size: .875em;
           letter-spacing: 1px;
           text-shadow: 0 0 1px, 0 0 2px
           }	
           &:focus {
           outline: none;
           box-shadow: 0 0 1.5em $bar-c, 0 1.25em 1.5em rgba(#000, .2);
           background: $bar-c;
           color: #000;
           }
          }
          復(fù)制代碼
          

          此時(shí),搜索欄的右邊緣與按鈕的左邊緣重合。但是,我們想要一些重疊 - 假設(shè)重疊使得搜索欄的右邊緣與按鈕的垂直中線重合。鑒于我們align-items: center在容器上有一個(gè)flexbox布局(body在我們的例子中),由我們的兩個(gè)項(xiàng)目組成的組件(條和按鈕)保持水平中間對(duì)齊,即使我們?cè)O(shè)置margin一個(gè)或另一個(gè)或在這兩個(gè)項(xiàng)目之間。(在最左邊的項(xiàng)目的左側(cè)或最右邊的項(xiàng)目的右側(cè)是一個(gè)不同的故事,但我們現(xiàn)在不會(huì)進(jìn)入那個(gè)。)

          這是.5*$btn-d半個(gè)按鈕直徑的重疊,相當(dāng)于按鈕的半徑。我們margin-right在欄上將其設(shè)為負(fù)數(shù)。我們還調(diào)整padding條形圖的右側(cè),以便我們補(bǔ)償重疊:

          $btn-d: 5em;
          $btn-r: .5*$btn-d;
          /* 同上 */
          [id='search-bar'] {
           /* 同上 */
           margin-right: -$btn-r;
           padding: 0 calc(#{$btn-r} + 1em) 0 1em;
          }
          
          

          除了條形按照DOM順序中的按鈕,所以它放在它的頂部,當(dāng)我們真正想要按鈕在頂部。

          幸運(yùn)的是,這有一個(gè)簡(jiǎn)單的解決方案(至少現(xiàn)在 - 以后還不夠,但讓我們一次處理一個(gè)問(wèn)題)。

          [for='search-btn'] {
           /* 同上 */
           position: relative;
          }
          

          在這種狀態(tài)下,條形和按鈕組件的總寬度是條形寬度$bar-w加上按鈕的半徑$btn-r(按鈕直徑的一半$btn-d),因?yàn)榘粹o的一半重疊。在折疊狀態(tài)下,組件的總寬度就是按鈕直徑$btn-d。

          由于我們希望在從展開(kāi)狀態(tài)到折疊狀態(tài)時(shí)保持相同的中心軸,我們需要將按鈕向左移動(dòng)擴(kuò)展?fàn)顟B(tài)(.5*($bar-w + $btn-r))減去按鈕半徑($btn-r)的組件寬度的一半。 我們稱(chēng)之為這種轉(zhuǎn)變$x,我們?cè)诎粹o上使用減號(hào)(因?yàn)槲覀儗粹o向左移動(dòng),左邊是x軸的負(fù)方向)。由于我們希望條形圖折疊到按鈕中,我們$x在它上面設(shè)置相同的偏移,但是在正方向上(因?yàn)槲覀儗l形圖移動(dòng)到右邊的 x軸)。 當(dāng)未選中復(fù)選框時(shí),我們處于折疊狀態(tài),而當(dāng)未選中復(fù)選框時(shí),我們處于展開(kāi)狀態(tài)。這意味著transform當(dāng)沒(méi)有選中復(fù)選框時(shí),我們的欄和按鈕會(huì)被CSS移動(dòng),并且我們當(dāng)前將它們置于其中(沒(méi)有transform)。 為了做到這一點(diǎn),我們--i在復(fù)選框后面的元素上設(shè)置了一個(gè)變量- 按鈕(使用label復(fù)選框創(chuàng)建)和搜索欄。此變量0處于折疊狀態(tài)(當(dāng)兩個(gè)元素都移位且未選中復(fù)選框時(shí))并1處于展開(kāi)狀態(tài)(當(dāng)我們的條和按鈕位于它們當(dāng)前占據(jù)的位置時(shí),沒(méi)有移位,并且復(fù)選框被選中)

          $x: .5*($bar-w + $btn-r) - $btn-r;
          [id='search-btn'] {
           position: absolute;
           left: -100vw;	
           ~ * {
           --i: 0;
           --j: calc(1 - var(--i)) /* 1 when --i is 0, 0 when --i is 1 */
           }
           &:checked ~ * { --i: 1 }
          }
          [for='search-btn'] {
           /*同之前 */
           transform: translate(calc(var(--j)*#{-$x}));
          }
          [id='search-bar'] {
           /*同之前 */
           transform: translate(calc(var(--j)*#{$x}));
          }
          
          

          我們現(xiàn)在有互動(dòng)的東西!

          單擊該按鈕可切換復(fù)選框狀態(tài)(因?yàn)樵摪粹o已使用 label 復(fù)選框創(chuàng)建)。

          除了現(xiàn)在按鈕有點(diǎn)難以點(diǎn)擊,因?yàn)樗俅挝挥谖谋据斎胂拢ㄒ驗(yàn)槲覀冊(cè)跅l上設(shè)置了 transform.

          并建立了堆疊上下文)。修復(fù)非常簡(jiǎn)單 - 我們需要 z-index 在按鈕上添加一個(gè)按鈕,然后將其移動(dòng)到條形圖上方。

          但是我們還有另一個(gè)更大的問(wèn)題:我們可以看到右側(cè)按鈕下方的欄桿。為了解決這個(gè)問(wèn)題,我們?cè)跈谏显O(shè)置clip-path了一個(gè)inset()值。這指定了一個(gè)剪切矩形,借助于元素頂部,右側(cè),底部和左側(cè)邊緣的距離border-box。剪切矩形之外的所有內(nèi)容都會(huì)被剪切掉,只顯示內(nèi)部的內(nèi)容

          在上圖中,每個(gè)距離都從邊框的邊緣向內(nèi)移動(dòng)。在這種情況下,他們是積極的。但它們也可以向外移動(dòng),在這種情況下它們是負(fù)的,并且剪切矩形的相應(yīng)邊緣在元素之外border-box。 起初,您可能認(rèn)為我們沒(méi)有理由這樣做,但在我們的特定情況下,我們會(huì)這樣做! 我們希望從top(dt),bottom(db)和left(dl)的距離是負(fù)的,并且足夠大以包含在該狀態(tài)中box-shadow的元素外部延伸的border-box距離,:focus因?yàn)槲覀儾幌M患羟械簟K越鉀Q方案是創(chuàng)建一個(gè)剪切矩形,邊緣在元素之外border-box在這三個(gè)方向。 與右邊的距離(dr)是折疊情況下的整個(gè)條寬$bar-w減去按鈕半徑$btn-r(未選中復(fù)選框--i: 0),并且0在展開(kāi)的情況下(選中復(fù)選框--i: 1)。

          $out-d: -3em;
          [id='search-bar'] {
           /* 同之前 */
           clip-path: inset($out-d calc(var(--j)*#{$bar-w - $btn-r}) $out-d $out-d);
          }
          
          

          我們現(xiàn)在有一個(gè)搜索欄和按鈕組件,在單擊按鈕時(shí)會(huì)展開(kāi)和折疊。

          由于我們不希望兩個(gè)便之間發(fā)生突然變化,我們使用 transition :

          [id='search-btn'] {
           /* 同之前 */
           ~ * {
           /* same as before */
           transition: .65s;
           }
          }
          
          

          我們還希望我們的按鈕background在折疊的情況下為綠色(未選中復(fù)選框--i: 0),在展開(kāi)的情況下為粉紅色(選中復(fù)選框--i: 1)。為此,我們使用與以前相同的技術(shù):

          [for='search-btn'] {
           /* 同之前 */
           $c0: #d9eb52; // green for collapsed state
           $c1: #dd1d6a; // pink for expanded state
           $h0: round(hue($c0)/1deg);
           $s0: round(saturation($c0));
           $l0: round(lightness($c0));
           $h1: round(hue($c1)/1deg);
           $s1: round(saturation($c1));
           $l1: round(lightness($c1));
           background: hsl(calc(var(--j)*#{$h0} + var(--i)*#{$h1}), 
           calc(var(--j)*#{$s0} + var(--i)*#{$s1}), 
           calc(var(--j)*#{$l0} + var(--i)*#{$l1}));
          }
          
          

          看看效果

          我們?nèi)匀恍枰龅氖莿?chuàng)建一個(gè)圖標(biāo),該圖標(biāo)在折疊狀態(tài)的放大鏡和展開(kāi)狀態(tài)的“x”之間變形,以指示關(guān)閉動(dòng)作。我們使用:before和:after偽元素執(zhí)行此操作。我們首先確定放大鏡的直徑以及圖標(biāo)線寬度所代表的直徑。

          $ico-d: .5*$bar-h;
          $ico-f: .125;
          $ico-w: $ico-f*$ico-d;
          
          

          我們絕對(duì)將偽元素放在按鈕中間,并考慮其尺寸。然后我們把它們變成inherit父母的transition。我們給:beforea background,因?yàn)檫@將是我們的放大鏡的把手,使它成為:after圓形border-radius并給它一個(gè)插圖box-shadow。

          [for='search-btn'] {
           /* 同之前 */	
           &:before, &:after {
           position: absolute;
           top: 50%; left: 50%;
           margin: -.5*$ico-d;
           width: $ico-d;
           height: $ico-d;
           transition: inherit;
           content: ''
           }
          	
           &:before {
           margin-top: -.4*$ico-w;
           height: $ico-w;
           background: currentColor
           }
           &:after {
           border-radius: 50%;
           box-shadow: 0 0 0 $ico-w currentColor
           } 
          }
          
          

          我們現(xiàn)在可以在按鈕上看到放大鏡組件,為了使我們的圖標(biāo)看起來(lái)更像放大鏡,我們的translate兩個(gè)組件都向外放大了放大鏡直徑的四分之一。這意味著所述手柄平移向右,在正方向X通過(guò)軸.25*$ico-d與所述主要部分的左側(cè),在負(fù)方向X以相同的軸線.25*$ico-d。 我們還scale手柄(該:before偽元素)水平至其一半width相對(duì)于其右邊緣(這意味著一個(gè)transform-origin的100%沿X軸)。 我們只希望在折疊狀態(tài)下發(fā)生這種情況(復(fù)選框未選中,--i是0,因此--j是1),因此我們將轉(zhuǎn)換量乘以--j并用于--j調(diào)整比例因子:

          [for='search-btn'] {
           /* 同之前 */
           &:before {
           /* 同之前 */
           height: $ico-w;
           transform: 
           translate(calc(var(--j)*#{.25*$ico-d})) 
           scalex(calc(1 - var(--j)*.5))
           }
           &:after {
           /* same as before */
           transform: translate(calc(var(--j)*#{-.25*$ico-d}))
           } 
          }
          
          

          我們現(xiàn)在處于折疊狀態(tài)的放大鏡圖標(biāo):

          由于我們希望旋轉(zhuǎn)兩個(gè)圖標(biāo)組件45deg,我們?cè)诎粹o本身上添加此旋轉(zhuǎn):

          [for='search-btn'] {
           /* 同之前 */
           transform: translate(calc(var(--j)*#{-$x})) rotate(45deg);
          }
          
          

          這仍然會(huì)離開(kāi)擴(kuò)展?fàn)顟B(tài),我們需要將圓形:after偽元素轉(zhuǎn)換為一條線。我們通過(guò)縮放它順著這樣做X軸,將其border-radius從50%到0%。我們使用的縮放系數(shù)是$ico-w我們想要獲得的線寬和$ico-d它在折疊狀態(tài)下形成的圓的直徑之間的比率。我們稱(chēng)這個(gè)比例$ico-f。 因?yàn)槲覀冎幌M鲞@在擴(kuò)展?fàn)顟B(tài)下,當(dāng)復(fù)選框被選中,并--i是1,我們使這兩個(gè)比例因子和border-radius依賴于--i和--j:

          $ico-d: .5*$bar-h;
          $ico-f: .125;
          $ico-w: $ico-f*$ico-d;
          [for='search-btn'] {
           /* 同之前 */	
           &:after{
           /* 同之前 */
           border-radius: calc(var(--j)*50%);
           transform: 
           translate(calc(var(--j)*#{-.25*$ico-d})) 
           scalex(calc(1 - var(--j)*.5))
           }
          }
          
          

          嗯,差不多,但并不完全。縮放也縮水了插圖box-shadow沿X軸,所以我們進(jìn)行了修復(fù)與第二插圖影子,我們(當(dāng)復(fù)選框被選中,并在擴(kuò)展?fàn)顟B(tài)下只能得到--i是1),因此,它的傳播和α取決于--i:

          $ico-d: .5*$bar-h;
          $ico-f: .125;
          $ico-w: $ico-f*$ico-d;
          [for='search-btn'] {
           /* 同之前 */
           --hsl: 0, 0%, 0%;
           color: HSL(var(--hsl));	
           &:after{
           /* 同之前 */
           box-shadow: 
           inset 0 0 0 $ico-w currentcolor, 
           /* collapsed: not checked, --i is 0, --j is 1
           * spread radius is 0*.5*$ico-d=0
           * alpha is 0
           * expanded: checked, --i is 1, --j is 0
           * spread radius is 1*.5*$ico-d=.5*$ico-d
           * alpha is 1 */
           inset 0 0 0 calc(var(--i)*#{.5*$ico-d}) HSLA(var(--hsl), var(--i))
           }
          }
          
          

          這給了我們最終的結(jié)果! 【本例完整源碼】

          實(shí)用案例

          以下是一些使用相同技術(shù)的演示。我們不會(huì)從頭開(kāi)始構(gòu)建這些 - 我們只會(huì)介紹它們背后的基本思想

          一、響應(yīng)橫條

          在這種情況下,我們的實(shí)際元素是前面較小的矩形,而后面的數(shù)字正方形和較大的矩形分別使用:before和:after偽元素創(chuàng)建。 數(shù)字方塊的背景是單獨(dú)的,并使用--slist對(duì)于每個(gè)項(xiàng)目不同的停止列表變量進(jìn)行設(shè)置。

          <p style='--slist: #51a9ad, #438c92'><!-- 1st paragraph text --></p>
          <p style='--slist: #ebb134, #c2912a'><!-- 2nd paragraph text --></p>
          <p style='--slist: #db4453, #a8343f'><!-- 3rd paragraph text --></p>
          <p style='--slist: #7eb138, #6d982d'><!-- 4th paragraph text --></p>
          
          

          影響橫幅樣式的因素是平價(jià),以及我們是處于廣泛,正常還是狹窄的情況。這些給我們的開(kāi)關(guān)變量

          html {
           --narr: 0;
           --comp: calc(1 - var(--narr));
           --wide: 1;	
           @media (max-width: 36em) { --wide: 0 }
           @media (max-width: 20em) { --narr: 1 }
          }
          p {
           --parity: 0; 
           &:nth-child(2n) { --parity: 1 }
          }
          
          

          數(shù)字方塊絕對(duì)定位,它們的位置取決于奇偶校驗(yàn)。如果--parity開(kāi)關(guān)關(guān)閉(0),則它們?cè)谧髠?cè)。如果它在(1)上,那么它們就在右邊。 一個(gè)值left: 0%沿著其父元素的左邊緣與數(shù)字方塊的左邊緣left: 100%對(duì)齊,而一個(gè)值沿著父元素的右邊緣對(duì)齊其左邊緣。 為了使數(shù)字方塊的右邊緣與其父邊緣的右邊緣對(duì)齊,我們需要從前一個(gè)100%值中減去自己的寬度。(請(qǐng)記住,%偏移量的值是相對(duì)于父級(jí)的尺寸。)

          left: calc(var(--parity)*(100% - #{$num-d}))
          
          

          ... $num-d編號(hào)方塊的大小在哪里。 在寬屏幕的情況下,我們還向外推送編號(hào)1em- 這意味著減去1em我們迄今為止對(duì)于奇數(shù)項(xiàng)目(--parity關(guān)閉開(kāi)關(guān))1em的偏移量,并添加到目前為止偶數(shù)項(xiàng)目的偏移量(--parity開(kāi)啟時(shí)) )。 現(xiàn)在問(wèn)題是......我們?nèi)绾吻袚Q標(biāo)志?最簡(jiǎn)單的方法是使用的權(quán)力-1。遺憾的是,我們?cè)贑SS中沒(méi)有冪函數(shù)(或冪函數(shù)運(yùn)算符),即使它在這種情況下非常有用:

          pow(-1, var(--parity))復(fù)制代碼
          

          這意味著我們必須使它與我們所擁有的(加法,減法,乘法和除法)一起工作,這導(dǎo)致了一個(gè)奇怪的小公式......但是,嘿,它有效!

          --sign: calc(1 - 2*var(--parity))
          
          left: calc(var(--parity)*(100% - #{$num-d}) - var(--wide)*var(--sign)*1em)
          
          

          我們還width使用這些變量來(lái)控制段落,并且max-width我們希望它具有上限并且僅在窄case(--narr: 1)中水平地完全覆蓋其父級(jí):

          width: calc(var(--comp)*80% + var(--narr)*100%);
          max-width: 35em;
          
          

          這font-size也取決于我們是否處于狹窄的情況(--narr: 1)或不是(--narr: 0):

          calc(.5rem + var(--comp)*.5rem + var(--narr)*2vw)
          
          

          ......對(duì)于:after偽元素(后面較大的矩形)的水平偏移也是如此,因?yàn)樗鼈?在窄情況(--narr: 1)中,而非零偏移,$off-x否則(--narr: 0)

          right: calc(var(--comp)*#{$off-x}); 
          left: calc(var(--comp)*#{$off-x});
          
          

          二、懸停并注重效果

          這個(gè)效果是通過(guò)一個(gè)鏈接元素和它的兩個(gè)偽元素在對(duì)角:hover和:focus狀態(tài)上對(duì)角滑動(dòng)創(chuàng)建的。鏈接的尺寸是固定的,其偽元素也是固定的,設(shè)置為它們的父對(duì)角線$btn-d(在寬度和高度形成的直角三角形中斜邊計(jì)算)水平和父height垂直。

          該:before定位使得它的左下角恰逢其父,而:after被定位為使得其右上角與其父一致。由于兩者都應(yīng)與height其父級(jí)相同,因此通過(guò)設(shè)置top: 0和解決垂直位置bottom: 0。水平放置的處理方式與前一個(gè)示例完全相同,使用--i切換變量來(lái)更改兩個(gè)偽元素之間的值,并使用--j其互補(bǔ)(calc(1 - var(--i))):

          left: calc(var(--j)*(100% - #{$btn-d}))
          
          

          我們?cè)O(shè)定transform-origin的:before到它的左下角(0% 100%)和:after其右上角的(100% 0%),再次,與交換機(jī)的幫助--i和補(bǔ)充--j

          transform-origin: calc(var(--j)*100%) calc(var(--i)*100%)
          
          

          我們將兩個(gè)偽元素旋轉(zhuǎn)到對(duì)角線和水平線之間的角度 $btn-a(也是由高度和寬度形成的三角形計(jì)算出來(lái)的,作為兩者之間比率的反正切)。通過(guò)這種旋轉(zhuǎn),水平邊緣沿著對(duì)角線相交。 然后我們按照自己的寬度向外移動(dòng)它們。這意味著我們將為兩者中的每一個(gè)使用不同的符號(hào),同樣取決于在:before和之間改變值的switch變量,:after就像前面的橫幅示例一樣:

          transform: rotate($btn-a) translate(calc((1 - 2*var(--i))*100%))
          
          

          在:hover和:focus,這個(gè)切換必須回去0。這意味著我們通過(guò)互補(bǔ)乘以上面的平移量--q的開(kāi)關(guān)變量--p這是0在正常狀態(tài)下和1在:hover或:focus狀態(tài):

          transform: rotate($btn-a) translate(calc(var(--q)*(1 - 2*var(--i))*100%))
          
          

          為了使偽元素在鼠標(biāo)移出或失焦時(shí)以相反的方式滑出(不回溯它們進(jìn)入的方式),我們將switch變量設(shè)置--i為--pfor :before的值,并將值設(shè)置--q為for :after,反轉(zhuǎn)轉(zhuǎn)換的符號(hào),確保只轉(zhuǎn)換transform屬性

          三、響應(yīng)信息

          在這種情況下,我們?yōu)槊總€(gè)項(xiàng)目(article元素)都有一個(gè)三行,兩列網(wǎng)格,第三行在寬屏幕場(chǎng)景中折疊,第二列在窄屏幕場(chǎng)景中折疊。在寬屏幕場(chǎng)景中,列的寬度取決于奇偶校驗(yàn)。在窄屏場(chǎng)景中,第一列跨越元素的整個(gè)內(nèi)容框,第二列具有寬度0。我們?cè)诹兄g也存在差距,但僅限于寬屏場(chǎng)景。

          $col-1-wide: calc(var(--q)*#{$col-a-wide} + var(--p)*#{$col-b-wide});
          $col-2-wide: calc(var(--q)*#{$col-b-wide} + var(--p)*#{$col-a-wide});
          $row-1: calc(var(--i)*#{$row-1-wide} + var(--j)*#{$row-1-norm});
          $row-2: calc(var(--i)*#{$row-2-wide} + var(--j)*#{$row-2-norm});
          $row-3: minmax(0, auto);
          $col-1: calc(var(--i)*#{$col-1-wide} + var(--j)*#{$col-1-norm});
          $col-2: calc(var(--i)*#{$col-2-wide});
          $art-g: calc(var(--i)*#{$art-g-wide});
          html {
           --i: var(--wide, 1); 
           --j: calc(1 - var(--i));
           @media (max-width: $art-w-wide + 2rem) { --wide: 0 }
          }
          article {
           --p: var(--parity, 0);
           --q: calc(1 - var(--p));
           --s: calc(1 - 2*var(--p));
           display: grid;
           grid-template: #{$row-1} #{$row-2} #{$row-3}/ #{$col-1} #{$col-2};
           grid-gap: 0 $art-g;
           grid-auto-flow: column dense;
           &:nth-child(2n) { --parity: 1 }
          }
          
          

          既然我們已經(jīng)設(shè)置了grid-auto-flow: column dense,我們可以在寬屏幕情況下只設(shè)置第一級(jí)標(biāo)題來(lái)覆蓋整個(gè)列(第二個(gè)用于奇數(shù)項(xiàng),第一個(gè)用于偶數(shù)項(xiàng)),并讓第二個(gè)級(jí)別標(biāo)題和段落文本填寫(xiě)第一個(gè)可用單元格。

          grid-column: calc(1 + var(--i)*var(--q));
          grid-row: 1/ span calc(1 + 2*var(--i));
          
          

          對(duì)于每個(gè)項(xiàng)目,一些其他屬性取決于我們是否處于寬屏幕方案中。 在寬屏幕情況下,垂直margin,垂直和水平padding值,box-shadow偏移和模糊都更大:

          $art-mv: calc(var(--i)*#{$art-mv-wide} + var(--j)*#{$art-mv-norm});
          $art-pv: calc(var(--i)*#{$art-pv-wide} + var(--j)*#{$art-p-norm});
          $art-ph: calc(var(--i)*#{$art-ph-wide} + var(--j)*#{$art-p-norm});
          $art-sh: calc(var(--i)*#{$art-sh-wide} + var(--j)*#{$art-sh-norm});
          article {
           margin: $art-mv auto;
           padding: $art-pv $art-ph;
           box-shadow: $art-sh $art-sh calc(3*#{$art-sh}) rgba(#000, .5);
          }
          
          

          我們有一個(gè)非零border-width和border-radius寬屏幕的情況

          $art-b: calc(var(--i)*#{$art-b-wide});
          $art-r: calc(var(--i)*#{$art-r-wide});
          article {
           border: solid $art-b transparent;
           border-radius: $art-r;
          }
          
          

          在寬屏幕場(chǎng)景中,我們限制項(xiàng)目width,但100%不管怎樣。

          $art-w: calc(var(--i)*#{$art-w-wide} + var(--j)*#{$art-w-norm});
          article {
           width: $art-w;
          }
          
          

          padding-box 漸變的方向也隨奇偶校驗(yàn)而變化:

          background: 
           linear-gradient(calc(var(--s)*90deg), #e6e6e6, #ececec) padding-box, 
           linear-gradient(to right bottom, #fff, #c8c8c8) border-box;
          
          

          以類(lèi)似的方式,margin,border-width,padding,width,border-radius,background梯度方向,font-size或line-height對(duì)標(biāo)題和段落文本還取決于我們是否是在寬屏場(chǎng)景(在第一級(jí)標(biāo)題的情況下border-radius或background梯度方向,也在奇偶校驗(yàn))。

          看效果:

          最后

          本篇文章主要介紹了使用CSS變量來(lái)驅(qū)動(dòng)布局和交互的切換的策略,其中值得注意的是:只適用于數(shù)值 - 長(zhǎng)度,百分比,角度,持續(xù)時(shí)間,頻率,無(wú)單位數(shù)值等.

          SS也能寫(xiě)變量了???

          其實(shí)早在2015年,層疊變量的自定義屬性(Custom Properties for Cascading Variables)就已經(jīng)問(wèn)世了,給CSS引進(jìn)了變量的概念。允許我們聲明一個(gè)變量,然后在樣式表的其他地方引用這個(gè)值。到目前為止,各大瀏覽器廠商基本支持了這個(gè)新特性。


          css variables


          肯定有小伙伴想,一些css預(yù)處理器也支持變量啊,比如less,sass等。css變量和預(yù)處理器里面的變量有著本質(zhì)的區(qū)別,css變量是瀏覽器支持的特性,而預(yù)處理器的變量近在css的處理過(guò)程中支持,處理完成后這些變量會(huì)代替為具體的值。

          定義一個(gè)css變量

          :root {
          	--main-font: sans-sarif;
          }

          上面的代碼定義了一個(gè)名為--main-font的變量。變量名前必須有兩個(gè)連字符(--)。

          變量必須在一個(gè)聲明塊內(nèi)聲明。這里使用了:root選擇器,因此這個(gè)變量可以在整個(gè)網(wǎng)頁(yè)使用。這里可以推斷出,css變量是有作用域的概念的,如果是定義在別的選擇器里面的話,只能在應(yīng)用了這個(gè)選擇器元素的子元素所用的類(lèi)中去引用這個(gè)變量。文字有點(diǎn)繞,我們看個(gè)具體的例子。


          css variable示例


          :root、page-content選擇器中定義了分別定義了--main-color、--content-color兩個(gè)顏色變量。在類(lèi)page-content中可以引用--main-color,在類(lèi)page-content-spec中可以引用--content-color,而在類(lèi)page-title中無(wú)法引用--content-color變量。

          動(dòng)態(tài)改變css variables

          不要將css variables理解為一個(gè)全局的常量,定義在:root中,在子選擇器中引用;應(yīng)該被看作一個(gè)選擇器的入?yún)ⅲ斎氩煌膮?shù),有不同的表現(xiàn)。簡(jiǎn)單來(lái)說(shuō),可以定義一個(gè)變量為黑色,然后在某個(gè)容器中重新將其定義為白色。那么基于該變量的任何樣式,在容器外部都會(huì)動(dòng)態(tài)解析為黑色,而在容器內(nèi)部會(huì)動(dòng)態(tài)解析為白色。

          我們還可以使用JavaScript在瀏覽器中實(shí)時(shí)訪問(wèn)和修改自定義屬性。例如:

          var rootElement=document.documentElement;
          rootElement.style.setProperty('--main-color', 'red')

          總結(jié)

          利用這種技術(shù),是不是可以方便的提取網(wǎng)頁(yè)主題等特性,實(shí)時(shí)切換網(wǎng)站主題?

          雖然大部分瀏覽器廠商都支持了css variable特性,但是某些廠商和版本依然不支持,所以我們?cè)谑褂眠@個(gè)特性的時(shí)候,應(yīng)該準(zhǔn)備一個(gè)回退方案,類(lèi)似下面的例子(相當(dāng)于設(shè)置了一個(gè)默認(rèn)值):

          color: black;
          color: var(--main-color)

          好了,今天的內(nèi)容就講到這里了,小伙伴們覺(jué)得怎么樣?歡迎大家在評(píng)論區(qū)留言和我一起探討!


          主站蜘蛛池模板: 78成人精品电影在线播放日韩精品电影一区亚洲 | 亚洲一区二区三区不卡在线播放| 日韩aⅴ人妻无码一区二区| 在线观看国产一区亚洲bd| 一区二区三区AV高清免费波多| 国产99精品一区二区三区免费| 国产精久久一区二区三区| 一区二区三区高清视频在线观看| 中文字幕色AV一区二区三区| 精品人妻码一区二区三区| 国产精品无码一区二区三区在| 中文字幕不卡一区| 无码人妻啪啪一区二区| 无码精品人妻一区| 久久综合亚洲色一区二区三区| 在线一区二区观看| 免费日本一区二区| 久久久精品日本一区二区三区| 亚洲日韩AV一区二区三区四区| 国产不卡视频一区二区三区| 无码视频免费一区二三区| 亚洲国产精品乱码一区二区| 日本精品一区二区三区在线视频一 | 亚洲色欲一区二区三区在线观看 | 亚洲一区二区三区久久久久| 久久91精品国产一区二区| 精品一区二区三区高清免费观看| 日韩精品国产一区| 国产精品538一区二区在线| 国产一区二区三区乱码在线观看| 无码丰满熟妇一区二区| 色一情一乱一区二区三区啪啪高| 综合无码一区二区三区四区五区 | 97se色综合一区二区二区| 亚洲国产精品综合一区在线| 亚洲AV无码一区二区三区牛牛| 亚洲综合一区二区| 无码人妻精一区二区三区| 国产成人一区二区动漫精品| 国产乱码精品一区二区三| 国产精品一区二区av|