首页
/ Electron 无边框与透明窗口样式指南:从 frame:false 到真正的异形窗口

Electron 无边框与透明窗口样式指南:从 frame:false 到真正的异形窗口

2026-09-06 19:08:33作者:农烁颖Land

本文是 custom-window-styles.md 的深度展开,系统讲解在 Electron 中打造"无系统装饰"与"真正透明"两类自定义窗口的核心原理与完整可运行示例。读完你将掌握 frametransparenthasShadowroundedCorners 等关键构造参数的真实语义、平台差异与各项硬性限制,并能在自己的 BrowserWindow / BaseWindow 应用中直接复用文中的示例工程。

窗口样式定制的入口:BrowserWindow 与 BaseWindow

在进入具体实现之前,需要先理解 Electron 窗口模型的整体背景。Electron 的 BrowserWindow 模块是应用窗口的基础,它派生自 BaseWindow 模块,二者都可以创建和管理窗口,主要区别在于:BrowserWindow 内置一个占满窗口的完整 Web 视图,而 BaseWindow 支持组合多个 View。在本文的示例中,二者可以互换使用,相关说明见 window-customization.mdbrowser-window.md

本文涉及的构造参数(frametransparenthasShadow 等)都属于 BaseWindowConstructorOptions,其完整定义位于 base-window-options.md。下面每一个参数默认值、平台行为均以该文档与仓库中的可运行 fiddle 为准。

仓库中针对本主题提供了一组开箱即用的完整示例,位于 docs/fiddles/features/window-customization/custom-window-styles/,下文的无边框与透明窗口代码即来自其中,可直接作为最小复现工程使用。

无边框窗口(Frameless Windows)

Electron 无边框窗口示例(加载 example.com 内容,无任何系统窗口边框与标题栏)

什么是无边框窗口

无边框窗口会移除操作系统附加的全部 chrome(chrome 指代浏览器/桌面环境提供的窗口边框、标题栏、关闭/最小化/最大化按钮等 UI 装饰,即 Glossary 意义上的"界面壳层"),让应用内容以更纯净的形态呈现。这在需要完全自定义 UI、沉浸式展示或自绘标题栏时非常常见。

如何创建:frame: false

创建无边框窗口的方法很简单:在 BrowserWindow(或 BaseWindow)构造函数中将 frame 参数设为 false。该参数在 base-window-options.md 中的定义为:frame(boolean,可选)——设为 false 以创建无边框窗口,默认值为 true

仓库中对应的最小示例位于 frameless-windows/main.js,完整内容如下:

const { app, BrowserWindow } = require('electron')

function createWindow () {
  const win = new BrowserWindow({
    width: 300,
    height: 200,
    frame: false
  })
  win.loadURL('https://example.com')
}

app.whenReady().then(() => {
  createWindow()
})

这个示例创建了一个 300×200、无任何窗口装饰的窗口并加载网页内容,是整个 Electron 中最简短的无边框窗口"hello world"。

无边框不等于"零装饰":相关参数组合

仅设置 frame: false 只是去掉了系统标题栏与按钮,窗口仍可能带有阴影、圆角等外观,并可通过系统默认行为进行缩放。根据 base-window-options.md 中相关构造参数的定义,实际项目通常还需要配合以下选项精确控制无边框窗口的外观:

  • hasShadow(boolean,默认 true):决定窗口是否带阴影。若不希望系统绘制阴影,可设为 false
  • roundedCorners(boolean,默认 true):决定无边框窗口是否带圆角。在 Windows 11 Build 22000 之前的版本上此参数无效(无边框窗口不会有圆角);在 Linux 上仅当桌面环境支持客户端侧装饰(client-side decorations)时才会绘制圆角。
  • titleBarStyle:在无边框窗口的基础上,还可以用 hiddenhiddenInset(macOS)、customButtonsOnHover(macOS)等取值控制标题栏与 macOS "红绿灯"按钮的呈现方式,构建"标题栏隐藏但保留系统按钮"的效果。
  • titleBarOverlay:与无边框窗口搭配,可启用 Window Controls Overlay 相关的 JavaScript API 与 CSS 环境变量,用于实现自定义标题栏。
  • trafficLightPosition(macOS):为无边框窗口自定义"红绿灯"按钮的位置。
  • thickFrame(Windows,默认 true):为 Windows 上的无边框窗口启用 WS_THICKFRAME 样式(即保留标准窗口框)。若设为 false,会移除窗口阴影和窗口动画,并禁用通过拖拽窗口边缘来调整大小的能力。

由于 frame: false 后不再有系统拖拽区域,让内容区可被鼠标拖动通常是刚需。仓库中的 custom-window-interactions.md 以及 custom-window-styles 下的透明窗口示例 都展示了通过 CSS 的 app-region: drag 区域声明来拖动窗口的做法,实现细节可参考 custom-window-styles.md 同目录的 custom-title-bar.md 主题。

Wayland(Linux)下的特殊行为

文档特别指出:在 Linux 的 Wayland 协议下,无边框窗口默认会带有 GTK 投影阴影与扩展的缩放边界(extended resize boundaries)。若希望得到一个"完全不绘制任何装饰"的彻底无边框窗口,需要在构造参数中额外显式设置 hasShadow: falsehasShadow 默认值虽为 true,但 Wayland 下无边框窗口的阴影来自 GTK 装饰层,必须显式关闭)。

透明窗口(Transparent Windows)

Electron 透明窗口示例:白色圆形文字"Hello World"悬浮于窗口背景之上

同一透明窗口在 macOS Mission Control 中的表现

如何创建:transparent: true

要创建完全透明的窗口,需要在构造函数中把 transparent 参数设为 true。该参数在 base-window-options.md 中的定义要点包括:

  • 默认值为 false
  • 在 Windows 上,除非窗口同时是无边框的,否则透明不生效
  • 当向 BaseWindow 添加 View 时,还需要在该 View 上调用 view.setBackgroundColor 并传入透明背景色,才能使该 View 的背景同样透明。

文档中配套的 fiddle(transparent-windows)利用"透明窗口 + CSS 样式"制造出一个圆形窗口的视觉假象,即:窗口本身透明,页面内容中只绘制一个白色圆形区域。工程文件位于 transparent-windows/ 目录下,主进程代码 main.js 如下:

const { app, BrowserWindow } = require('electron')

function createWindow () {
  const win = new BrowserWindow({
    width: 100,
    height: 100,
    resizable: false,
    frame: false,
    transparent: true
  })
  win.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()
})

注意此处与无边框示例的差异:窗口同时设置了 frame: falsetransparent: true,且显式把 resizable 设为 false。结合下面文档列出的限制可以看出,"不可缩放"是透明窗口的稳定前提(见后文 Limitations 部分)。

页面文件 index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
    <link href="./styles.css" rel="stylesheet">
    <title>Transparent Hello World</title>
  </head>
  <body>
    <div class="white-circle">
        <div>Hello World!</div>
    </div>
  </body>
</html>

样式文件 styles.css 是整个"圆形窗口"效果的关键:

body {
    margin: 0;
    padding: 0;
    background-color: rgba(0, 0, 0, 0); /* Transparent background */
}
.white-circle {
    width: 100px;
    height: 100px;
    background-color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    app-region: drag;
    user-select: none;
}

实现要点拆解:

  • body 背景被设为 rgba(0, 0, 0, 0)(完全透明),这是让窗口视觉透明的关键——窗口的透明基于渲染出的网页背景,HTML 背景不透明时窗口也就不透明;
  • 真正可见的内容是 .white-circle 这个 100×100 的白色圆形 div,配合 border-radius: 50% 呈现圆形外观;
  • app-region: drag 声明使该圆形区域可以被当作标题栏一样拖动窗口(弥补无边框窗口没有系统拖拽区域的不足);
  • user-select: none 防止拖拽过程中误选中文本。

由于窗口尺寸(100×100)与圆形 div 尺寸一致,最终用户看到的就是一个"圆形窗口",这正是"透明窗口 + CSS"打造异形窗口的通用套路。

透明窗口的限制(Limitations)

透明窗口并不等同于"完全自由"的窗口,文档明确列出了若干使用中必须接受的边界条件,这些限制直接影响技术选型:

  • 无法穿透透明区域点击:不能点击穿过透明区域到达下面的内容。即透明只是"视觉上的透明",命中测试仍按整块窗口区域进行(Windows 上透明区域的点击穿透需要另行使用其它 API 方案,详见 browser-window.md 相关说明与官方 issue 讨论)。
  • 透明窗口不可缩放:将 resizable 设为 true 可能使某些平台上的透明窗口停止正常工作。因此示例中显式设置 resizable: false
  • CSS blur() 滤镜只作用于窗口自身内容:它只能模糊窗口内(Web contents)的元素,无法对窗口下方其他应用的内容产生模糊。也就是说,无法用这种方式实现 iOS 风格的"背景毛玻璃"遮罩效果。
  • 打开 DevTools 时窗口将不再透明:调试主内容时会临时失去透明效果。
  • Windows 平台
    • 透明窗口不能通过 Windows 系统菜单或双击标题栏的方式最大化(相关背景见上游 PR 讨论,原因与 Windows 的最大化路径相关)。
  • macOS 平台
    • 透明窗口不会显示原生窗口阴影。

更进一步的窗口定制思路

掌握了 frametransparent 两个开关之后,围绕"自定义窗口样式"还可以继续扩展的方向包括:

  1. 自定义标题栏而非完全无边框:如果你仍希望保留系统窗口按钮(如 macOS 的"红绿灯"),titleBarStyle: 'hidden' 是不错的选择,它隐藏标题栏但保留系统按钮。相关 fiddle 见 custom-title-bar/,文档见 custom-title-bar.md
  2. 圆角与背景色控制:通过 roundedCornersbackgroundColorhasShadow 等参数(定义见 base-window-options.md)精细调节窗口外观;backgroundColortransparent: true 时还可配合 #AARRGGBB 形式的 Alpha 值使用。
  3. 平台特性叠加:macOS 的 vibrancy、Windows 的 backgroundMaterial(如 Mica/Acrylic)等参数能进一步定制系统级材质外观,但这些与"完全透明"目标并存时需要按平台单独验证。
  4. 窗口尺寸与拖拽行为:无边框、透明窗口常与自绘拖拽区(app-region: drag)、无边框自定义交互相结合,仓库的 custom-window-interactions.md 对该主题有系统讲解。

小结

本文以仓库中的 custom-window-styles.md 为主线,还原并扩充了 Electron 无边框窗口与透明窗口的完整实现:核心只有两个开关——frame: false 移除系统 chrome,transparent: true 打开窗口透明通道;而真正的"异形窗口"外观则由 HTML/CSS 在透明画布上绘制。同时必须牢记平台的硬性边界:Wayland 下需额外关闭阴影、Windows 下透明必须配合无边框、透明窗口不可缩放且无法穿透点击、DevTools 会破坏透明效果等。配合 base-window-options.md 中的构造参数定义,你完全可以在自己的 Electron 应用中快速复现出纯净的无边框 UI 或真正的异形透明窗口。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388