你以为 PWA 窗口拖拽只能靠非标准属性?Chrome 今天把这件事彻底原生化了
做过 Electron 桌面应用、PWA 安装后的自定义 titlebar,或者任何需要隐藏浏览器原生窗口边框的场景,你一定碰到过这个问题:拖拽区域怎么写?
很长一段时间,答案都是 app-region: drag——一个 WebKit/Blink 私有的非标准属性。你去 MDN 查,搜到的文档写的都是实验性警告。你去 caniuse 查,Safari 一栏永远是 No signal。
这不是开发者不知道标准不等同于好用的区别——大家只是没有选择。
Chrome 152 把这件事彻底原生化了。
Chrome 152(2026-08-25 稳定版)正式支持了 window-drag: move,这是 W3C CSS UI Level 4 规范里的标准属性。它的作用和 app-region: drag 完全一样:让一个元素的点击拖拽行为变成移动整个窗口——但这是正经的 CSS 属性,不是私有前缀的 Hack。
具体用法:
/* 把整个 header 变成窗口拖拽区 */
.header {
window-drag: move;
}
/* 按钮不参与拖拽,必须显式排除 */
.header button {
window-drag: none;
}
就这么两行。以前你要写 -webkit-app-region: drag 和 -webkit-app-region: no-drag,现在有了一个所有浏览器最终都会认的标准写法。
一个属性,背后是两份历史债务
app-region 最早是 Chrome 为了支持 Electron 应用和 Chrome App 的自定义窗口标题栏加的。Electron 把它发扬光大,所有做桌面端 PWA 的团队都在用。但它从来没进过任何标准——它是 WebKit 的实验性功能,后来靠 Chromium 强推才成了事实标准。
CSS Working Group 最终决定把这个能力收编进 CSS UI Level 4,改名 window-drag,值从 drag/nodrag 改成 move/none——更直观,也更符合 CSS 属性的命名惯例。
迁移成本:零
这是这次更新最良心的地方。Chrome 152 没有废弃 app-region,也没有要求你立刻迁移。内部实现上,app-region 就是一个映射到 window-drag 的别名,两套写法在 Chromium 里完全等价。你现在去改也行,不改也行,浏览器不会报警告。
但建议尽快用标准属性更新代码,因为 Firefox 已经对 window-drag 投了 Positive,Safari 还没表态——等 Safari 也支持了,纯标准的写法才能真正通用。
和 Window Controls Overlay 配合使用
window-drag 最典型的使用场景是配合 Window Controls Overlay(WCO)做自定义 titlebar。WCO 让你把窗口控制按钮(关闭/最小化/最大化)覆盖在页面内容上,window-drag 让你把页面的任意区域变成拖拽句柄。两个 API 组合,就是一个完整的自定义窗口:
.titlebar {
/* 窗口控制按钮区域 */
position: fixed;
top: 0;
left: 0;
right: 0;
height: 40px;
window-drag: move; /* 整条 titlebar 可拖动窗口 */
-webkit-app-region: drag; /* Safari fallback,仍需前缀版 */
}
.titlebar button {
window-drag: none; /* 按钮不参与拖拽,可点击 */
-webkit-app-region: no-drag;
}
注意 -webkit-app-region 仍然需要保留作为 Safari 的 fallback——目前 Safari 还没实现 window-drag,但这个状态迟早会变。
下一步怎么做
如果你正在做 Electron 应用、PWA 安装桌面版,或者任何需要自定义窗口标题栏的场景,现在去把你的 -webkit-app-region: drag 改成 window-drag: move,把 -webkit-app-region: no-drag 改成 window-drag: none。保留旧写法作为 Safari fallback,直到 Safari 跟进支持。Chrome 已经稳定大半年,这个迁移窗口期已经成熟了。
评论区
登录后可评论。