你以为 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 化

  1. 写 manifest.webmanifest
  2. 加 display_override: [“window-controls-overlay”]
  3. Service Worker 加上离线支持
  4. 桌面端安装后 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)跟进进度。

下一步

如果你的项目符合以下条件,现在就可以开始迁移:

  1. Electron 项目里有 app-region 相关代码
  2. 核心 UI 功能不依赖 Node.js 特有 API
  3. 目标用户使用 Chrome 或 Edge 桌面版

把 app-region: drag 替换成 window-drag: move,加上 window-drag: none 到每个交互子元素,跑通 Window Controls Overlay 安装流程——这件事的技术成本不高,但能让你的应用从 Electron 私有生态里向前迈一步。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 15 阅读