KO
|
EN
gitlite — search
Search
#typescript
#ai-agents
#ai
#dsh-plugin
#deepseek-harness
#open-source
#cli
#claude-code
#codex
#developer-tools
#react
#windows
dumogu-scrollbar
★ 35
Open GitHub ↗
A simple custom scroll bar plugin.
Download README (.md)
Explore Similar Repositories
TinyBasRV
:
Small Tiny BASIC computer based on CH32V003
Awesome-Human-Data-For-Manipulation
:
No description available.
2API-Fuse
:
No description available.
rp5-dualboot
:
A guide on how to dual-boot Android and Linux on the Retroid Pocket 5.
ClipMaster
:
A powerful GNOME Shell clipboard manager with history, encryption, image support, favorites, and 12 themes. Follows system dark/light mode.
// repository documentation
Was this content helpful?
★ 0
(0 ratings)
Select Rating:
★
★
★
★
★
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
dumogu-scrollbar
?
Download (.md)
[English](https://github.com/wurencaideli/dumogu-scrollbar/blob/master/README.md) | [中文](https://github.com/wurencaideli/dumogu-scrollbar/blob/master/docs/README.zh-CN.md) | [한국어](https://github.com/wurencaideli/dumogu-scrollbar/blob/master/docs/README.ko-KR.md) | [日本語](https://github.com/wurencaideli/dumogu-scrollbar/blob/master/docs/README.ja-JP.md) ## Introduction A simple and lightweight custom scrollbar plugin. The compressed file is less than 10KB. The scrollbar is rendered as an absolutely-positioned overlay — it does **not** wrap or modify the scroll container in any way. By default it mounts to `document.body`, keeping your original DOM structure intact. You can also use the `DumoguScrollbarRail` component directly to place scrollbar rails anywhere you like with fully custom styles. [DEMO](https://wurencaideli.github.io/dumogu-scrollbar/demo.html) ## Install ```bash npm install dumogu-scrollbar ``` Or load directly in the browser via UMD: ```html <link rel="stylesheet" href="dumogu-scrollbar/dist/dumogu-scrollbar.css" /> <script src="dumogu-scrollbar/dist/dumogu-scrollbar.umd.js"></script> <script> const { DumoguScrollbar, DumoguScrollbarRail } = window['dumogu-scrollbar']; </script> ``` ## Quick Start ### 1. Import CSS With a bundler: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; ``` Or in the browser: ```html <link rel="stylesheet" href="dumogu-scrollbar/dist/dumogu-scrollbar.css" /> ``` ### 2. Hide native scrollbars The plugin does **not** hide native scrollbars for you. Add this CSS to the target element: ```css .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; } .no-scrollbar::-webkit-scrollbar { display: none; } ``` **Important:** Do NOT mount the custom scrollbar into the scrollable element itself. Since the scrollbar overlay uses `position: absolute`, placing it inside a scroll container would cause it to move with the scroll position. Instead, mount it to `body` (the default) or to a wrapper element outside the scroll container. ## Usage ### Page-level scrollbar (window) Call `bind()` with no arguments to bind to `window`, and `mount()` with no arguments to mount to `body`: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; import { DumoguScrollbar } from 'dumogu-scrollbar'; const ds = new DumoguScrollbar({ keepShow: false, stopClickPropagation: true, }); ds.bind(); // bind to window ds.mount(); // mount to document.body ``` ### Element scrollbar Pass a scrollable element to `bind()`: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; import { DumoguScrollbar } from 'dumogu-scrollbar'; const ds = new DumoguScrollbar({ keepShow: true, stopClickPropagation: true, }); ds.bind(document.querySelector('#my-scroll-container')); ds.mount(); ``` ### Mount to a custom container Pass a container element to `mount()`. The scrollbar overlay will be positioned relative to that container instead of `body`: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; import { DumoguScrollbar } from 'dumogu-scrollbar'; const ds = new DumoguScrollbar({ keepShow: false }); ds.bind(document.querySelector('#my-scroll-container')); ds.mount(document.querySelector('#my-wrapper')); ``` This is useful when your scroll container is inside a positioned ancestor — mounting to `body` would cause misalignment, but mounting to the wrapper keeps the scrollbar positioned correctly without manual CSS. ### Using DumoguScrollbarRail standalone You can create individual rails (X or Y) and place them anywhere in the DOM — even completely outside the scroll container's layout: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; import { DumoguScrollbarRail } from 'dumogu-scrollbar'; // Always-visible horizontal rail const railX = new DumoguScrollbarRail({ isX: true, keepShow: true, stopClickPropagation: true, }); document.querySelector('#rail-container').appendChild(railX.railEl); railX.bind(document.querySelector('#my-scroll-container')); railX.railEl.classList.add('my-custom-rail-style'); ``` You can also create hover-only rails by setting `keepShow: false`: ```js // Only visible on hover or when hovering the scroll target const railX = new DumoguScrollbarRail({ isX: true, keepShow: false, stopClickPropagation: true, }); ``` Each rail is independent — you can mix always-show and hover-show rails in different positions. ### Managing multiple instances When you have several scroll containers on the page, use a shared `requestAnimationFrame` loop to keep all scrollbars updated: ```js import 'dumogu-scrollbar/dist/dumogu-scrollbar.css'; import { DumoguScrollbar } from 'dumogu-scrollbar'; const dsList = []; const railList = []; // Create instances... const ds1 = new DumoguScrollbar({ keepShow: true }); ds1.bind(document.querySelector('#scroll-1')); ds1.mount(); dsList.push(ds1); function updateLoop() { requestAnimationFrame(() => { dsList.forEach(item => item.update()); railList.forEach(item => item.update()); updateLoop(); }); } updateLoop(); ``` Each `DumoguScrollbar` instance manages both X and Y rails internally. Use `DumoguScrollbarRail` standalone when you need to position rails independently. ## API ### `new DumoguScrollbar(options?)` | Option | Type | Default | Description | |---|---|---|---| | `keepShow` | `boolean` | `false` | Always show the scrollbar (otherwise shows on hover/drag) | | `stopClickPropagation` | `boolean` | `false` | Stop click events from propagating on the rail | ### `new DumoguScrollbarRail(options)` | Option | Type | Default | Description | |---|---|---|---| | `isX` | `boolean` | `false` | Horizontal rail (`true`) or vertical (`false`) | | `keepShow` | `boolean` | `false` | Always show the rail | | `stopClickPropagation` | `boolean` | `false` | Stop click events from propagating on the rail | ### Methods | Method | Description | |---|---| | `bind(targetEl?)` | Bind to a scrollable element. Omit to bind to `window`. | | `mount(containerEl?)` | Mount the scrollbar overlay. Omit to mount to `document.body`. | | `unmount()` | Remove the scrollbar overlay from the DOM. | | `update()` | Recalculate scrollbar position and size. Call this after the target's content changes size. | | `destroy()` | Unmount, remove all listeners, and mark the instance as destroyed. | ### Properties | Property | Type | Description | |---|---|---| | `scrollbarEl` | `HTMLElement` | The root scrollbar element. Add CSS classes to it for custom styling. | | `railX` | `DumoguScrollbarRail` | The horizontal rail instance. | | `railY` | `DumoguScrollbarRail` | The vertical rail instance. | | `targetEl` | `HTMLElement \| undefined` | The currently bound scroll target. | | `isMounted` | `boolean` | Whether the scrollbar is currently mounted. | | `isDestroyed` | `boolean` | Whether the instance has been destroyed. | ### DumoguScrollbarRail properties | Property | Type | Description | |---|---|---| | `railEl` | `HTMLElement` | The root rail element. | | `thumbEl` | `HTMLElement` | The thumb/dragger element inside the rail. | | `railContainerEl` | `HTMLElement` | The container element between the rail and thumb. | | `isX` | `boolean` | Get/set horizontal mode. | | `keepShow` | `boolean` | Get/set always-show mode. | ## Keeping scrollbar position in sync When content inside the scroll container changes (DOM mutations, images loading, viewport resize), the scrollbar position and thumb size need to be recalculated. Use `requestAnimationFrame` to keep it updated: ```js function updateLoop() { requestAnimationFrame(() => { dsInstance.update(); updateLoop(); }); } updateLoop(); ``` For multiple instances, update them all in a single loop: ```js const instances = [ds1, ds2, ds3]; function updateLoop() { requestAnimationFrame(() => { instances.forEach(item => item.update()); updateLoop(); }); } updateLoop(); ``` If your content is static, you only need to call `update()` after making changes (e.g. after adding/removing DOM elements). ## Behavior details ### `keepShow` | Value | Behavior | |---|---| | `true` | Scrollbar rails are always visible. The `.dumogu-scrollbar-rail_keep_show` class is added. | | `false` (default) | Rails appear when: the mouse hovers over the rail itself, OR the mouse hovers over the bound scroll target. The `.dumogu-scrollbar-rail_hover` and `.dumogu-scrollbar-rail_target_hover` state classes control visibility. | ### `stopClickPropagation` When `true`, click events on the rail (including track-jump clicks) will not bubble up to parent elements. Useful when the scrollbar is inside an element with its own click handlers. ### Thumb minimum size The thumb has a minimum size (similar to native scrollbars), so it remains grabbable even when the content is extremely large relative to the viewport. ## Custom Styling Add CSS classes to `scrollbarEl` (for `DumoguScrollbar`) or `railEl` (for `DumoguScrollbarRail`), then target the internal class names in your stylesheet: ```js ds.scrollbarEl.classList.add('my-theme'); ``` ```css /* Custom horizontal rail */ .my-theme .dumogu-scrollbar-rail_x { height: 10px; padding: 1px; background: rgba(0, 0, 255, 0.1); border-radius: 999px; box-shadow: inset 1px 1px 2px #0000001c; box-sizing: border-box; bottom: 6px; width: calc(100% - 12px); left: 6px; } .my-theme .dumogu-scrollbar-rail_thumb_x { border-radius: 999px; background: #ffffff; box-shadow: 0 0 2px #000000; } /* Custom vertical rail — offset to the left of the scroll container */ .my-theme .dumogu-scrollbar-rail_y { width: 8px; right: initial; left: -14px; } .my-theme .dumogu-scrollbar-rail_thumb_y { border-radius: 999px; background: #e14fad; background-image: linear-gradient(to top, #e14fad 0%, #f9d423 100%); } ``` For `DumoguScrollbarRail` standalone rails, add the class directly to `railEl`: ```js railX.railEl.classList.add('my-rail-theme'); ``` ```css .my-rail-theme .dumogu-scrollbar-rail_thumb_x { background: #43e97b; background-image: linear-gradient(to right, #43e97b 0%, #38f9d7 100%); } ``` ### Positioning notes The default rail CSS positions rails at the edges of the target area. Since rails use absolute positioning, you can override `top`/`right`/`bottom`/`left` to move them anywhere relative to the mount container. Use `!important` when needed to override inline styles. ### Internal CSS class names | Class | Description | |---|---| | `.dumogu-scrollbar` | Root overlay element | | `.dumogu-scrollbar-target` | Positioned target area matching the scroll container | | `.dumogu-scrollbar-rail` | A single rail (track) | | `.dumogu-scrollbar-rail_x` / `.dumogu-scrollbar-rail_y` | Direction-specific rail | | `.dumogu-scrollbar-rail_container` | Inner container of a rail | | `.dumogu-scrollbar-rail_thumb` | The draggable thumb | | `.dumogu-scrollbar-rail_thumb_x` / `.dumogu-scrollbar-rail_thumb_y` | Direction-specific thumb | ### State classes | Class | Applied when | |---|---| | `.dumogu-scrollbar-rail_hidden` | Content fits without scrolling | | `.dumogu-scrollbar-rail_keep_show` | `keepShow` is `true` | | `.dumogu-scrollbar-rail_hover` | Mouse is over the rail | | `.dumogu-scrollbar-rail_target_hover` | Mouse is over the scroll target | | `.dumogu-scrollbar-rail_dragging` | Thumb is being dragged | ## TypeScript Type definitions are included. Both `ScrollbarOption` and `RailOption` types are exported: ```ts import type { ScrollbarOption, RailOption } from 'dumogu-scrollbar'; ```