赞
踩
网上很多方法都采用scss,现在用原生css实现一种简单版
mode.vue(随便定义名称):
// 在data里面定义mode为false
/*
* 模式切换
* */
fnChangeMode(){
this.mode = !this.mode;
if (this.mode == true) {
window.document.documentElement.setAttribute('data-theme', 'dark')
} else {
window.document.documentElement.setAttribute('data-theme', 'light')
}
}
/** 注意这里的css样式必须使用全局,不能加scoped标签!!! **/ <style> :root[data-theme=dark] { /* 模式切换变量,默认light模式 */ --current-background-color: var(--dark-background-color); --current-primary-color: var(--dark-primary-color); /* 深色主题 */ --dark-primary-color: #fff; --dark-background-color: #282c34; } :root[data-theme=light] { /* 模式切换变量,默认light模式 */ --current-background-color: var(--light-background-color); --current-primary-color: var(--light-primary-color); /* 浅色主题 */ --light-primary-color: #666; --light-background-color: #fff; } .header-wrap { height: 60px; background-color: var(--current-background-color); display: flex; justify-content: space-between; align-items: center; box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); } .mode{ margin-right: 20px; cursor: pointer; color:var(--current-primary-color)!important; } </style>
app.vue
#app {
background: var(--fill-1);
}
utils/theme.js
import { lightTheme, darkTheme } from '../less/variable';
import cssVars from 'css-vars-ponyfill';
export const initTheme = theme => {
document.documentElement.setAttribute('data-theme', theme);
cssVars({
watch: true, // 当添加,删除或修改其<link>或<style>元素的禁用或href属性时,ponyfill将自行调用
variables: theme == 'dark' ? darkTheme : lightTheme, // variables 自定义属性名/值对的集合
onlyLegacy: false, // false 默认将css变量编译为浏览器识别的css样式 true 当浏览器不支持css变量的时候将css变量编译为识别的css
});
};
variable.js
//浅色
export const lightTheme = {
'--fill-1': '#fff',
'--text': '#3c3c3c',
'--slide-arrow': '#000000',
};
// 深色
export const darkTheme = {
'--fill-1': '#222',
'--text': '#fff',
'--slide-arrow': '#f2f2f2',
'--text-1': 'rgba(255, 255, 255, 0.3)',
'--text-2': '#ffcd32',
};
header.vue(随便定义,作用用于切换样式)
import { initTheme } from '@/utils/theme'; export default { name: 'Header', data() { return { theme: 'dark', }; }, methods: { changeTheme() { this.theme == 'light' ? (this.theme = 'dark') : (this.theme = 'light'); initTheme(this.theme); }, }, created() { initTheme(this.theme); }, };
html {
filter: invert(1) hue-rotate(180deg);
}
本次的暗黑模式使用到两个滤镜函数:invert()、hue-rotate()。
invert():反相,反向输出图像着色,值为0%则无变化,值为0~100%则是线性乘子效果,值为100%则完全反转
hue-rotate():色相旋转,减弱图像着色,处理非黑白的颜色,值为0deg则无变化,值为0~360deg则逐渐减弱,值超过360deg则相当绕N圈再计算剩余的值
invert()简单理解就是黑变白,白变黑,黑白颠倒。hue-rotate()简单理解就是冲淡颜色。为了确保主题色调不会改变,将色相旋转声明为180deg比较合理。
按照设计原则来说,换肤只针对组件,像一些媒体类型的元素,例如背景、图片、视频等,都是不能直接处理的,需保持其原样。既然暗黑模式是使用了滤镜的反相和色相旋转实现,那么对这些媒体元素再次使用滤镜的反相和色相旋转就能复原了。
img,
video {
filter: invert(1) hue-rotate(180deg);
}
<body>
<input class="ios-switch" type="checkbox">
<div class="main">网站主体</div>
</body>
.ios-switch { ... &:checked { ... & + .main { filter: invert(1) hue-rotate(180deg); img, video, .exclude { filter: invert(1) hue-rotate(180deg); } } } } .main { background-color: #fff; transition: all 300ms; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。