Skip to content

换肤

CSS 变量

分别定义黑天白夜会变化的变量

css
/* 白天模式 */
:root {
  --body-bg: #fff;
  --main-bg: #fff;
  --main-color: #000;
  --btn-img: url("./dark-btn.svg");
}

/* 黑夜模式 */
:root .dark {
  --body-bg: #000;
  --main-bg: #000;
  --main-color: #fff;
  --btn-img: url("./light-btn.svg");
}

在 css 上使用

css
body {
  background-color: var(--body-bg);
}

main {
  color: var(--main-color);
}

i {
  background: var(--btn-img);
  background-size: cover;
}
html
<body>
  <main>
    test
    <i />
  </main>
</body>

通过监听 i 的点击,往 body 上切换 class,已改变 css 变量

js
document.querySelector('i').onclick = () => {
  document.body.classList.toggle('dark')
}

css 变量 -- 兼容性解决

使用 css-vars-ponyfill

shell
npm i css-vars-ponyfill --save

创建 light.js 文件定义白天模式用到的变量

js
export default {
  "--body-bg": "#fff",
  "--main-bg": "#fff",
  "--main-color": "#000",
  "--btn-img": 'url("./dark-btn.svg")'
};

创建 dark.js 文件定义黑夜模式用到的变量

js
export default {
  "--body-bg": "#000",
  "--main-bg": "#000",
  "--main-color": "#ffffff",
  "--btn-img": `url("./light-btn.svg")`
};

在 css 上正常使用

css
body {
  background-color: var(--body-bg);
}

main {
  color: var(--main-color);
}

i {
  background: var(--btn-img);
  background-size: cover;
}
html
<body>
  <main>
    test
    <i />
  </main>
</body>

引入 cssVars,并调用,每次切换主题也调用一次

js
import cssVars from "css-vars-ponyfill"
import light from "./light.js";
import dark from "./dark.js";

let isLight = true
function changeTheme() {
  cssVars({
    watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用
    variables: isLight ? light : dark, // variables 自定义属性名/值对的集合
    /** false  默认将css变量编译为浏览器识别的css样式  true 当浏览器不支持css变量的时候将css变量编译为识别的css */
    /** 开发中应该使用 true,如果为了看效果,可以设成 false */
    onlyLegacy: true,
  })
}
changeTheme() // 初始化时,需要渲染一次
document.querySelector('i').onclick = () => {
  document.body.classList.toggle('dark')
  isLight = !isLight
  changeTheme()
}

其他方案

  1. 全局变量名,但需要维护难,需要时刻注意优先级
  2. less / sass 在线编译,代码难以看懂