换肤功能(scss、css变量)
博客地址:
产品 SaaS 化,通常需要有换肤功能
这⾥简单记录⼀下主题⾊及其衍⽣⾊(⾼亮、浅⾊)的更换功能
scss 全局定义
每个页⾯都有颜⾊,那么应该把颜⾊值定义在 global.scss ⽂件中,通过变量定义,⽐如
$color-primary: #4762FE;
$color-primary-dark: #3245D9;
$color-primary-light: #C2D1FF;
$color-primary-lightest: #EBF0FF;
$color-primary-transparency: rgba(71,98,254,0.1);
每个页⾯的样式表引⼊此⽂件
@import './global.scss';
// 使⽤例⼦
.demo {
color: $color-primary
}
这样,只要更改 scss 中全局变量的颜⾊值,就可以同步更改项⽬的颜⾊值
css 变量定义
思考如何注⼊颜⾊值?
这⾥就⽤到 css 的变量函数了:var()
之前有谈到使⽤ css 的变量以及赋值⽅法:
var() 函数⽤于插⼊⾃定义的属性值
两个参数:property,value
property:必填,⾃定义属性的名称,必需以 -- 开头
value:可选,备⽤值,在属性不存在的时候使⽤
⽐如
body {
--tempColor: #fff;
}
.temp {
color: var(--tempColor)
}
设置其属性:DOM.style.setProperty(name, value)
这⾥就很清楚了,scss 中全局变量引⼊的是 var() 函数的变量值
获取衍⽣⾊
主题⾊是只有⼀个,需要通过主题⾊来获取其衍⽣颜⾊(⾼亮、浅⾊等)
scss 中提供⼀个⽅法:mix()
Mix 函数是将两种颜⾊根据⼀定的⽐例混合在⼀起,⽣成另⼀种颜⾊。其使⽤语法如下:
mix($color-1,$color-2,$weight);
$color-1 和 $color-2 指的是你需要合并的颜⾊,颜⾊可以是任何表达式,也可以是颜⾊变量
$weight 为合并的⽐例(选择权重),默认值为 50%,其取值范围是 0~1 之间。它是每个 RGB 的百分⽐来衡量,当然透明度也会有⼀定的权重
如果指定的⽐例是 25%,意味着第⼀个颜⾊所占⽐例为 25%,第⼆个颜⾊所占⽐例为75%
此外,scss 还有⼀个 HSL 函数,也是设置颜⾊值的⽅法,这⾥就不过多探究了
坑来了
当我把 var() 函数获取的颜⾊值放进 mix 函数中,居然报错:
SassError: argument $color-2 of mix($color-1, $color-2, $weight: 50%) must be a color
mix 函数⽆法使⽤带有 var() 函数变量的参数,HSL 函数也是;但普通变量是可以的
最终只能使⽤ js 函数通过主题⾊来获取衍⽣颜⾊
这⾥提供⼏个⽅法:
// str: ⼗六进制颜⾊值,n:透明度
export function colorRgba(str, n) {
// ⼗六进制颜⾊值的正则表达式
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
let sColor = LowerCase()
n = n || 1
// ⼗六进制颜⾊转换为RGB格式
if (sColor && st(sColor)) {
let sColorChange = getRgbNum(sColor)
return 'rgba(' + sColorChange.join(',') + ',' + n + ')'
css变量} else {
return sColor
}
}
// 获取 rgb 颜⾊值
function getRgbNum(sColor) {
if (sColor.length === 4) {
let sColorNew = '#'
for (let i = 1; i < 4; i += 1) {
// 补全颜⾊值例如:#eee,#fff等
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
}
sColor = sColorNew
}
// 处理六位颜⾊值
let sColorChange = []
for (let i = 1; i < 7; i += 2) {
/
/ 核⼼代码,通过parseInt将⼗六进制转为⼗进制,parseInt只有⼀个参数时是默认转为⼗进制的,第⼆个参数则是指定转为对应进制
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
}
return sColorChange
}
// 加深或减弱颜⾊值
export function lightDarkenColor(color, num) {
let colorArr = getRgbNum(color)
let sColorChange = []
for (let i = 0; i < colorArr.length; i++) {
let val = colorArr[i] + num
if (val < 0) {
val = 0
}
if (val > 255) {
val = 255
}
sColorChange.push(val)
}
return 'rgba(' + sColorChange.join(',') + ',1)'
}
最后只需要在路由全局前置守卫中计算颜⾊值,并赋值到 css 变量上,在 scss 全局变量中⽤ var() 函数引⼊ css 变量(各种颜⾊值)
换肤流程
通过接⼝获取主题⾊ --> js 计算衍⽣⾊值 --> 赋值到 css 变量 --> scss 全局变量⽤ var() 函数引⼊ css 变量 --> 页⾯样式引⽤ scss 全局颜⾊值使⽤例⼦
global.scss
$color-primary: var(--primaryColor, #4762FE);
$color-primary-dark: var(--primaryDarkColor, #3245D9);
$color-primary-light: var(--primaryLightColor, #C2D1FF);
$color-primary-lightest: var(--primaryLightestColor, #EBF0FF);
$color-primary-transparency: var(--primaryTransparencyColor, rgba(71,98,254,0.1));
路由守卫:
router.beforeEach((to, from, next) => {
const primaryColor = getConfigStyle() // 从接⼝获取的主题⾊ const colorObj = {
primaryColor: primaryColor,
primaryDarkColor: lightDarkenColor(primaryColor, -20),
primaryLightColor: colorRgba(primaryColor, 0.3),
primaryLightestColor: colorRgba(primaryColor, 0.12),
primaryTransparencyColor: colorRgba(primaryColor, 0.1) }
// 逐个设置 css 变量到 body 上
document.body.style.setProperty(`--${ele[0]}`, ele[1])
})
next()
})
博客地址:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论