在网站迭代升级时,经常会收到更换网站配色的需求,或者提供入口,让用户自己选择页面的配色主题。
该怎么去实现这种需求呢?
我们先看看antd里面,是用的什么方式来实现的:
antd 的样式使用了 Less 作为开发语言,并定义了一系列全局/组件的样式变量,你可以根据需求进行相应调整。
...
原理上是使用 less 提供的 modifyVars 的方式进行覆盖变量,可以在本地运行 例子 查看定制效果。下面将针对不同的场景提供一些常用的定制方式。
有两种方式实现定制主题:
- 通过webpack
以 webpack@4 为例进行说明,通过修改webpack.config.js
中的 less-loader ,对 options 属性进行相应配置。
// webpack.config.js
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
+ options: {
+ lessOptions: { // 如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
+ modifyVars: {
+ 'primary-color': '#1DA57A',
+ 'link-color': '#1DA57A',
+ 'border-radius-base': '2px',
+ },
+ javascriptEnabled: true,
+ },
+ },
}],
// ...other rules
}],
// ...other config
}
这种方式能直接在编译代码时,直接替换对应的颜色值,但是不支持动态更换主题色。
- 使用umi
在项目根目录的.umirc.ts
或 config/config.ts 文件中 theme 字段进行主题配置。theme
可以配置为一个对象或文件路径。
"theme": {
"primary-color": "#1DA57A",
},
这种方式依赖umi
,而且和webpack的一样,不支持动态修改颜色值。
- 配置 less变量文件
建立一个单独的 less 变量文件,引入这个文件覆盖 antd.less 里的变量。
@import '~antd/lib/style/themes/default.less';
@import '~antd/dist/antd.less'; // 引入官方提供的 less 样式入口文件
@import 'your-theme-file.less'; // 用于覆盖上面定义的变量
这种方式比较灵活,没有额外的依赖。如果需要添加动态更换主题色,可以考虑在切换主题色选项后,给body上添加不同的className,实现不同主题色的展示。甚至可以通过动态加载css文件的方式进行样式的覆盖,不过要注意样式的优先级:
/**
* 动态加载CSS
* @param {string} url 样式地址
*/
function dynamicLoadCss(url) {
const head = document.getElementsByTagName('head')[0]
const link = document.createElement('link')
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = url
head.appendChild(link)
}
css variables
除了上述的一些方法,还可以尝试使用css variables
。css variables
的基本概念和语法可以通过 Using CSS custom properties (variables) 进行了解。
:root{
--primary-color: #C5C5C5!important;
--secondary-color: #6C7478!important;
--tertiary-color: #FFFFFF!important;
--success-color: #80b855!important;
--warning-color: #eaca44!important;
--error-color: #ef4d4d!important;
}
/* Theming */
header{
background-color: var(--primary-color);
}
div{
color: var(--tetriary-colory);
}
修改主题时,直接操作颜色变量。
const bodyStyles = document.body.style;
bodyStyles.setProperty('--primary-color', 'red');
bodyStyles.setProperty('--tertiary-color', 'yellow');
但该方案有一些兼容性的问题,使用前也需要进行评估:caniuse
网友评论