你以为 Electron 的 app-region 只能在 Electron 里用?Chrome 今天把它变成了 Web 标准
写过 Electron 桌面应用的前端,都踩过 app-region: drag 这个坑——它能让你把一个 div 变成窗口标题栏,但属性名是 Electron 私有的,属性值没有统一规范,Safari 和 Firefox 完全不认识它,你的代码只能在 Electron 里跑。今天 Chrome 152 把这件事用一行 CSS 彻底原生化了:window-drag: move,而且它已经进了 W3C CSS Basic User Interface Level 4 规范。
痛点:Electron 私有的那一套,Web 标准不认
自定义桌面应用标题栏,一直是 Electron 的强项。核心靠的就是这个 CSS:
/* Electron 专用,非标准 */
.titlebar { app-region: drag; }
.btn { app-region: no-drag; }
但 app-region 是 Electron 自己发明的,不在任何 Web 标准里。带来的问题:
- 普通浏览器完全不认识——你在 Chrome 调试窗口里打开这个 PWA,app-region: drag 直接被当成无效属性
- 只能装成桌面应用才能用——普通标签页里,这个属性没有任何效果
- 值名不规范——Electron 的 drag/no-drag,没有统一标准,不同版本行为可能有差异
- 没有继承语义——子元素要不要继承、能不能单独覆盖,说不清楚
做 Electron 的人习惯了也就忍了,但如果你想用纯 Web 技术做一个 PWA 桌面应用,这件事以前根本没法做。
新方案:window-drag: move
Chrome 152 正式支持了 CSS Basic User Interface Module Level 4 中的 window-drag 属性:
/* Chrome 152+ 标准语法 */
.titlebar { window-drag: move; }
.interactive-area { window-drag: none; }
语义非常清晰:
- move:这个区域可以拖动窗口(替代 Electron 的 app-region: drag)
- none:这个区域恢复正常指针交互,不拖动窗口(替代 app-region: no-drag)
- 明确的继承行为:window-drag 可以在子元素上单独覆盖,不会出现子元素继承了父级拖动属性但无法取消的问题
前置条件:必须是已安装的 PWA
和 Electron 不同,window-drag 是浏览器原生能力,不是 Electron 私有 API。它有一个硬性前置条件:必须是已安装到桌面的 PWA,且使用了 Window Controls Overlay 显示模式。普通标签页里,这个属性不生效。
所以你的 manifest.webmanifest 需要加上这一行:
{
"display_override": ["window-controls-overlay", "standalone"],
"display": "standalone"
}
完整实战:做一个可拖动的 PWA 标题栏
第一步:manifest 配置 Window Controls Overlay
{
"name": "My Desktop App",
"short_name": "App",
"start_url": "/",
"display_override": ["window-controls-overlay"],
"display": "standalone",
"theme_color": "#111827",
"icons": [...]
}
第二步:HTML 标题栏结构
<div class="titlebar">
<div class="titlebar-content">
<span class="app-name">My App</span>
<input type="text" class="search-field" placeholder="Search..." />
<button class="settings-btn">⚙</button>
</div>
</div>
<div class="app-content"><!-- 主内容区 --></div>
第三步:CSS
.titlebar {
height: 44px;
background: #111827;
color: #f9fafb;
display: flex;
align-items: center;
/* 标题栏区域可以拖动窗口 */
window-drag: move;
}
.search-field, .settings-btn {
/* 搜索框和按钮不能拖动窗口,要恢复正常交互 */
window-drag: none;
}
关键点:window-drag: none 需要显式标在每个交互元素上,因为窗口拖动区域会拦截所有指针事件——如果你不给按钮加 window-drag: none,用户在标题栏里点任何按钮都不会有任何反应。
和 Electron app-region 的区别
| 能力 | Electron app-region | CSS window-drag |
|---|---|---|
| 标准归属 | Electron 私有 | W3C CSS UI Level 4 |
| 浏览器支持 | 仅 Electron | Chrome 152+, Edge 152+ |
| 继承语义 | 不明确 | 显式,可单独覆盖 |
| 是否需要 PWA 安装 | 否 | 是(Window Controls Overlay) |
| 适用场景 | Electron 桌面应用 | PWA 桌面应用 |
迁移路径:Electron 项目怎么接
如果你现在有 Electron 项目用了 app-region,想平滑迁移到 Web 标准:
阶段一:加 window-drag 做渐进增强
/* 兼容 Electron + Chrome 152+ */
.titlebar {
app-region: drag; /* Electron 旧方案 */
window-drag: move; /* Web 标准新方案 */
}
.interactive-area {
app-region: no-drag; /* Electron 旧方案 */
window-drag: none; /* Web 标准新方案 */
}
两个属性同时存在,Electron 用旧的,Chrome 152+ 用新的,互不影响。
阶段二:PWA 化
- 写 manifest.webmanifest
- 加 display_override: [“window-controls-overlay”]
- Service Worker 加上离线支持
- 桌面端安装后 window-drag 自动生效
阶段三:完全迁移(长期目标)
Electron 本身的强项是完整 Node.js 环境接入。如果你只需要做 UI 桌面应用,window-drag + PWA 能覆盖大部分场景,同时省掉 Electron 的打包和分发成本。
浏览器兼容性
| 浏览器 | 支持情况 |
|---|---|
| Chrome 152+ | ✅ 稳定 |
| Edge 152+ | ✅ 稳定 |
| Firefox | ❌ 不支持 |
| Safari | ❌ 不支持 |
目前只有 Chrome/Edge 支持,但作为 Chromium 系内核,Electron 理论上可以在未来版本里也支持这个标准。需要关注 ChromeStatus 页面(chromestatus.com/feature/477608113)跟进进度。
下一步
如果你的项目符合以下条件,现在就可以开始迁移:
- Electron 项目里有 app-region 相关代码
- 核心 UI 功能不依赖 Node.js 特有 API
- 目标用户使用 Chrome 或 Edge 桌面版
把 app-region: drag 替换成 window-drag: move,加上 window-drag: none 到每个交互子元素,跑通 Window Controls Overlay 安装流程——这件事的技术成本不高,但能让你的应用从 Electron 私有生态里向前迈一步。
评论区
登录后可评论。