Scroll
`@better-scroll/scroll-bar` powered `TxScroll` container.
Usage
Scroll
Loading demo...
Best Practices
- Prefer native mode for plain article or document scrolling where platform behavior is enough; use BetterScroll only when consistent scrollbars, wheel bridging, bounce, or pull plugins matter.
- Keep
scrollChaining=falsefor nested panels by default. Enable it only when the parent-child scroll handoff is intentional and tested. - Use
noPaddingwhen the child component owns its own spacing, especially virtualized lists, tables, and full-bleed media. - For horizontal or both-axis content, set a deterministic content width or allow the component to set
width: max-content; otherwise BetterScroll cannot infer horizontal overflow reliably. - Always pair
pullDownRefresh/pullUpLoadwith the matching finish method after async work, including failure paths. - Avoid passing large mutable objects through
options; prefer first-class props for documented behavior so watchers and docs stay accurate.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
native | boolean | false | Force native browser scrolling and skip BetterScroll initialization. |
unified | boolean | false | Force BetterScroll takeover for consistent cross-environment behavior (overrides Safari/Chromium auto-native; native=true still wins). |
nativeAutoFallback | boolean | true | Controls auto-native fallback on macOS + Chromium 145+; does not affect the macOS Safari native-first rule. |
noPadding | boolean | false | Remove the default content padding; horizontal and both-axis modes also set content width to max-content. |
scrollChaining | boolean | false | Allow parent scroll handoff at boundaries; not recommended by default, enable only when nested handoff is explicitly needed. |
direction | 'vertical' | 'horizontal' | 'both' | 'vertical' | Select the scroll axes; native mode maps this to overflow-x/y, BetterScroll maps it to scrollX, scrollY, and freeScroll. |
scrollbar | boolean | true | Enable the BetterScroll scrollbar plugin; native mode uses browser scrollbars. |
scrollbarFade | boolean | true | Pass BetterScroll scrollbar fade behavior through when scrollbar is enabled. |
scrollbarInteractive | boolean | true | Allow BetterScroll scrollbar dragging when scrollbar is enabled. |
scrollbarAlwaysVisible | boolean | false | Keep the BetterScroll wrapper in always-visible scrollbar state. |
scrollbarMinSize | number | 18 | Set the minimum BetterScroll scrollbar thumb size via --tx-scrollbar-min-size. |
probeType | 0 | 1 | 2 | 3 | 3 | BetterScroll probeType |
bounce | boolean | true | Enable BetterScroll boundary bounce and the local wheel overshoot behavior. |
click | boolean | true | Pass BetterScroll click handling through. |
wheel | boolean | true | Enable the local wheel bridge for BetterScroll mode; ctrl wheel gestures are ignored. |
refreshOnContentChange | boolean | true | Observe content mutations and call BetterScroll refresh() after changes. |
pullDownRefresh | boolean | Record<string, unknown> | false | Enable pull-down refresh; BetterScroll receives plugin options, native mode emits a threshold-based trigger. |
pullDownThreshold | number | 70 | Minimum native touch delta and BetterScroll plugin threshold for pulling-down. |
pullDownStop | number | 56 | BetterScroll pull-down stop position; native mode does not use this value. |
pullUpLoad | boolean | Record<string, unknown> | false | Enable pull-up load; BetterScroll receives plugin options, native mode emits when the bottom threshold is reached. |
pullUpThreshold | number | 0 | Native distance-to-bottom threshold and BetterScroll plugin threshold for pulling-up. |
options | Record<string, unknown> | {} | Extra BetterScroll options; wheelOvershoot is consumed locally before options are passed through; on macOS, when wheel and bounce are both on, useTransition: false is injected by default — pass useTransition explicitly in options to override. |
Events
| Event | Params | Description |
|---|---|---|
scroll | { scrollTop: number; scrollLeft: number } | Emits absolute scroll offsets from native mode or BetterScroll position updates. |
pulling-down | - | Emits once per pull-down cycle until finishPullDown() is called. |
pulling-up | - | Emits once per pull-up cycle until finishPullUp() is called. |
Slots
| Slot | Description |
|---|---|
default | Main scroll content rendered inside .tx-scroll__content. |
header | Optional content before the default slot. In native mode it is rendered before .tx-scroll__content; in BetterScroll mode it is rendered inside the scroll content. |
footer | Optional content after the default slot, commonly used for load-more status. |
Expose
| Name | Type | Description |
|---|---|---|
nativeScrollRef | Ref<HTMLElement | null> | Native scroll element ref when native mode is active. |
scrollTo(x, y, time?) | (x: number, y: number, time?: number) => void | Scrolls to absolute offsets. BetterScroll mode negates offsets internally and honors time; native mode calls scrollTo(x, y). |
getScrollInfo() | () => TxScrollInfo | Returns current offsets, scroll size, and client size. |
refresh() | () => void | Calls BetterScroll refresh() and updates scrollability state. No-op in native mode. |
finishPullDown() | () => void | Resets native pull-down lock or forwards to BetterScroll finishPullDown() then schedules refresh. |
finishPullUp() | () => void | Resets native pull-up lock or forwards to BetterScroll finishPullUp() then schedules refresh. |
Behavior Notes
- BetterScroll Mode
- Supports
bouncewith a more consistent scrollbar appearance - Content/container changes auto
refresh()(configurable viarefreshOnContentChange)
- Supports
- Native Mode
- Uses native browser scrolling
directionmaps tooverflow-x/yto keep structure consistent- macOS Safari uses native scrolling directly
- Automatically falls back to native scrolling on macOS + Chromium
145+(Chromium already supports it natively) - Set
unified=trueto force BetterScroll takeover across environments
Runtime Strategy (Priority)
native=true: always use native scrolling (highest priority).unified=true: always let BetterScroll take over (consistent cross-environment behavior).- Running on macOS Safari: use native scrolling directly.
nativeAutoFallback=trueandmacOS + Chromium >= 145: auto switch to native scrolling.- Otherwise: use BetterScroll.
Direction and Scrollbar
Scroll (horizontal)
Loading demo...
Scroll (bounce + always show scrollbar)
Loading demo...
Scroll Chaining (Advanced)
By default inner scrolling does not propagate to the outer container (even at edges). Enable scrollChaining if you want scroll to bubble at the top/bottom.
⚠️ We do not recommend enabling
scrollChainingby default. In nested scrolling layouts, it can make users unsure which layer is actually scrolling. Enable it only when parent-child scroll handoff is explicitly required.
Scroll (scroll chaining, advanced)
Loading demo...
Use Native Scrolling
If you do not need BetterScroll behavior, switch to native scrolling (keeps the same container structure).
Scroll (native)
Loading demo...
Pull-to-Refresh and Load More
- Pull-to-refresh: enable
pullDownRefresh, listen to@pulling-down, then callfinishPullDown()when done. - Load more: enable
pullUpLoad, listen to@pulling-up, then callfinishPullUp()when done. - In
native=trueor auto-native fallback mode, events are degraded triggers;pullDownStoponly works in BetterScroll mode.
Scroll (pull down + pull up)
Loading demo...
Overview
native=truealways wins. Otherwise,unified=trueforces BetterScroll; macOS Safari and macOS Chromium with native overscroll support use native mode unless unified is set.- In native mode,
directionmaps to CSS overflow andscrollChaining=falsemaps tooverscroll-behavior: containon enabled axes. - In BetterScroll mode,
directionmaps toscrollX,scrollY, andfreeScroll;probeTypecontrols scroll event frequency. - Content and wrapper resize changes are coalesced into one animation frame before
refresh();refreshOnContentChange=falsedisables mutation-observer refreshes but keeps resize refreshes. - Pull-down / pull-up events are locked after emission. Consumers must call
finishPullDown()/finishPullUp()after async work to allow the next cycle. - Native pull-down is a thresholded touch fallback at scrollTop 0;
pullDownStopapplies only to BetterScroll mode.
Technologies
- Runtime contract:
native=truealways wins; otherwiseunified=trueforces BetterScroll, while macOS Safari and supported macOS Chromium default to native fallback. - Axis contract: native mode maps
directionto CSS overflow andoverscroll-behavior; BetterScroll maps it toscrollX,scrollY, andfreeScroll. - Refresh contract: resize and content mutations are coalesced before
refresh(). Pull-down/up events are lock-based and requirefinishPullDown()/finishPullUp()after async work. - Verified coverage:
scroll.test.tscovers native overflow, slots, scroll events,getScrollInfo(),scrollTo(), native pull locks, and coalesced refreshes;scroll-export.test.tsprotects the public export boundary. - Component source:
packages/tuffex/packages/components/src/scroll/src/TxScroll.vue. - Runtime helpers:
packages/tuffex/packages/components/src/scroll/src/scroll-wheel.ts,better-scroll-pull-plugins.ts, andruntime-capabilities.ts. - Types:
packages/tuffex/packages/components/src/scroll/src/types.ts. - Coverage:
packages/tuffex/packages/components/src/scroll/__tests__/scroll.test.tsverifies native direction overflow, slots, scroll events,getScrollInfo(),scrollTo(), native pull locks, and coalesced BetterScroll refreshes.scroll-export.test.tsverifies the public export boundary.
查看源码
packages/tuffex/packages/components/src/scroll/index.ts