外观
Tauri 自定义 Titlebar 与窗体圆角实现指南
约 1283 字大约 4 分钟
TaurimacOS自定义窗口Titlebar
次阅读
2026-05-12
概述
基于 Tauri 2 + 前端框架(Vue / React / Svelte 等)实现 macOS 风格的自定义窗口外观:隐藏原生标题栏,自绘红黄绿交通灯按钮,可拖拽 Titlebar,以及圆角窗体。所有窗口样式逻辑均在前端完成,Rust 后端无窗口相关代码。
一、架构总览
tauri.conf.json → 禁用原生装饰 + 透明窗口
Cargo.toml → 启用 macOS 私有 API feature
capabilities/default.json → 授权前端窗口操作权限
Titlebar 组件 → 交通灯按钮 + 拖拽区域
全局样式 → Titlebar 样式 + 窗体圆角二、Tauri 配置层
2.1 tauri.conf.json 关键配置
{
"app": {
"macOSPrivateApi": true,
"windows": [{
"decorations": false,
"transparent": true,
"resizable": true,
"fullscreen": false,
"center": true
}]
}
}三个配置缺一不可:
| 配置项 | 作用 | 缺失后果 |
|---|---|---|
macOSPrivateApi: true | 允许使用 macOS 私有窗口 API | transparent 在 macOS 上不生效 |
decorations: false | 移除原生标题栏 | 自定义 Titlebar 会被原生栏遮挡 |
transparent: true | 窗口背景透明 | 圆角处露出矩形窗口底色 |
2.2 Cargo.toml Feature Flag
tauri = { version = "2.0", features = ["macos-private-api"] }与 tauri.conf.json 中的 macOSPrivateApi: true 配对,是 Rust 侧的等效开关。
2.3 capabilities/default.json 权限声明
"permissions": [
"core:window:allow-start-dragging",
"core:window:allow-close",
"core:window:allow-minimize",
"core:window:allow-toggle-maximize",
"core:window:allow-set-size",
"core:window:allow-set-position",
"core:window:allow-center",
"core:window:allow-is-maximized"
]
allow-start-dragging是data-tauri-drag-region属性生效的必要权限,缺少则拖拽失效。
三、自定义 Titlebar
3.1 组件结构
以下以 HTML 结构为例,适配任意前端框架:
<header class="app-titlebar" data-tauri-drag-region ondblclick="handleTitlebarDblClick">
<div class="titlebar-left">
<div class="traffic-lights">
<button class="traffic-light traffic-close" onclick="handleClose()">
<!-- 关闭图标 SVG -->
</button>
<button class="traffic-light traffic-minimize" onclick="handleMinimize()">
<!-- 最小化图标 SVG -->
</button>
<button class="traffic-light traffic-maximize" onclick="handleMaximize()">
<!-- 最大化图标 SVG -->
</button>
</div>
<div class="titlebar-brand">
<span class="app-title">应用名称</span>
</div>
</div>
<div class="titlebar-right">
<!-- 放置自定义按钮:设置、搜索等 -->
</div>
</header>
data-tauri-drag-region声明在<header>上,使整个标题栏区域可拖拽移动窗口。
3.2 窗口控制逻辑
import { getCurrentWindow } from '@tauri-apps/api/window'
const appWindow = getCurrentWindow()
function handleTitlebarDblClick() { appWindow.toggleMaximize() }
function handleMinimize() { appWindow.minimize() }
function handleMaximize() { appWindow.toggleMaximize() }
function handleClose() { appWindow.close() }- 双击 Titlebar 区域触发最大化/还原(模拟 macOS 原生行为)
- 按钮各自调用 Tauri Window API
3.3 拖拽区域实现
两种方式并存(双重保障):
| 方式 | 属性 | 说明 |
|---|---|---|
| Tauri 原生 | data-tauri-drag-region | Tauri 识别此属性后自动处理窗口拖拽 |
| Webkit CSS | -webkit-app-region: drag | Webview 兼容层,确保在各平台生效 |
交互元素(按钮、链接)需要排除在拖拽区域外:
.app-titlebar {
-webkit-app-region: drag; /* 整个 header 可拖拽 */
}
.app-titlebar button,
.app-titlebar a {
-webkit-app-region: no-drag; /* 子元素不参与拖拽 */
}3.4 交通灯按钮样式
尺寸与布局:
.traffic-lights {
display: flex;
align-items: center;
gap: 8px;
}
.traffic-light {
width: 12px; /* 圆形直径 12px */
height: 12px;
border-radius: 50%;
border: none;
cursor: pointer;
}颜色系统:
| 按钮 | 默认色 | Hover 色 |
|---|---|---|
| 关闭(红) | #ff5f57 | #ff3b30 |
| 最小化(黄) | #febc2e | #f5a623 |
| 最大化(绿) | #28c840 | #20b835 |
Hover 交互(模拟 macOS 原生行为):
.traffic-light {
color: transparent; /* SVG 图标默认隐藏 */
}
.traffic-light svg {
opacity: 0;
}
.traffic-lights:hover .traffic-light svg {
opacity: 1; /* hover 整组时所有图标同时显现 */
}
.traffic-light:hover {
color: rgba(0, 0, 0, 0.6); /* 图标变为深色 */
}图标使用
currentColor继承color,opacity控制显隐。当鼠标 hover 任意一个交通灯按钮时,三个图标同时显示(通过父级.traffic-lights:hover触发),与 macOS 原生行为完全一致。
3.5 Titlebar 整体尺寸
.app-titlebar {
height: 42px;
padding: 0 12px;
background: var(--color-bg-white);
border-bottom: 1px solid var(--color-border-light);
user-select: none;
flex-shrink: 0;
}四、窗体圆角
4.1 实现原理
┌─ Tauri 原生窗口(透明,无装饰)──────────────────┐
│ │
│ ┌─ .app-container (border-radius: 10px) ──────┐ │
│ │ │ │
│ │ 所有可见 UI 内容 │ │
│ │ │ │
│ └──────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘- Tauri 窗口本身是透明无边框的矩形
.app-container是唯一可见的内容层,设置了圆角overflow: hidden裁切掉圆角外的内容
4.2 CSS 实现
html, body {
background: transparent; /* webview 背景透明 */
}
.app-container {
height: 100vh;
background: var(--color-bg-light);
border-radius: 10px;
overflow: hidden;
}4.3 注意事项
| 要点 | 说明 |
|---|---|
transparent: true 必须 | 否则原生窗口的矩形底色会露出,圆角无效 |
overflow: hidden 必须 | 否则子元素会溢出圆角区域 |
html, body 必须透明 | 否则 webview 层的背景色会遮挡圆角效果 |
| 全屏模式 | fullscreen: false 默认关闭;全屏时圆角无意义 |
五、常见问题排查
| 问题 | 排查方向 |
|---|---|
| 窗口不透明 / 圆角无效 | 检查 macOSPrivateApi、transparent、Cargo.toml feature 三处是否全部启用 |
| 标题栏无法拖拽 | 检查 capabilities/default.json 是否声明 allow-start-dragging |
| 按钮点击无效 | 检查是否有 -webkit-app-region: no-drag 排除按钮 |
| 交通灯颜色不对 | 暗色主题下需要额外覆盖交通灯颜色 |
| 窗口闪烁 / 白边 | html, body { background: transparent } 是否在最顶层 CSS 生效 |