13

前端设置任何颜色作为主题色(不用预先指定固定几种),吐血整理

 3 years ago
source link: https://zhuanlan.zhihu.com/p/338440777
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前端设置任何颜色作为主题色(不用预先指定固定几种),吐血整理

微信公众号:web前端学习圈,关注领取85G前端全套系统教程

项目中,本来要提供2个主题,一个深色,一个浅色,本来想利用scss来实现,但是觉得,如果后期,再有3个、4个呢?感觉这种提供几种固定主题的方案,有些不太灵活,正好看到element-ui中主题,可以随意指定

v2-9040490697a076a6b2ca7fd702b64a86_720w.jpg
v2-98baf8906223381769e6912c50e41486_720w.jpg

于是也,准备实现一个随时可以定制的主题功能。

一、参考element-ui中的主题切换

查看element-ui在切换主题时发送的请求

发现,它其实是通过把前端选择的主题色,当做参数,然后发送给后端,然后让后端生成一个新的css文件,再发给前端。

然后再通过js,将css设置到head中的style上,完成主题切换。

不过需要注意:
返回的css文件,不仅仅是简单的将颜色替换为我们刚才选择的那个主题色,还需要进行一些“颜色的计算”。

v2-7710572316c370b1a82c1f32e00f45a4_b.jpg

如图所示,button在hover时,会在主题色上有个减淡的效果。

也就是说,对于我们选择的任何颜色,都必须计算出一个减淡的颜色值,赋值给那些有hover的class。

我知道大家会问,颜色我怎么计算?比如白色 #ffff,我如何进行加减乘除?

二、使用color库,对主题色进行计算

这里有个神器。名称叫做 Color, 可以在npm中搜索,并安装它。

>npm install color

详细用法可以查看npm介绍,这里不赘述。

那么又有一个问题来了。我知道怎么操作它,但是计算规则是什么?

这个确实不好找,element-ui后端将主题色简单的规则,我们也无从得知。

然而,经过我一番尝试,发现公式很简单:
将任意的主题色和“不同程度的白色”进行“混合”得到的。

如button的hover,正好是将主题色#8F13ED与0.2程度的白色(1就是完全白,0就是全黑)进行混合而得到。

let primaryColor = "#8F13ED";
Color(primaryColor)
  .mix(Color("white"), 0.2)
  .hex()      //#A542F1  

顺着这个思路,你可以对照element-ui中某一个主题,可以将所有的规则都找出来,只不过混合程度不一样,有的是0.9,或者0.92,或者0.8等等。

现在解决了如何计算得到所有与主题色相关的颜色,那么接下来解决发送请求,后端将这个css文件返回给前端。

不过,我本着前端得事情,前端干的原则。这个css文件不需要后端返回,而是前端自己生成。

先将模板主题文件下载下来。

然后复制到js中。

这是我已经构造好的文件,由于比较大,所以放到百度云下面

链接: https://pan.baidu.com/s/1PpAMjl4dF7zBrvv5zOP2Gg 
 提取码: gegh

到此为止,已经解决了,从选择主题色,到生成对应主题色的css文件的流程,此后,当切换任意颜色时。所有element的组件都会变。但也仅仅是element的组件会变,你自定义的样式和组件,并不会变。

那么我们自定义的组件是如何拿到我们设置的主题色,以及通过主题色计算出来的相关颜色呢?

可以使用css变量。

三、使用css变量

关于什么是css变量,以及怎么用。可以参考阮一峰的这篇文章
CSS 变量教程

而且它的兼容性,也非常好。

简而言之,就是定义一个,以"--"开头的变量,这样浏览器就会将它当做一个css的变量来进行处理,然后使用var()引用这个变量。

--hover-color:red;    //定义变量
background-color: val(--hover-color)   //通过css内置函数var,使用变量

打开刚才从百度网盘下载的index.js。在最后面加上

//设置全局css变量
  jquery("body").attr(
    "style",
    `--primary-color:${primaryColor};
    --success-color:${successColor};
    --warning-color:${warningColor};
    --danger-color:${dangerColor}`
  );

打开浏览器控制台,可以看到变量已经生效。

之后,你在组件的任何位置想使用 定义好的全局变量,都是没问题的

background-color: var(--primary-color);

如果觉得不错就给个赞吧,你的鼓励是我前进的动力(相信你看完这篇文章,你会啪的一下站起来,很快啊)

原作者姓名: 寒水寺一禅
原出处:segmentfault
原文链接:前端设置任何颜色作为主题色(不用预先指定固定几种),吐血整理_小李子的前端 - SegmentFault 思否


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK