配了三年桌面 PWA,每次自定义窗口拖拽都要靠 -webkit-app-region 黑魔法——今天 window-drag 把这件事彻底标准化了
你做桌面 PWA 或者套 Electron 壳的时候,有没有想过把浏览器原生的标题栏藏掉,自己画一套?这时候问题来了——怎么让某个区域能拖动窗口?
过去解法是 -webkit-app-region: drag。这个属性 Chromium 先用,后来 Electron 跟进,几乎成了业界事实标准。但它从来没进过 CSS 规范,是个纯正的「浏览器私有属性」。
Chrome 152 把这件事扳过来了。
window-drag 是什么
CSS Basic User Interface Module Level 4 规范里新增了 window-drag 属性,用来声明页面上的某个区域「拖动这个区域 = 拖动整个应用窗口」。值有两个:
/* 声明为可拖拽窗口区域 */
.titlebar {
window-drag: move;
}
/* 取消拖拽,让子元素恢复可交互 */
button {
window-drag: none;
}
对应的就是旧的 -webkit-app-region: drag 和 -webkit-app-region: no-drag。只不过现在名字改成了标准化版本,语义更准确(move vs none,比 drag vs no-drag 更好理解),且自带 CSS 继承行为——子元素默认继承 none,不需要每个按钮单独写一遍。
实际怎么用
最典型的场景是 PWA 自定义标题栏:
<script>
if (windowControlsOverlay in navigator) {
// 根据窗口控件位置动态适配背景
const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
document.body.classList.toggle(controls-right, x > 0);
}
</script>
<header class="titlebar">
<span class="app-title">My App</span>
<div class="window-controls">
<button id="minimize">─</button>
<button id="maximize">☐</button>
<button id="close">✕</button>
</div>
</header>
.titlebar {
display: flex;
align-items: center;
justify-content: space-between;
/* 把整个 header 声明为窗口拖拽区 */
window-drag: move;
/* 防止拖拽时选中文本 */
user-select: none;
/* 保证标题栏在内容上方 */
z-index: 9999;
/* 适配窗口控件位置(Linux/Windows 在右,macOS 在左) */
background: linear-gradient(90deg,
#36c, 45%,
var(--bg) 90%);
}
.titlebar.controls-right {
background: linear-gradient(90deg,
#36c, var(--bg) 33%, var(--bg));
}
/* 窗口控制按钮取消拖拽,恢复可点击 */
.window-controls button {
window-drag: none;
background: transparent;
border: none;
cursor: pointer;
}
这就是 PWA 里 Window Controls Overlay 的标准配合用法。navigator.windowControlsOverlay.getTitlebarAreaRect() 能拿到原生标题栏占用的矩形区域,帮你动态计算自定义标题栏的背景渐变方向,保证视觉上「原生标题栏」和「自定义标题栏」无缝衔接。
和旧属性怎么迁移
已有的项目不用担心,Chromium 内部把 app-region 实现成了 window-drag 的别名,两套写法同时生效:
/* 旧写法,Chromium 内部映射到 window-drag,完全兼容 */
.titlebar {
-webkit-app-region: drag;
}
button {
-webkit-app-region: no-drag;
}
新增代码建议直接用 window-drag。CSS 工作组这次没有废弃旧属性,只是加了一层标准化别名,过渡是平滑的。
浏览器支持情况
| 浏览器 | 支持 |
|---|---|
| Chrome 152+ | ✅ |
| Edge 152+ | ✅ |
| Firefox | Positive(有意实现) |
| Safari | 暂无信号 |
目前只有 Chromium 系浏览器(Chrome/Edge)稳定支持,但 Firefox 那边已经是 Positive 信号,进了标准化快车道。Electron 应用里因为本身就是 Chromium 内核,-webkit-app-region 早就生效,升级到 window-drag 只需要改一行属性名。
什么时候用它
window-drag 解决的是「桌面 Web 应用」这个场景里的原生体验问题:
用它的场景:
- PWA 安装到桌面后,想隐藏原生标题栏、自己画标题栏
- Electron/Tauri 套壳应用,需要自定义窗口控制按钮(最小化/最大化/关闭)
- 任何想把某个区域变成「窗口拖拽手柄」的 Web 页面
不需要它的场景:
- 普通移动端/桌面浏览器里的网页——用户本来就不应该能拖动页面里的某个 div 去移动浏览器窗口
- macOS/Linux 上用原生标题栏的桌面应用
app-region 之所以成为事实标准,就是因为桌面 Web 应用场景真实存在。现在它进了 CSS 规范,意味着未来跨浏览器一致性和工具链支持都会更好。如果你现在正在做 PWA 桌面化或者 Electron 应用,window-drag: move 值得现在就换上去——一行属性的事。
评论区
登录后可评论。