前端 “一键换肤“ 的 N 种方案
方式一:
1 把两种css样式写在一个文件里,通过切换body元素的类名切换不同主题。
缺点:
多种主题样式都要引入,导致代码量增大
样式不易管理
查找样式复杂
开发效率低
拓展性差
方式二:
2 实现多套css主题样式文件如: light.css; dark.css; 根据用户切换操作,通过 link 标签动态加载不同的主题样式。
export default function setTheme(theme = 'ligth') {
let link = document.querySelector('#theme-link')
let href = "/theme/" + theme + ".css"
if (!link) {
let head = document.querySelector('head')
link = document.createElement('link')
link.id = '#theme-link'
link.rel = "stylesheet"
link.href = href
head.appendChild(link)
} else {
link.href = href
}
}
缺点:
需要重复 CV 多份样式文件进行单独修改
没有单独提取出可变的样式部分
需要提前知道打包后的文件路径,否则可能导致主题样式引入错误
方式三:
3 利用css变量实现,但是css变量的var有兼容性,属于新属性。
通过 body.style.setProperty(key, value) 动态修改 body 上的 CSS 变量,使得页面上的其他部分可以应用最新的 CSS 变量对应的样式.
document.body.style.setProperty('--background-color','yellow')
//undefined
document.body.style.setProperty('--theme-color','yellow')
//undefined
style="-webkit-tap-highlight-color: transparent; --background-color:yellow; --theme-color:yellow;"
//document.body.style.setProperty('--key','value') 设置key的时候要带上--否则加不上,只有color,background-color等正确的key才能加上。
//定义全局变量
document.body.style.setProperty('--theme-bg','red')
//用法:引用之前定义的全局变量
#app {
background-color: var(--theme-bg);
}
.father2[data-v-058daaa6] {
display: flex;
justify-content: center;
align-items: center;
height: 120px;
background-color: var(--theme-bg);
}
知识说明:
var()
var()函数可以代替元素中任何属性中的值的任何部分。var()函数不能作为属性名、选择器或者其他除了属性值之外的值。(这样做通常会产生无效的语法或者一个没有关联到变量的值。)
:root
:root是一个伪类,表示文档根元素html,非IE及ie8及以上浏览器都支持,在:root中声明相当于全局属性,只要当前页面引用了:root segment所在文件,都可以使用var()来引用
:root {
--main-bg-color: pink;
}
body {
background-color: var(--main-bg-color);
}
calc()
可以用于计算css值。