关于样式变更有很多种方案,然而,js去直接控制元素样式变更,不适合主题色变更,可先参考naive UI
native UI 库主题色参考
import { cloneDeep, kebabCase } from 'lodash-es';
/** 添加css vars至html */
export function addThemeCssVarsToHtml(themeVars: ThemeVars) {
const keys = Object.keys(themeVars) as ThemeVarsKeys[];
const style: string[] = [];
keys.forEach(key => {
style.push(`--${kebabCase(key)}: ${themeVars[key]}`); /
});
const styleStr = style.join(';');
document.documentElement.style.cssText += styleStr;
}
在源码中,我们可以看到申明的n-naive的样式变量
vars:
--n-bezier
--n-font-size
--n-padding
--n-border-radius
--n-option-height
--n-option-prefix-width
--n-option-icon-prefix-width
--n-option-suffix-width
--n-option-icon-suffix-width
--n-color
--n-option-color-hover
--n-option-color-active
--n-divider-color
--n-option-text-color
--n-option-text-color-hover
--n-option-text-color-active
--n-option-text-color-child-active
--n-prefix-color
--n-suffix-color
--n-option-icon-size
--n-option-opacity-disabled
vars变量
:root 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 元素,除了优先级更高之外,与 html 选择器相同
CSS 变量-浏览器兼容性
自定义属性 (—*):CSS 变量
带有前缀—的属性名,比如—example—name,表示的是带有值的自定义属性,其可以通过 var 函数在全文档范围内复用的。
CSS 自定义属性是可以级联的:每一个自定义属性可以多次出现,并且变量的值将会借助级联算法和自定义属性值运算出来。
结合root伪类 + vars做到主题色变更
https://codepen.io/web-kubor/pen/zYWbKyB
Scss预编译
$primary: #409eff;
:root {
--fill-color-primary: $primary;
}
// 编译后 css,变量没有成功应用 ↓
:root {
--fill-color-primary: $primary;
}
Css变量语法
https://sass-lang.com/documentation/breaking-changes/css-vars 为了提供与普通CSS的最大兼容性,较新版本的Sass要求在插值中写入自定义属性值中的SassScript表达式
$primary: #409eff;
:root {
--fill-color-primary: #{$primary};
}
// 编译后 css
:root {
--fill-color-primary: #409eff;
}
主题色变更解决方案
.light_theme {
--defipay-text-primary: #333333;
}
.dark_theme {
--defipay-text-primary: #ffffff;
}
body {
color: var(--defipay-text-primary);
}
function swtichTheme() {
if (document.body.classList.contains("dark_theme")) {
document.body.classList.remove("dark_theme");
document.body.classList.add("light_theme");
} else {
document.body.classList.remove("light_theme");
document.body.classList.add("dark_theme");
}
}
function initTheme() {
document.body.classList.add("light_theme");
}