使用 less/css 动态的切换主题色实现换肤功能
前言
说起换肤功能,前端肯定不陌生,其实就是颜色值的更换,实现方式有很多,也各有优缺点
看需求是什么
一般来说换肤的需求分为两种:
一种是几种可供选择的颜色/主题样式,进行选择切换,这种可供选择的主题切换不会很多
另一种是需要自定义色值,或者通过取色板取色,可供选择的范围就很大了
如何实现#
对于可供选择的颜色/主题样式换肤的实现
一个全局 class 控制样式切换
切换的时候 js 控制样式的切换
JS 改变 href 属性值切换样式表,例如:
这种方式需要维护几个主题样式表,js 点击切换的时候通过改变 css 样式表链接来实现。 例如这个demo
这种实现对于,颜色和主题多了的时候,维护起来就很麻烦,需要同时维护 n 个样式文件,并且使用 JS 改变 href 属性会带来加载延迟,样式切换不流畅,体验也不好。
但如果是有包含不同复杂背景图片切换的时候,这种方式可以实现,但其他如下面要说的 css 变量 less modifyVars 就无法实现了
HTML 的 rel 属性下的 alternate 实现: MDN Alternative style sheets 示例:
所有样式表都可分为 3 类:
没有 title 属性,rel 属性值仅仅是 stylesheet 的<link>无论如何都会加载并渲染,如 reset.css;
有 title 属性,rel 属性值仅仅是 stylesheet 的<link>作为默认样式 CSS 文件加载并渲染,如 default.css;
有 title 属性,rel 属性值同时包含 alternate stylesheet 的<link>作为备选样式 CSS 文件加载,默认不渲染,如 red.css 和 green.css;
alternate 意味备用,相当于是 css 预加载进来备用,所以不会有上面那种切换延时
但怎么用呢?禁用掉?
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
link 的 disabled 属性
使用 JavaScript 代码修改<link>元素 DOM 对象的 disabled 值为 false,可以让默认不渲染的 CSS 开始渲染。实现 demo
对于制定动态色值换肤的实现 # 如果是要实现动态换肤,自定义色值,那上面的几种方式就不适合了。
先看下已有的实现有哪些方法
Element-UI 有换肤功能 示例预览
实现原理: 官方解释
先把默认主题文件中涉及到颜色的 CSS 值替换成关键词:链接
根据用户选择的主题色生成一系列对应的颜色值:链接
把关键词再换回刚刚生成的相应的颜色值:链接
直接在页面上加 style 标签,把生成的样式填进去:链接
看这个实现,还是比较麻烦的,想看看还有没有更优雅的方法来实现
Ant Design 的更换主题色功能是用 less 提供的 modifyVars 的方式进行覆盖变量来实现。
less的 modifyVars方法
modifyVars 方法是是基于 less 在浏览器中的编译来实现。
所以在引入 less 文件的时候需要通过 link 方式引入,然后基于 less.js 中的方法来进行修改变量
link 方式引入主题色文件
更改主题色事件
如果发现项目运行报错如下:
那可能是没有开启 javascriptEnabled:true
在 webpack 配置里开启
less 方法仅限于用 less 的项目才能使用,查了下 sass 是没有类似 less.modifyVars 这种方法的。
那有没有通用一点的方法呢?于是就有了
css 变量方法
如果项目里用的不是 less, 那么还是用 css 的方法,通用且容易操作,使用 css 变量来进行主题色的修改,替换主题色变量,然后用 setProperty 来进行动态修改
用法就是给变量加--前缀,涉及到主题色的都改成 var(--themeColor)这种方式
用之前看下兼容性
大部分主流浏览器还是支持的,而且主要是操作起来够简便。
用法举例:
使用:
要修改主题色的话:
评论