CSS变量自动换色技术
时间:2023-03-28 17:04:51
HTML
欢迎关注微信公众号:前端探员在四福上看到了这样一个设计,当阅读量比较小的时候,文字是灰色的,当阅读量比较大的时候(>=100),文字变成了棕色,效果如下,是不是很醒目?此外,还有一个进度条,可以根据进度自动改变颜色。其实这样的逻辑判断也可以通过纯CSS实现如下。主要用到CSS变量和边界值计算。现在就分享给大家。1.基本数学原理CSSDirect中没有if判断逻辑。要达到这样的效果,就需要充分利用CSScalc的计算特性和临界条件。假设你要实现这样一个逻辑:--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]区间取较小的值,所以当--y大于等于100时最终结果为10,比如100,计算(var(--y)-99)*99的结果是99,在区间[10,20]中取较大的值,所以最后的结果是20。用一张图来表达如下。为什么要在这里繁衍?99呢?其实就是放大插值操作。严格来说,本例中大于20即可。当乘以20时,范围变为...,-20,0,20,40,...,还包括区间[10,20]。这就是CSS中if判断的基本原理。使用了一点数学运算。接下来我们来看看实战效果。2、首先通过饱和度的变化做一个简单的布局。因为纯CSS无法获取值的大小,所以我们需要使用CSS变量来计算。,所以HTML可以1read99read102Reading如果不考虑HTML语义或SEO等因素,“number”和“reading”"这里num::before{counter-reset:numvar(--num);content:counter(num);}num::after{content:'reading';}这样,HTML可以进一步简化Simplefor修改后的效果如下。既然是灰色和棕色之前的变化,一个简单的方法就是通过饱和度来控制。比如这里的棕色是#aa540e,hsl颜色是hsl(27,50%,36%)。饱和度可以如下控制颜色的鲜艳度。饱和度越高,颜色越亮,饱和度越低,颜色越暗。当饱和度降到0时,就变成全灰了,如下图。因此,这里要切换两种颜色,可以计算饱和度,具体规则是当--num大于等于100时,饱和度为85%,否则为0%,使用的基本原理上一节,所以实现是num{--s:clamp(0%,(var(--num)-99)*99%,85%);/*>100*/color:hsl(27var(--s)36%);}逻辑同上,不再赘述,实际效果如下由于饱和度本身也有一个“阈值”,当饱和度低于0%时,仍然渲染为0%,所以上面的实现可以去掉最小值,简化版如下num{--s:min((var(--num)-99)*99%,85%);color:hsl(27var(--s)36%);}也可以达到同样的目的3.完整的颜色控制虽然饱和度变化控制比较容易,只需要控制一个参数就可以了,但是还是有一些限制。首先,这个灰色可能不是设计师想要的灰色(实际上可能会稍微浅一点)。而且,换色不够自由。比如默认是蓝色,一定量后变成红色。控制住。因此,我们需要以完全解析的方式来实现它。原理是控制颜色的三个参数,要么rgb要么hsl,假设两种颜色分别为rgb(29125250)和rgb(2446754),如下,不仅有增量变化,还有递减变化变化(例如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,需要改大一些。比如999clamp支持的参数必须是[min,val,max],min和max不能互换,所以重新实现上面的代码。实际效果如下4.自动改变背景颜色虽然可以通过以上方法实现自动改变颜色,但是还是有一些不足之处。代码量比较大,有些繁琐,容易混淆,尤其是前后序号的顺序只适用于两种颜色的变化,比如各种分段颜色可能做不出来。与纯色相比,背景在多层叠加上有很大的优势。如果你控制了每一个背景的大小,你能控制最终显示的颜色吗??还是上面的例子,我们先通过渐变绘制两层背景,上面是红色rgb(2446754),下面是蓝色rgb(29125250),然后用background-size来控制大小每一层,原理是这样的,具体实现如下num{background:linear-gradient(rgb(2446754),rgb(2446754)),linear-gradient(rgb(29125250),rgb(29125250));颜色:#fff;background-size:calc((var(--num)-99)*100%),100%;}其实这个计算是基于一个简单的解释:当--num大于等于100时,计算结果必须大于100%,所以可以看到上面的红色背景,整体表现为红色。当--num小于100时,计算结果必须小于等于0%。即使是负数,background-size也被解析为0%,所以上面的红色背景是看不见的,下面蓝色的整体表现如下。如果要更改文本颜色,可以使用background-clipnum{background:linear-gradient(rgb(2446754),rgb(2446754)),linear-gradient(rgb(29125250),rgb(29125250));颜色:透明;背景大小:calc((var(--num)-99)*100%),100%;-webkit-background-clip:text;}是不是比上面的方法简单多了?5.自动变色进度条背景也可以适配多种颜色接下来我们看文章开头的一个案例,实现这样一个可以自动变色的进度条。有几个规则:当进度小于30%时,背景为红色;当进度大于30%小于60%时,背景为橙色;当进度大于60%小于90%时,背景为蓝色。当进度大于90%时,背景为绿色。假设HTML如下
CSS变量可以通过CSS伪类和计数器显示在页面上。有兴趣的可以看看张新旭的这篇文章:小技巧:如何使用content属性显示CSSvar变量值(本例也是在此基础上修改的),只需修改.bar{display:flex;高度:20px;背景色:#f5f5f5;}.bar::before{counter-reset:progressvar(--percent);内容:计数器(进度)'%\2002';显示:弹性;证明内容:结束;宽度:计算(变量(--百分比)*1%);字体大小:12px;颜色:#fff;背景:#2486ff;white-space:nowrap;}效果如下那么如何根据进度自动改变颜色呢?原理还是差不多的!首先,通过渐变绘制几种颜色,将最后一种颜色放在最前面,然后根据CSS变量控制背景大小。原理如下:由于background-size本身是有边界限制的,当小于0%时,仍然是Renderat0%,所以不需要用clamp来限制,减少代码量.具体的代码实现是这样的。bar::before{/*其他样式*/background-image:linear-gradient(green,green),linear-gradient(#2486ff,#2486ff),linear-gradient(orange,orange),linear-渐变(红色,红色);背景大小:calc((var(--percent)-90)*100%)100%,calc((var(--percent)-60)*100%)100%,calc((var(--percent)-30)*100%)100%,100%100%;}简单看一下里面的逻辑:当--percent大于90时,所有背景都是100%大小,自然显示当绿色上toplayer大于60小于等于90,只有toplayer的绿色尺寸为0,其他背景尺寸为100%,所以--percent更大时显示第二层的蓝色小于30且小于等于60时,上两层背景尺寸为0,下两层背景尺寸为100%,所以显示第三层的橙色。当--percent小于30时,只有底层的size为100%,其他均为0,所以底层红色的实际表现如下。向外移动,变红向外移动,可以通过text-indent属性实现,文字颜色由白变红(hsl(0,100%,50%)),可以通过亮度实现,当亮度为100%,任何颜色都会变成白色。由于亮度本身的限制,当超过100%时,依然会按照100%进行渲染。这个可以用。具体实现如下。bar::before{/*其他样式*/--l:max(50%,(var(--percent)-9)*100%);颜色:hsl(0,100%,var(--l));--offset:clamp(0%,(var(--percent)-10)*-120%,120%);text-indent:var(--offset);}这里的计算原理也和前面一样,大家可以在这里仔细斟酌。实际效果如下:可以看出当百分比小于10时,文字在外面,避免了空格不足,非常聪明。完整代码可以访问:CSSautocolor(codepen.io)6.综上所述,以上就是CSS自动换色技术。核心其实就是边界值的灵活计算。是不是很厉害?这里总结一下实现要点:实现原理是CSS变量和calc计算clamp来限制表达式的范围。通用核心代码--x:clamp(10,(var(--y)-99)*99,20)saturation可以控制颜色的鲜艳程度。当饱和度为0时,它变成灰色。完全控制颜色变化,可以完全用rgb或hsl表示,单独计算。以上方案只适用于两种颜色的切换。多层背景叠加可以实现多色切换多层背景切换的核心是背景大小的控制。当亮度为100%时,颜色变为白色。部件属性本身有一个“阈值”。充分利用这个特性可以减少区域判断。当然这个技术不仅仅适用于颜色的变化,只要是值的变化,比如文章中text-indent的切换,充分利用这些小技巧可以让我们的页面更??加灵活,更精致。最后,如果觉得对你有好处和帮助,请点赞、收藏、转发???欢迎关注微信公众号:前端大侦探