在前端开发中,修改主题色方案通常可以通过以下几种方式实现:
1. CSS变量(CSS Custom Properties):
使用CSS的变量功能,由 var()函数来获取值(比如: color: var(--main-color);
),结合使用修改html或body上属性,在全局或局部范围内使用这些变量,通过修改变量的值来改变主题颜色。
案例:
Taro官网动态修改data-theme属性值
MDN官网 动态修改html上class dark/light
应用:
CSS变量(CSS Custom Properties):
动态更改,定义亮色/深色调css变量,颜色或图片都可以使用这种方式更改:
css
/* 亮色调默认颜色 */
.root-light {
--primary-color: red;
}
/* 深色调默认颜色 */
.root-dark {
--primary-color: blue;
}
button {
background-color: var(--primary-color);
}
在切换主题色方法中动态更新,在html中通过js修改深色调/亮色调class,应用到的颜色变量的元素会自动更新对应的颜色:
js
const theme = 'dark';
const body = document.querySelector("body");
body.classList.add(`root-${theme}`);
优缺点:
-
优点:
- 灵活性高,可以在整个应用程序中定义和使用变量,可以动态修改主题色,实现即时切换效果。
- 适用于单个应用程序或网站的主题修改,不需要额外的工具或依赖。
-
缺点:
- 兼容性受限,低版本的浏览器可能不支持CSS变量,但现在项目一般只会要求主流浏览器了吧。
- 需要手动在代码中添加对CSS变量的支持,可能增加一些开发成本。
2. 预处理器(Preprocessor):
使用CSS预处理器如Sass、Less或Stylus等,可以定义变量来表示主题颜色,然后在样式表中使用这些变量来设置具体的颜色。通过修改变量的值,可以轻松地修改整个应用程序的主题色。
案例:
如element ui 、anted design 都是采取预处理器方式动态修改主题色。
应用:
预处理器(Preprocessor)
css
/* 定义主题颜色变量 */
$primary-color: #ff0000;
/* 使用主题颜色变量 */
button {
background-color: $primary-color;
}
在上面的示例中,我们使用 Sass 预处理器来定义一个名为 $primary-color
的变量,并在button
元素的样式规则中使用该变量来设置背景颜色。如果要更改主题颜色,只需修改变量的值即可。
优缺点:
-
优点:
- 提供了更强大的功能,例如变量、混合器等,可以更便捷地定义和修改主题色。
- 可以根据需求轻松切换不同的主题样式文件。
-
缺点:
- 需要额外学习和配置样式预处理器,增加了一些开发复杂性。
- 需要编译预处理器的源代码,可能增加了一些构建步骤和性能开销。
3. 扩展-根据主题色切换图片
以上两种方案都是可以通过定义变量方式指定不同主题色下的图片。另外,我们也可以在主题色切换时保存色值,提高js计算在哪个色区范围内,动态更改内联图片路径。
以下方法判断一个颜色是否属于红色系列的函数。它接受一个十六进制颜色值作为参数。函数颜色值转换为 RGB 值,并使用 rgbToHsl 辅助函数将 RGB 值转换为 HSL 值。最后,判断 HSL 值的色调是否在红色系列范围内(0°-30°和330°-360°),如果是,则返回 true,否则返回 false。
js
function isRedColorSeries(hexColor) {
// 去除可能的 # 前缀
if (hexColor.startsWith('#')) {
hexColor = hexColor.substring(1);
}
// 转换为 RGB 值
let red = parseInt(hexColor.substring(0, 2), 16);
let green = parseInt(hexColor.substring(2, 4), 16);
let blue = parseInt(hexColor.substring(4), 16);
// 转换为 HSL 值
const hsl = rgbToHsl(red, green, blue);
// 判断色调是否在红色系列范围内
return (hsl.hue >= 0 && hsl.hue <= 30) || (hsl.hue >= 330 && hsl.hue <= 360);
}
// RGB 值转换为 HSL 值的辅助函数
function rgbToHsl(red, green, blue) {
red /= 255;
green /= 255;
blue /= 255;
const max = Math.max(red, green, blue);
const min = Math.min(red, green, blue);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case red:
h = (green - blue) / d + (green < blue ? 6 : 0);
break;
case green:
h = (blue - red) / d + 2;
break;
case blue:
h = (red - green) / d + 4;
break;
}
h /= 6;
}
return {
hue: Math.round(h * 360),
saturation: Math.round(s * 100),
lightness: Math.round(l * 100)
};
}
export default isRedColorSeries;
例:如果是红色系主题色,引入红色系图片,否则为蓝色系图片。
js
<template>
<div>
<img
:src="require(`@/assets/steps/${isRed ? 'red' : 'blue'}-03.png`)"
/>
</div>
</template>
<script>
import isRedColorSeries from "@/utils/isRedColorSeries";
export default {
data() {
return {
isRed: isRedColorSeries(),
};
},
};
</script>