native_web_scroll
Web‑native scrolling for Flutter Web with a single ScrollController.
- Syncs a Flutter
ScrollControllerwith a real DOM scroller behind your content. - Preserves native browser behavior (momentum, accessibility, OS settings).
- Works everywhere: on Web it uses DOM; elsewhere it behaves like a normal controller.
- Also fixes scroll issues with
Draggablein Telegram and other in‑app browsers by relying on native DOM scrolling and proper wheel event handling.
Why use this
- You want native browser scrolling feel on Web.
- You need one
ScrollControllerfor both programmatic control and user scrolling. - You hit odd scroll behavior (e.g. jitter with
Draggableinside in‑app browsers).
Platform support
- Web: native DOM scrolling via
HtmlElementView. - Android/iOS/macOS/Windows/Linux: falls back to a regular
ScrollController.
Quick start
import 'package:native_web_scroll/native_web_scroll.dart';
NativeScrollBuilder(
builder: (context, scrollController) => ListView.builder(
controller: scrollController,
itemCount: 100,
itemBuilder: (context, i) => Text('Item $i'),
);
);
How it works (Web)
- Registers a platform view and renders an HTML
<div>with scroll overflow. - Mirrors scroll position between the DOM and the Flutter
ScrollController(both ways), avoiding feedback loops. - Updates a spacer element to reflect
viewport + maxScrollExtent, reducing drift when content size changes.
Notes
- Flutter vs browser scrollbars:
hideFlutterScrollbarshides only Flutter’s scrollbars. Native browser scrollbars are unaffected. - In‑app browsers (e.g., Telegram):
stopWheelPropagation: truehelps avoid nested scroll conflicts and improvesDraggableinteraction. - Dynamic layouts: for external initial offsets, set them in a post‑frame callback (
jumpTo/animateTo) after the controller has clients.
Troubleshooting
- Double scrollbars: set
hideFlutterScrollbars: true(or hide native DOM scrollbars via CSS if you prefer Flutter’s). - Jumps/drift after layout changes: ensure the controller has clients, then
jumpTo/animateToin a post‑frame callback. - Nested scroll conflicts: keep
stopWheelPropagation: trueor tune per layout.
Libraries
- native_web_scroll
- Public entrypoint that conditionally exports the platform implementation.