跳到主要内容

主题一键切换

Media Query

初始NextJS项目后运行项目发现网页当前主题是黑暗模式,正和我电脑的主题匹配,打开白天模式后网页自动关闭暗黑模式。然后我在项目中发现了这几行代码:

@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
body {
color: white;
background: black;
}
}

查了下 MND ,大致意思是使用媒体查询识别当前系统的主题。是否是暗黑模式。详见MDN

如果是 dark 模式则背景颜色调为黑色、字体调为白色。

CSS Variable

这里使用 CSS 变量来实现一键主题切换。

给跟 html 元素添加一个自定义属性

注意,所有的 DOM 元素可以添加自定义属性的,自定义属性以 data- 开头,比如 data-theme, data-props。我们这里添加自定义属性 data-themehtml 元素上。

const html = document.getElementsByTagName('html')[0];

html.setAttribute('data-theme', 'dark');

然后定义相关 CSS 变量。变量根据不同的属性定义不同的值,这里使用 CSS 属性选择器。

// 当 html 元素的 data-theme 属性值为 dark 时的变量值
html[data-theme="dark"] {
--primary-color: #ffffff; // 主要的字体颜色
--primary-background-color: rgba(14, 14, 14, 1); // 主要的背景色
--secondary-background-color:#1D1D1D;
--footer-background-color: rgba(36, 36, 36, 1); // footer组件的背景色
--navbar-background-color: rgba(0, 0, 0, 0.5); // navbar组件的背景色
--secondary-color: rgba(255, 255, 255, 0.5); // 次一级,色值没那么显眼的字体颜色
--link-color: #34a8eb; // 链接 hover 上去的颜色
}

// 当 html 元素的 data-theme 属性值为 light 时的变量值
html[data-theme="light"] {
--primary-color: #333333;
--primary-background-color: rgba(255, 255, 255, 1);
--secondary-background-color: rgba(255, 255, 255, 1);
--footer-background-color: #f4f5f5;
--navbar-background-color: rgba(255, 255, 255, 0.5);
--secondary-color: #666666;
--link-color: #0070f3;
}

然后在相关使用颜色的 css 属性不直接给一定固定的颜色,而是给一个变量。

.header{
background-color: var(--primary-background-color);
color: var(--primary-color);
}

所以想改变主题直接改变 html 元素的 data-theme 属性的值就好。

const setTheme = (theme) => {
// ...
document.getElementsByTagName('html')[0].dataset.theme = theme; // 自定义属性可在元素的 dataset 对象里获取
}
网站备案:蜀ICP备2023001425号👏 Powered By Docusaurus, Semi Design