在构建桌面应用时,原生窗口的默认样式往往无法满足精致交互的需求。Electron 为 BrowserWindow 提供了丰富的样式配置,让你可以轻松创建无边框窗口、透明窗口、置顶工具以及模态对话框,从而打破矩形窗口的桎梏,塑造出贴合产品设计的独特界面。
无边框窗口
无边框窗口去除了系统自带的标题栏和窗口边框,允许你完全用 HTML/CSS 自定义标题栏、关闭按钮和窗口拖拽区域。这是实现自定义 UI 的第一步。
创建方式是在 BrowserWindow 选项中设置 frame: false:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
width: 900,
height: 600,
frame: false, // 隐藏系统窗口边框
titleBarStyle: 'hidden', // macOS 上可隐藏标题栏但保留红绿灯按钮
// ...
})
无边框窗口需要注意几个关键的交互细节:
- 窗口拖拽:在 HTML 中,给自定义标题栏区域添加 CSS 属性
-webkit-app-region: drag,即可让用户拖动该区域来移动窗口。同时,对标题内的按钮(关闭、最小化等)设置-webkit-app-region: no-drag以保证可点击。 - 窗口控制按钮:你需要自己实现最小化、最大化/还原、关闭按钮,并调用对应的
win.minimize()、win.maximize()、win.unmaximize()、win.close()方法。 - 双击最大化:在自定义标题栏区域监听
dblclick事件,调用win.isMaximized()判断状态后切换最大化/还原。 - 系统菜单:在 Windows 上,原生标题栏右键会显示系统菜单(移动、大小等)。无边框窗口可以通过监听标题区域右键事件,手动调用
menu.popup()来实现类似效果,以保持用户习惯。
实用示例:自定义标题栏
<!-- 标题栏结构 -->
<div class="title-bar" style="-webkit-app-region: drag;">
<span>我的应用</span>
<button style="-webkit-app-region: no-drag;" onclick="window.close()">✕</button>
</div>
透明窗口
透明窗口让窗口背景完全或部分透明,常用于启动画面、桌面挂件、圆形悬浮工具或个性化弹窗。实现方法是将 transparent 设为 true,同时确保网页本身的背景也使用透明(例如 background: transparent 或 rgba)。
const win = new BrowserWindow({
transparent: true,
frame: false, // 透明窗口通常也设为无边框以获得完整效果
width: 300,
height: 300
})
在 CSS 中,你需要显式地把 body 或根元素的背景设透明:
body {
background: transparent;
margin: 0;
overflow: hidden;
}
实用注意事项:
- 透明窗口开启后,原生窗体阴影会消失,窗口可能难以与桌面区分。你可以用 CSS 添加自定义阴影或彩色描边。
- 某些平台的窗口管理器中,透明区域的鼠标事件可能会穿透到桌面。必须确保可见内容有背景或使用
pointer-events: auto来正确捕获点击。 - macOS 上,透明窗口结合无边框可以做出类似毛玻璃的效果,但需要额外处理。
置顶窗口
置顶(Always on Top)让窗口始终停留在其他窗口的上方,即使用户切换到其他应用,该窗口依然可见。这对于悬浮工具、快捷操作栏、计时器或监控面板非常有用。
可以直接在创建窗口时启用:
const win = new BrowserWindow({
alwaysOnTop: true
})
也可以在运行时动态切换:
win.setAlwaysOnTop(true) // 开启置顶
win.setAlwaysOnTop(false) // 取消置顶
// 设置置顶层级别(macOS 支持浮动窗与普通置顶)
win.setAlwaysOnTop(true, 'floating') // 窗口始终悬浮,即使在全屏空间之上
win.setAlwaysOnTop(true, 'normal') // 相对于父窗口置顶
真实场景中,你可能希望提供一个“图钉”图标让用户自行锁定窗口,点击时调用 setAlwaysOnTop(!isOnTop) 即可切换。
需要注意的是,置顶窗口过多会扰乱用户的窗口管理,因此尽量只对确实需要前台展示的工具类窗口使用该特性。
模态窗口
模态窗口会阻止用户与父窗口交互,直到该子窗口被关闭。这非常适用于设置对话框、登录弹窗或保存确认等需要用户必然响应的场景。
Electron 提供了两种创建模态窗口的方式:
- 使用
modal选项并指定parent窗口:
const parentWin = BrowserWindow.getFocusedWindow()
const modalWin = new BrowserWindow({
parent: parentWin, // 指定父窗口
modal: true, // 设为模态
width: 400,
height: 300,
frame: false, // 模态窗通常也自定义外观
resizable: false
})
modalWin.loadFile('dialog.html')
这种方法会自动处理模态行为:父窗口变灰、不可点击,子窗口始终保持在父窗口之上。在 macOS 上,模态窗口会以工作表(sheet)的形式从父窗口滑出,视觉效果更原生。
- 使用
dialog模块的简单模态对话框:
如果只是需要简单的消息提示、确认框或保存文件,可以直接使用 dialog.showMessageBox() 或 dialog.showOpenDialog()。这些对话框是系统原生的,不需要额外创建 BrowserWindow。
const { dialog } = require('electron')
dialog.showMessageBox({
type: 'warning',
buttons: ['取消', '确定'],
title: '确认删除',
message: '此操作不可恢复,是否继续?'
})
模态窗口需要谨慎使用,不要频繁打断用户操作流。通常在需要用户明确确认或输入信息时才使用。
组合使用实例
许多现代的 Electron 应用会混合运用以上样式来打造独特界面。例如,一个快捷启动器可以这样设计:
- 无边框窗口 + 透明背景,让搜索框仿佛直接贴在桌面上。
- 置顶显示,用户随时按键呼出,无需切换窗口。
- 点击选项弹出模态设置窗,设置完毕后关闭。
这些窗口样式的组合赋予了 Electron 应用媲美原生甚至超越原生的界面自由度,是前端技能转化为优秀桌面体验的核心地带。