背景が透ける透明なウィンドウを作る

transparent: true とページの CSS で背景を透かし、デスクトップに浮かぶウィジェットを作る。白い背景が残る原因、macOS の macOSPrivateApi、Mica などの効果も示す。

ウィンドウ 対象: Tauri 2.x 更新日: 読了目安: 約9分 win-008
目次
  1. 前提条件
  2. 1. フロントエンドから実装する (TypeScript)
  3. ページの背景を透明にする (CSS)
  4. ウィンドウ効果で背後をぼかす
  5. 透明なウィンドウを後から開く
  6. 2. バックエンドから実装する (Rust)
  7. 動作確認
  8. よくあるエラーと対処法
  9. OS ごとの違いと注意点
  10. 関連レシピ

角の丸いカード型のウィジェットや、画面に重ねる半透明のオーバーレイは、ウィンドウの背景を透明にして作ります。設定ファイルの transparent: true(Rust なら transparent(true))でウィンドウを透明にし、ページの CSS でも背景を透明にします。透明かどうかは作成時に決まり、実行中に切り替える API はありません。枠を消す方法は フレームレスウィンドウ、影は 影を付ける・消す で扱います。

前提条件

プラグインは不要で、transparent は設定だけなので権限も要りません。後述の API を JS から呼ぶときだけ次の権限を追加します。どちらも core:default には含まれません。

使う API権限
setEffects() / clearEffects()(背後をぼかす効果)core:window:allow-set-effects
new WebviewWindow()(透明なウィンドウを後から開く)core:webview:allow-create-webview-window
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Capability for the main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "core:window:allow-set-effects",
    "core:webview:allow-create-webview-window"
  ]
}

設定例です。枠があると透けた部分の上にタイトルバーが残るので、普通は decorations: false と組み合わせます。shadow: false は Windows で周りに出る細い枠線を避けるためです(理由は win-014)。

{
  "app": {
    "macOSPrivateApi": true,
    "windows": [
      {
        "label": "main",
        "title": "Widget",
        "width": 360,
        "height": 240,
        "transparent": true,
        "decorations": false,
        "shadow": false,
        "alwaysOnTop": true
      }
    ]
  }
}

macOS で透明にするには app.macOSPrivateApi: true が必要です(Cargo の macos-private-api フィーチャーも有効になります)。macOS の非公開 API を使うため、Mac App Store の審査には通りません。

1. フロントエンドから実装する (TypeScript)

ページの背景を透明にする (CSS)

ウィンドウが透明でも、ページに背景色があればその色で塗られます。ページ全体の背景を透明にし、見せたい部分だけに色を付けます。

/* ページ全体は透明に。html ではなく :root で書くのがポイント */
:root,
body {
  background: transparent;
}

body {
  margin: 0;
  overflow: hidden; /* スクロールバーが出ると不透明な帯が見えてしまう */
}

/* 見せたいカードだけに色と角丸を付ける */
.card {
  margin: 8px;
  padding: 16px;
  border-radius: 16px;
  background: rgba(30, 30, 30, 0.85);
  color: #fff;
}

よくあるのが「html { background: transparent; } と書いたのに白いまま」という失敗です。create-tauri-app の vanilla テンプレートの styles.css は :root に背景色を指定しており、:root は html より詳細度が高いので html の指定が負けます。ダークモード用の @media の中にも :root の背景色があり、OS をダークモードにしたときだけ灰色になることもあります。該当行を消すか、上のように :root で上書きします。

CSS の backdrop-filter: blur() でぼけるのはページ内の要素だけで、ウィンドウの後ろのデスクトップはぼけません。背後をぼかすには次のウィンドウ効果を使います。

ウィンドウ効果で背後をぼかす

Windows の Mica や Acrylic、macOS のすりガラス効果は、設定ファイルの windowEffects か JS の setEffects() で付けます。透明なウィンドウでないと効きません。effects 配列には OS ごとの候補を並べられ、各 OS は自分が対応する種類のうち先頭の 1 つだけを使います。Mica と Acrylic を並べても、Mica が使えない環境で Acrylic に切り替わるわけではありません。対応していない効果はエラーにならず、何も起きないだけです。

import { getCurrentWindow, Effect, EffectState } from '@tauri-apps/api/window';

const win = getCurrentWindow();

// Windows 11 は Mica、macOS は HUD 風の素材を使う
export async function enableGlass() {
  await win.setEffects({
    effects: [Effect.Mica, Effect.HudWindow],
    state: EffectState.Active, // macOS のみ: 非アクティブでも効果を保つ
    radius: 12,                // macOS のみ: 効果の角丸
  }); // core:window:allow-set-effects が必要
}

export async function disableGlass() {
  await win.clearEffects();
}

起動時から付けるなら、ウィンドウの設定に "windowEffects": { "effects": ["mica", "hudWindow"], "state": "active" } と書きます。

透明なウィンドウを後から開く

実行中に透明へ切り替えることはできないので、透明なウィンドウを別に開きます。表示するページの用意は サブウィンドウを開く を参照してください。

import { WebviewWindow } from '@tauri-apps/api/webviewWindow';

export function openOverlay() {
  const overlay = new WebviewWindow('overlay', {
    url: '/overlay.html',
    width: 320,
    height: 180,
    transparent: true,
    decorations: false,
    shadow: false,
    alwaysOnTop: true,
    skipTaskbar: true,
  }); // core:webview:allow-create-webview-window が必要
  void overlay.once('tauri://error', (e) => console.error('作成に失敗:', e.payload));
  return overlay;
}

2. バックエンドから実装する (Rust)

Rust では WebviewWindowBuilder の transparent(true) で作ります。このメソッドは macOS では macos-private-api フィーチャーが有効なときしか存在しないので、macOSPrivateApi 無しで macOS 向けにビルドするとコンパイルエラーになります。効果は EffectsBuilder で組み立て、set_effects(None) で外します。Windows ではウィンドウを同期コマンドで作ると固まることがあるので、作成するコマンドは async にします。

use tauri::window::{Effect, EffectState, EffectsBuilder};
use tauri::{WebviewUrl, WebviewWindowBuilder};

/// 透明なオーバーレイを開く(同じラベルのウィンドウがあればエラー)
#[tauri::command]
async fn open_overlay(app: tauri::AppHandle) -> Result<(), String> {
    WebviewWindowBuilder::new(&app, "overlay", WebviewUrl::App("overlay.html".into()))
        .inner_size(320.0, 180.0)
        .transparent(true) // macOS では macOSPrivateApi が必要
        .decorations(false)
        .shadow(false)
        .always_on_top(true)
        .skip_taskbar(true)
        .effects(
            EffectsBuilder::new()
                .effects([Effect::Mica, Effect::HudWindow])
                .state(EffectState::Active)
                .build(),
        )
        .build()
        .map_err(|e| e.to_string())?;
    Ok(())
}

/// 呼び出し元ウィンドウの効果を付け外しする
#[tauri::command]
fn set_glass(window: tauri::WebviewWindow, enable: bool) -> Result<(), String> {
    let effects = enable.then(|| {
        EffectsBuilder::new()
            .effects([Effect::Mica, Effect::HudWindow])
            .build()
    });
    window.set_effects(effects).map_err(|e| e.to_string())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![open_overlay, set_glass])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Rust のコマンド経由なら、JS 側に core:window:allow-set-effects などの権限は要りません。

import { invoke } from '@tauri-apps/api/core';

await invoke('open_overlay');
await invoke('set_glass', { enable: false });

動作確認

npm run tauri dev で起動すると、角の丸いカードだけが表示され、周りにデスクトップが見えます。全体が白や灰色なら、DevTools のコンソールで次を実行してページの背景を確かめます。

const colors = [document.documentElement, document.body].map((el) => getComputedStyle(el).backgroundColor);
console.log(colors);

透明なら次のように出ます。色が出たら、その要素に当たっている CSS を上書きします。

['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 0)']

よくあるエラーと対処法

  • ウィンドウ全体が白・灰色のまま: ページ側の背景です。上記のとおり :root の背景色(ダークモード用も)を消すか上書きします。
  • macOS だけ透けない / transparent というメソッドが無いという趣旨のコンパイルエラーになる: app.macOSPrivateApi: true が抜けています。
  • 「window.set_effects not allowed. Permissions associated with this command: core:window:allow-set-effects」: 権限の追加漏れです。リリースビルドでは「Command plugin:window|set_effects not allowed by ACL」と出ます。
  • 効果が付かないのにエラーも出ない: ウィンドウが透明でない、ページの背景が不透明、OS がその効果に対応していない(Mica は Windows 11 のみ、Linux は非対応)のどれかです。
  • ウィンドウの周りに細い白い線が見える: Windows で shadow が有効なままです。影を付ける・消す を参照してください。

OS ごとの違いと注意点

  • Windows: Mica と Tabbed は Windows 11 のみ、Acrylic は 10 / 11、Blur は 7 / 10 / 11 (22H1) が対象です。Acrylic と Blur は、一部のビルドでリサイズやドラッグ中の動きが重くなると注記されています。backgroundColor の透明度は、ウィンドウ側では無視され、WebView 側では 0 以外が不透明扱いになるので、半透明は CSS の rgba() で塗ります。
  • macOS: macOSPrivateApi が必須で、App Store では配布できません。効果は hudWindow、sidebar、popover などの素材から選び、state と radius は macOS だけで効きます。
  • Linux: ウィンドウ効果は非対応です。
  • 共通: 透けて見えても、透明な部分のクリックが背後のアプリに届くとは限りません。背後を操作させたいなら クリックスルー、デスクトップに浮かべるなら 常に最前面 を組み合わせます。
  • 起動直後の白いチラつきを消したいだけなら、transparent ではなく設定ファイルの backgroundColor(例: "#1e1e1e")でページが描かれる前の背景色を決めます。

関連レシピ

参考リンク(公式ドキュメント)

Web Ninja

この記事を書いた人

Web Ninja ウェブエンジニア (Web Engineer)

会社員ネットワークエンジニアから独立してかれこれ 25 年以上 Web エンジニアとして活動中。普段は JavaScript と Node.js を自在に操り、時には C++ や Perl といった古流の技も嗜みます。近年は Tauri × Rust という新たな武器を手に、デスクトップアプリ開発の最前線を駆け抜けています。「作りたい」を「作れる」に変えるための、実践的な「技」をお届けします。

お問い合わせ: tauri.ninja@gmail.com

内容の誤り・動かないコードを報告する