成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊 CSS 變量自動變色技術

開發 前端
CSS 中并沒有直接的 if 判斷邏輯。要實現這樣一種效果,必須充分利用 CSS calc 的計算特性和臨界條件。

偶爾在網上看到這樣一個設計,當閱讀量比較少時,文字呈灰色,當閱讀量比較多(>=100)時,文字就變成褐色了,示意效果如下:

是不是非常醒目呢?

另外,還有那種可以根據進度自動變色的進度條,如下:

其實通過純 CSS 也能實現這樣的邏輯判斷,主要用到了 CSS 變量和邊界值計算,現在分享一下:

一、基本數學原理

CSS 中并沒有直接的 if 判斷邏輯。要實現這樣一種效果,必須充分利用 CSS calc 的計算特性和臨界條件。

假設要實現這樣一個邏輯:

--x默認值為 10,當變量--y大于等于 100 時,--x變為 20。

如何實現呢?這里先給出答案,然后進行分析:

--x: clamp(10,(var(--y) - 99) * 99,20)

這里用到了 clamp函數,你可以理解為一個區間,有 3 個值 [Min, Val, Max],前后分別是最小、最大值,中間是動態值,這里其實就是一個簡單的線性函數,并且單調遞增,所以這里的邏輯就是:

當--y小于 100 時,比如 99,(var(--y) - 99) * 99 的計算結果是 0,再小就是負數了,在 [10, 20] 區間中取較小值,所以最終結果是 10。

當--y大于等于 100 時, 比如 100 ,(var(--y) - 99) * 99 的計算結果是 99,在 [10, 20] 區間中取較大值,所以最終結果是 20。

用一張圖表示如下:

為什么這里需要乘以 99 呢?其實是一個放大插值的操作,嚴格來講,這個例子中只要大于 20 就夠了,當乘以 20 以后,范圍就變成了 ...、-20、0、 20、40、...,也是包含 [10, 20] 這個區間的。

這個就是CSS 中 if 判斷的基本原理了,用到了一點點數學運算,接下來看實戰效果。

二、通過飽和度變化

首先簡單布局一下;

由于純 CSS 無法獲取到數值的大小,這里需要借助 CSS 變量進行計算,所以 HTML 可以這樣。

<num style="--num:1">1<span>閱讀</span></num>
<num style="--num:99">99<span>閱讀</span></num>
<num style="--num:102">102<span>閱讀</span></num>

如果不考慮 HTML 語義或者 SEO 這類因素,這里的“數字”和“閱讀”都可以通過偽元素來生成;

num::before {
counter-reset: num var(--num);
content: counter(num);
}
num::after {
content: '閱讀';
}

于是,HTML 可以進一步簡化為:

<num style="--num:1"></num>
<num style="--num:99"></num>
<num style="--num:102"></num>

簡單修飾后效果如下:

由于是灰色和褐色之前的變化,一種簡單的方式是通過飽和度來控制,比如這里褐色的顏色是#aa540e,用 hsl 顏色表示就是 hsl(27, 50%, 36%),如下:

這里飽和度可以控制顏色的鮮艷程度。飽和度越高,顏色越鮮艷,飽和度越低,顏色越暗淡,當飽和度降為 0,就變成徹底的灰色了,如下:

所以,這里要實現兩種顏色的切換,可以通過計算飽和度,具體規則就是。

當 --num大于等于 100 時,飽和度為 85%,否則為 0%,利用前面一節的基本原理,所以實現就是。

num{
--s: clamp(0%,(var(--num) - 99) * 99%,85%);/* >100 */
color: hsl(27 var(--s) 36%);
}

邏輯和前面一致,這就不重復了,實際效果如下:

Kapture 2022-04-21 at 15.55.20

由于飽和度本身也有“閾值”,當飽和度低于 0% 時,仍然按照 0% 來渲染,所以上面實現可以去除最小值,簡化后如下:

num{
--s: min((var(--num) - 99) * 99% ,85%);
color: hsl(27 var(--s) 36%);
}

同樣能達到相同的目的。

三、完全顏色控制

雖然飽和度變化控制比較容易,只需要控制一個參數就行了,但還是有些局限性。

首先,這個灰色可能并不是設計師想要的灰色(實際可能會偏淡一點),再者,顏色變化不夠自由,比如,默認是一個藍色,超出一定數量后變成紅色,這種就無法控制了。

于是,我們需要用完全解析的方式來實現,原理其實就對顏色的 3 個參數進行控制,rgb 或者 hsl 都可以,假設兩個顏色分別是rgb(29 125 250)和rgb(244 67 54),如下:

這里不僅有遞增的變化,也有遞減的變化(比如,125 => 67、250 => 54),所以在 calc 計算的時候需要取反,具體實現如下:

num{
--r: clamp(29, (var(--num) - 99) * 999 + 29 , 250);/*29, 250*/
--g: clamp(67, (var(--num) - 100) * -999 + 67 , 125);/*128, 67*/
--b: clamp(54, (var(--num) - 100) * -999 + 54 , 250);/*250, 54*/
color: rgb(var(--r) var(--g) var(--b));
}

需要注意幾點:

  • 系數需要足夠大,這里是 999,比如第一條,當 --num 為 100 時,如果系數是 99,那么計算的結果是 99 + 29,沒有達到最大值 250,所以需要改大一點,比如 999。
  • clamp 支持的參數必須是 [min, val, max],min 和 max 不能對調,所以以上代碼在實現時做了交換。

實際效果如下:

Kapture 2022-04-21 at 16.43.24

四、自動背景顏色變化

雖然顏色可以通過上述方式進行自動變化,但是還是有些不雅。

  • 代碼量比較多,有些繁瑣,容易混淆,特別是前后數字的順序。
  • 只適用于兩個顏色的變化,比如多種分段的顏色可能就無法實現了

背景相比于單純的顏色來說,有一個非常大的優勢在于多層疊加,如果控制每個背景的大小,不就可以控制最終展示的顏色了嗎?

還是上面這個例子,我們先通過漸變繪制兩層背景,上面是紅色rgb(244 67 54),下面是藍色rgb(29 125 250),然后通過background-size來控制每一層的大小,原理是這樣的:

具體實現如下:

num{
background: linear-gradient(rgb(244 67 54),rgb(244 67 54)),
linear-gradient(rgb(29 125 250), rgb(29 125 250));
color: #fff;
background-size: calc( (var(--num) - 99) * 100% ), 100%;
}

其實這個計算根據簡單,解釋一下:

  • 當 --num 大于等于 100 時,計算結果肯定是大于 100% 的,所以上面的紅色背景是可見的,整體表現為紅色。
  • 當 --num 小于 100 時,計算結果肯定是小于等于 0% 的,即使是負數,background-size 也解析為 0%,所以上面的紅色背景是不可見的,整體表現為下面的藍色。

實際表現如下:

Kapture 2022-04-21 at 18.19.56

如果希望實現文字顏色的變化,可以利用到 background-clip。

num{
background: linear-gradient(rgb(244 67 54),rgb(244 67 54)),
linear-gradient(rgb(29 125 250), rgb(29 125 250));
color: transparent;
background-size: calc( (var(--num) - 99) * 100% ), 100%;
-webkit-background-clip: text;
}

Kapture 2022-04-21 at 18.29.38

是不是相比上面的方式簡單了許多呢?

五、自動變色的進度條

背景還可以適配多種顏色。接下來看一個文章開頭的案例,實現這樣一個可以自動變色的進度條,有這樣幾條規則:

  • 當進度小于 30% 時,背景呈紅色。
  • 當進度大于 30% 并且 小于 60% 時,背景呈橙色。
  • 當進度大于 60% 并且 小于 90% 時,背景呈藍色。
  • 當進度大于 90% 時,背景呈綠色。

示意如下:

假設 HTML 如下:

<div class="bar" style="--percent: 50;"></div>

可以通過 CSS 偽類和計數器將 CSS 變量顯示在頁面,有興趣的可以看看張鑫旭老師的這篇文章:小tips: 如何借助content屬性顯示CSS var變量值[1](這個案例也是在這個基礎上修改的),簡單修飾一下。

.bar {
display: flex;
height: 20px;
background-color: #f5f5f5;
}
.bar::before {
counter-reset: progress var(--percent);
content: counter(progress) '%\2002';
display: flex;
justify-content: end;
width: calc(var(--percent) * 1%);
font-size: 12px;
color: #fff;
background: #2486ff;
white-space: nowrap;
}

效果如下:

那么該如何根據進度自動變色呢?

原理還是類似的!首先,還是將幾個顏色通過漸變繪制出來,最后的顏色放在最前面,然后根據 CSS 變量控制背景尺寸就行了,原理示意如下:

由于background-size本身有邊界限制,當小于 0% 時,仍然按 0% 來渲染,所以這里可以不必用 clamp來加以限制,減少代碼量,具體代碼實現是這樣的:

.bar::before{
/*其他樣式*/
background-image: linear-gradient(green,green),
linear-gradient(#2486ff,#2486ff),
linear-gradient(orange, orange),
linear-gradient(red, red);
background-size: calc( (var(--percent) - 90) * 100% ) 100%,
calc( (var(--percent) - 60) * 100% ) 100%,
calc( (var(--percent) - 30) * 100% ) 100%,
100% 100%;
}

簡單看一下里面的邏輯:

  • 當 --percent 大于 90 時,所有背景的尺寸都是 100%,自然顯示最上層的綠色。
  • 當 --percent 大于 60 ,小于等于 90 時,只有最上層的綠色尺寸是 0,其他背景尺寸都是 100%,所以顯示第二層的藍色。
  • 當 --percent 大于 30 ,小于等于 60 時,上面兩層背景尺寸都是 0,下面兩層背景尺寸都是 100%,所以顯示第三層的橙色。
  • 當 --percent 小于 30 時,只有最底層的尺寸是 100%,其他都是 0,所以顯示最底層的紅色。

實際表現如下:

Kapture 2022-04-21 at 23.00.00

背景自動變色已經實現了,不過數字還有一點小問題,當進度條比較小時,百分比數字明顯放不下了,如下:

所以,在這種情況下應該把百分比數字移到外面來,并且變成紅色。

移到外面,可以通過text-indent屬性來實現,文字顏色從白色變成紅色(hsl(0,100%,50%)),可以通過亮度來實現,當亮度為 100% 時,任何顏色都會變成白色,由于亮度本身有限制,當超過 100% 時,仍然按照 100% 來渲染,這一點可以利用起來,具體實現如下:

.bar::before{
/*其他樣式*/
--l: max(50%, (var(--percent) - 9 ) * 100%);
color: hsl(0, 100%, var(--l));
--offset: clamp(0%, ( var(--percent) - 10 ) * -120% , 120%);
text-indent: var(--offset);
}

這里的計算原理也和前面一樣,大家在這里可以仔細斟酌一下。

實際效果如下:

Kapture 2022-04-21 at 23.46.59

可以看到,當百分比小于 10 時,文字是在外部的,避免了空間不足的情況,非常智能。

完整代碼可以訪問:CSS auto color(codepen.io)[2] 或者 CSS auto color(juejin.io)[3]。

六、總結一下

以上就是關于 CSS 自動變色技術的全部內容了,核心其實就是邊界值的靈活計算,是不是非常強大呢?這里總結一下實現要點:

  • 實現原理是 CSS 變量 和 calc 計算;
  • clamp 可以限制表達式的區間范圍;
  • 通用核心代碼 --x: clamp(10,(var(--y) - 99) * 99,20);
  • 飽和度可以控制顏色的鮮艷程度,當飽和度為0,就變成灰色了;
  • 完全控制顏色變化,可以用 rgb 或者 hsl 完全表示出來,分別進行計算;
  • 以上方案僅適用于兩個顏色的切換;
  • 多層背景疊加可以實現多種顏色切換;
  • 多層背景切換的核心在于背景尺寸的控制;
  • 亮度為 100% 時,顏色就變成了白色;
  • 部分屬性本身有“閾值”,充分利用這種特性可以減少區域判斷。

當然,這種技術不僅僅適用于顏色的變化,只要是數值的變化都可以,比如文章中text-indent的切換,充分利用這些小技巧可以讓我們的頁面更加靈活,更加精致。

責任編輯:武曉燕 來源: 前端偵探
相關推薦

2023-07-24 09:41:08

自動駕駛技術交通

2024-07-26 09:47:28

2024-09-30 09:33:31

2023-05-31 08:42:02

管理產品技術項目

2024-09-09 00:00:00

編寫技術文檔

2022-11-14 08:32:51

CSS組件Box

2021-11-04 06:58:31

CSS性能設備

2024-02-20 21:34:16

循環GolangGo

2021-08-27 07:06:10

IOJava抽象

2023-08-10 08:28:46

網絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發模式

2022-05-24 08:21:16

數據安全API

2023-09-10 21:42:31

2022-05-05 12:57:40

架構

2023-10-31 14:04:17

Rust類型編譯器

2022-10-28 07:27:17

Netty異步Future

2022-11-12 12:33:38

CSS預處理器Sass

2022-02-14 07:03:31

網站安全MFA

2022-01-04 12:08:46

設計接口
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 特黄特色大片免费视频观看 | 精区3d动漫一品二品精区 | 在线视频第一页 | 亚洲欧美日韩精品久久亚洲区 | 亚洲九色 | 一级a性色生活片久久毛片 一级特黄a大片 | 91精品国产一区二区三区动漫 | 亚洲精品一区在线 | 亚洲国产区| 成人在线精品视频 | 久久久成人一区二区免费影院 | 久久久久久免费观看 | 激情一区二区三区 | 在线观看国产视频 | 自拍第1页| com.国产| 国产成年人小视频 | 伊人爽 | 日韩在线播放av | 午夜精品视频一区 | 国产精品成人一区 | 国产精品久久久99 | 亚州综合在线 | 久久久久久91香蕉国产 | 日韩精品在线观看网站 | 久久久精彩视频 | 在线看亚洲 | 亚洲午夜网 | 日韩欧美国产一区二区三区 | 亚洲精品久久久久中文字幕欢迎你 | 亚洲成人免费视频在线 | 亚洲一区二区三区视频免费观看 | 日韩精品一区二区三区视频播放 | 国产97碰免费视频 | 午夜视频一区二区 | 国产精品色婷婷久久58 | 免费的黄色片子 | 亚洲嫩草| 国产精品久久久久久久久久久新郎 | 欧美成人影院 | 免费观看一区二区三区毛片 |