Dark Mode
概览
自动更新原生界面
"本地界面"包括文件选择器、窗口边框、对话框、上下文 菜单等 - 任何UI来自操作系统而非应用的界面。 默认行为是从操作系统选择自动主题。
自动更新您自己的界面
如果您的应用有自己的黑暗模式,您应该在与系统黑暗模式设置同步时切换。 你可以通过 prefers-color-scheme CSS 媒体查询来实现此功能.
手动更新您自己的界面
If you want to manually switch between light/dark modes, you can do this by setting the desired mode in the themeSource property of the nativeTheme
module. This property's value will be propagated to your Renderer process. Any CSS rules related to prefers-color-scheme
will be updated accordingly.
macOS 设置
在 macOS 10.14 Mojave 中, Apple 为所有 macOS 电脑引入了一个全新的 系统级暗色模式。 如果您的 Electron 应用具有深色模式,您可以 使用"本机 api" 应用 应用
。
In macOS 10.15 Catalina, Apple introduced a new "automatic" dark mode option for all macOS computers. 为了让API isDarkMode
和 Tray
在这个模式中正常工作,你需要在 Info.plist
文件里把 NSRequiresAquaSystemAppearance
设置为 false
,或者使用 >=7.0.0
的Electron。 Both Electron Packager and Electron Forge have a darwinDarkModeSupport
option to automate the Info.plist
changes during app build time.
If you wish to opt-out while using Electron > 8.0.0, you must set the NSRequiresAquaSystemAppearance
key in the Info.plist
file to true
. Please note that Electron 8.0.0 and above will not let you opt-out of this theming, due to the use of the macOS 10.14 SDK.
示例
此示例演示了Electron 应用程序从nativeTheme
中获取主题颜色。 此外,它还使用 IPC 通道提供主题切换和重置控制。
- main.js
- preload.js
- index.html
- renderer.js
- styles.css
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron/main')
const path = require('node:path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('darkMode', {
toggle: () => ipcRenderer.invoke('dark-mode:toggle'),
system: () => ipcRenderer.invoke('dark-mode:system')
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link rel="stylesheet" type="text/css" href="./styles.css">
</head>
<body>
<h1>Hello World!</h1>
<p>Current theme source: <strong id="theme-source">System</strong></p>
<button id="toggle-dark-mode">Toggle Dark Mode</button>
<button id="reset-to-system">Reset to System Theme</button>
<script src="renderer.js"></script>
</body>
</html>
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
const isDarkMode = await window.darkMode.toggle()
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
})
document.getElementById('reset-to-system').addEventListener('click', async () => {
await window.darkMode.system()
document.getElementById('theme-source').innerHTML = 'System'
})
:root {
color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}
@media (prefers-color-scheme: light) {
body { background: #ddd; color: black; }
}