关于样式变更有很多种方案,然而,js去直接控制元素样式变更,不适合主题色变更,可先参考naive UI

native UI 库主题色参考

  1. import { cloneDeep, kebabCase } from 'lodash-es';
  2. /** 添加css vars至html */
  3. export function addThemeCssVarsToHtml(themeVars: ThemeVars) {
  4. const keys = Object.keys(themeVars) as ThemeVarsKeys[];
  5. const style: string[] = [];
  6. keys.forEach(key => {
  7. style.push(`--${kebabCase(key)}: ${themeVars[key]}`); /
  8. });
  9. const styleStr = style.join(';');
  10. document.documentElement.style.cssText += styleStr;
  11. }

在源码中,我们可以看到申明的n-naive的样式变量

  1. vars:
  2. --n-bezier
  3. --n-font-size
  4. --n-padding
  5. --n-border-radius
  6. --n-option-height
  7. --n-option-prefix-width
  8. --n-option-icon-prefix-width
  9. --n-option-suffix-width
  10. --n-option-icon-suffix-width
  11. --n-color
  12. --n-option-color-hover
  13. --n-option-color-active
  14. --n-divider-color
  15. --n-option-text-color
  16. --n-option-text-color-hover
  17. --n-option-text-color-active
  18. --n-option-text-color-child-active
  19. --n-prefix-color
  20. --n-suffix-color
  21. --n-option-icon-size
  22. --n-option-opacity-disabled

vars变量

:root 这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 元素,除了优先级更高之外,与 html 选择器相同

https://developer.mozilla.org/zh-CN/docs/Web/CSS/:root

CSS 变量-浏览器兼容性

自定义属性 (—*):CSS 变量

带有前缀—的属性名,比如—example—name,表示的是带有值的自定义属性,其可以通过 var 函数在全文档范围内复用的。
CSS 自定义属性是可以级联的:每一个自定义属性可以多次出现,并且变量的值将会借助级联算法和自定义属性值运算出来。
image.png

结合root伪类 + vars做到主题色变更

https://codepen.io/web-kubor/pen/zYWbKyB
image.png

Scss预编译

  1. $primary: #409eff;
  2. :root {
  3. --fill-color-primary: $primary;
  4. }
  5. // 编译后 css,变量没有成功应用
  6. :root {
  7. --fill-color-primary: $primary;
  8. }

Css变量语法

https://sass-lang.com/documentation/breaking-changes/css-vars 为了提供与普通CSS的最大兼容性,较新版本的Sass要求在插值中写入自定义属性值中的SassScript表达式

  1. $primary: #409eff;
  2. :root {
  3. --fill-color-primary: #{$primary};
  4. }
  5. // 编译后 css
  6. :root {
  7. --fill-color-primary: #409eff;
  8. }

主题色变更解决方案

  1. .light_theme {
  2. --defipay-text-primary: #333333;
  3. }
  4. .dark_theme {
  5. --defipay-text-primary: #ffffff;
  6. }
  7. body {
  8. color: var(--defipay-text-primary);
  9. }
  1. function swtichTheme() {
  2. if (document.body.classList.contains("dark_theme")) {
  3. document.body.classList.remove("dark_theme");
  4. document.body.classList.add("light_theme");
  5. } else {
  6. document.body.classList.remove("light_theme");
  7. document.body.classList.add("dark_theme");
  8. }
  9. }
  10. function initTheme() {
  11. document.body.classList.add("light_theme");
  12. }