Skip to content

换肤

方案一:CSS 样式覆盖实现

核心原理:通过切换 css 选择器的方式实现主题样式的切换.

  1. 在组件中保留不变的样式,将需要变化的样式进行抽离
  2. 提供多种样式,给不同的主题定义一个对应的 CSS 选择器
  3. 根据不同主题设置不同的样式
css
/* 通过 .light 和 .dark 两个类选择器来区分明亮主题和暗黑主题,
并且事先准备了它们对应的样式 */

/* light 默认主题*/
body.light {
  background-color: #fff;
}

/* dark 暗黑主题 */
body.dark {
  background-color: rgb(51, 50, 50);
}

缺点:

  1. 多种主题样式都要引入,导致代码量增大
  2. 当主题样式复杂时,需要维护大量的 CSS 类和规则,可能导致 CSS 文件臃肿

方案二:多套 CSS 主题样式

核心原理: 根据用户切换操作,通过 link 标签动态加载不同的主题样式,解决所有主题打包到一个文件导致体积过大问题

js
// 关键代码

function swapStylesheet(themeurl) {
  document.getElementById("themelink").setAttribute("href", themeurl);
}

缺点:

  1. 需要预先把多套主题的样式都编译好并存储在服务器上,增加了资源占用。且如果主题数量较多,可能会影响首次加载速度
  2. 需要提前知道打包后的文件路径,否则可能导致主题样式引入错误

方案三:CSS 自定义变量

缺点:对老版本浏览器兼容性较差,需要做兼容处理。同时,CSS 变量无法在 IE 浏览器中使用

  • MDN 解释:var() CSS 函数可以插入一个自定义属性(有时也被称为“CSS 变量”)的值,用来代替非自定义属性中值的任何部分

demo 地址

css
/* default css */
:root {
  --primary-color: #3498db;
  --secondary-color: #2ecc71;
  --text-color: #333;
}

/* test2.css */
:root {
  --primary-color: #34db58;
  --secondary-color: #cc2e2e;
  --text-color: #6520dc;
}
js
// 关键函数: 通过link标签外链切换主题样式
function changeTheme() {
      let link = document.getElementById("themelink");

      link.setAttribute(
        "href",
        link.href.includes("default.css") ? "test2.css" : "default.css"
      );
    }
  </script

Released under the MIT License.