
OverlayScrollbarsを使ったTauriアプリのスクロールバーのスタイリング
Michael Charles Aubrey // Mon Aug 04 2025
サイドプロジェクトで開発している Tauri アプリで、カスタムスクロールバーを動作させるのに苦労していました。過去には単純に::-webkit-scrollbar
を使用して成功していましたが、最近はうまく動作しなくなっているようです。GitHub のユーザーx4080さんがoverlayscrollbars
ライブラリの使用を提案してくれ、これが非常にうまく機能しました。しかし、セットアップが私が期待していたよりも少し直感的でなかったので、動作させる方法についてクイックガイドをまとめてみました。
この記事では、React と Tailwind CSS でスタイリングされた Tauri アプリで作業します。ただし、必要に応じて適応できると思います。
まず、overlayscrollbars
をインストールしました
npm install overlayscrollbars
次に、import
を使って CSS にoverlayscrollbars
のスタイルを含め、カスタムスクロールバー用のスタイルを準備しました。
@import "overlayscrollbars/overlayscrollbars.css";
.os-theme-custom.os-scrollbar {
--os-size: 8px;
--os-padding-perpendicular: 0px;
--os-padding-axis: 0px;
}
.os-theme-custom.os-scrollbar .os-scrollbar-track {
background: rgba(120, 90, 200, 0.12);
border-radius: 4px;
}
.os-theme-custom.os-scrollbar .os-scrollbar-handle {
background: rgba(80, 60, 180, 0.45);
border-radius: 4px;
transition: background-color 0.2s ease;
}
.os-theme-custom.os-scrollbar .os-scrollbar-handle:hover {
background: rgba(80, 60, 180, 0.7);
}
次に、このフックを使用してスクロール可能な要素でoverlayscrollbars
を初期化しました。これは主に Tailwind を使用しているため、.overflow-y-auto
とoverflow-auto
を選択できるからです。Tailwind を使用していない場合は、異なるアプローチが必要になります。
import { OverlayScrollbars } from "overlayscrollbars";
import { useEffect } from "react";
export const useOverlayScrollbars = () => {
useEffect(() => {
// すべてのスクロール可能な要素でOverlayScrollbarsを初期化
const initScrollbars = () => {
// メインのスクロール可能なエリアをターゲットにする
const scrollableElements = [
document.body,
document.querySelector('[data-scrollable="true"]'),
...document.querySelectorAll(".overflow-y-auto"),
...document.querySelectorAll(".overflow-auto"),
].filter(Boolean) as Element[];
scrollableElements.forEach((element) => {
const htmlElement = element as HTMLElement;
if (
htmlElement &&
!htmlElement.hasAttribute("data-overlayscrollbars-initialize")
) {
OverlayScrollbars(htmlElement, {
scrollbars: {
theme: "os-theme-custom",
autoHide: "never",
},
});
htmlElement.setAttribute("data-overlayscrollbars-initialize", "true");
}
});
};
// 即座に初期化
initScrollbars();
// DOM変更時に再初期化(動的コンテンツ用)
const observer = new MutationObserver(() => {
setTimeout(initScrollbars, 100);
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["class"],
});
return () => {
observer.disconnect();
// すべてのOverlayScrollbarsインスタンスをクリーンアップ
document
.querySelectorAll("[data-overlayscrollbars-initialize]")
.forEach((element) => {
const instance = OverlayScrollbars(element as HTMLElement);
if (instance) {
instance.destroy();
}
});
};
}, []);
};
次にApp.tsx
でフックを呼び出しました。
import { useOverlayScrollbars } from "./hooks/useOverlayScrollbars";
function App() {
// 初期状態...
// カスタムスクロールバーを初期化
useOverlayScrollbars();
// その他のフック...
return <main>{/* アプリのコンテンツ ... */}</main>;
}
export default App;
以上です!これまでのところ、サイドプロジェクトの Snappad でスクロールバーのスタイリングにうまく機能しています。
