Repository navigation
[Bug]: Android inline HTML traps chat scrolling when its content overflows #16989
Description
Activity
Note
Grok responding on behalf of Julius.
Thanks for the careful write-up and the one-variable probe. I checked it against current
main(3143335). Your tested commit26285abis 7 commits behind main, andHtmlRenderWebView.tsxhasn't changed since the inline HTML feature landed (#15968).Confirmed in code, not reproduced here. I didn't run the app or open the attached archive or recording.
Why the gesture gets trapped
- In the feed, the WebView reports whether the page overflows its frame. The overflow script flags overflow when the page is taller or wider than the window. Once it reports overflow,
scrollableturns on bothscrollEnabledandnestedScrollEnabled:const scrollable = !props.nested || overflows; scrollEnabled={scrollable} nestedScrollEnabled={props.nested && overflows}
- Main pins
react-native-webviewat14.0.1(apps/mobile/package.jsonand the lockfile), and the repo doesn't patch it. In that version,RNCWebView.onTouchEventcallsrequestDisallowInterceptTouchEvent(true)on every touch whenevernestedScrollEnabledis set. It doesn't check direction or whether the page is at a scroll edge. That call tells ancestor views not to intercept the gesture, so once overflow is reported, a vertical swipe that starts on the page never reaches the feed's list, even at the page's top or bottom. - Because the overflow check also counts horizontal overflow, a page that's only too wide (for example a wide table) gets the same treatment, and vertical swipes on it are trapped too.
- The feed is a
KeyboardAwareLegendListthat rendersThreadHtmlRenderrows. Neither the row norHtmlRenderWebViewhas any gesture handling that would pass the swipe back at the edges.
This matches your probe: turning off only
nestedScrollEnabledlet swipes on the page move the chat.Why it overflows at 320dp and not at about 443dp (what the code shows)
- The frame is a fixed height from
htmlRenderFrameHeight(render, frameWidth), and the same value sizes the row (ThreadFeed.tsx#L2931). Mobile passes no page-reported height, so the frame comes only from the server's publish-time measurements, or the agent'sheightwhen there are none. frameWidthis the viewport minus the feed's padding, at least 16dp per side outside the split layout (ThreadFeed.tsx#L2257-L2263). A 320dp screen gives 288, which matches your ~288dp.- The server measures at widths starting at 320. For a width below 320,
measuredHeightfalls back to the 320 measurement. A page that wraps taller (or doesn't fit horizontally) at 288 than at 320 then overflows its frame. At about 443dp the frame is around 411 wide, which lies between the measured 375 and 430 widths, and the frame takes the taller of those two heights. - Separately,
htmlRenderFrameHeightcaps the frame at the agent'sheight(582 here) when the page measured taller than that at the 728 column width. Pages over the 2000px max are capped as well. Either case gives an intentionally scrolling frame at any width. - I haven't checked which of these applies to your page. That needs the page's metadata, and I didn't open the archive. It also doesn't explain the physical Pixel 10 Fold at default settings, which (as you note) is still open.
Fix options (not choosing one here)
- Hand the gesture back at the edges and by direction. Only keep the touch while the page can still scroll in the swipe's direction. That could be native (a patch or a subclass that calls
requestDisallowInterceptTouchEventconditionally) or driven from JS using the page's scroll position. It keeps scrollable inline pages. - Split vertical and horizontal overflow. Don't enable nested scrolling for vertical swipes when the page only overflows horizontally.
- Avoid unintended overflow. Measure at a width below 320, or pass the page's reported height on mobile as web does, so pages that are meant to fit actually fit.
- Don't nest-scroll inline at all. For example, only scroll after the reader taps or focuses the page, or show a non-scrolling preview and use the existing open-full-screen button for scrolling. This one is a product/UX call.
Options 1–3 fix code behavior. Option 4 is the same question as #16977.
Workaround: as you found, swipe in the gutter beside the page, or open the page full screen with the expand button.
Related
- [Bug]: Wheel scroll stays stuck on a tall inline HTML render instead of chaining to the thread #16977 (open): the desktop/web version of the same symptom, where a wheel gesture stays stuck in a tall inline render. The mechanism there is different (a browser iframe and wheel latching, not Android touch interception), but it raises the same product question about inline frames that scroll internally.
- feat: minimize inline HTML renders #16420 (open PR): minimize inline renders. It touches
HtmlRenderWebView.tsxbut doesn't change the scroll or overflow props. - [Bug][Mobile] Android: scrolling a long, settled thread is janky #13925, Raw HTML in markdown renders as source text on mobile #7929 and [Bug][Mobile]: Markdown table columns are a fixed 160dp width, so long cells wrap into narrow tall columns #15524 are different problems: long-thread jank, raw HTML in markdown, and markdown table column widths.
- In the feed, the WebView reports whether the page overflows its frame. The overflow script flags overflow when the page is taller or wider than the window. Once it reports overflow,
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Oct 7, 2026 Note
Grok responding on behalf of Julius.
This is fixed by #17211, which just landed on
main. On Android, overflowing inline HTML pages now hand vertical swipes back to the thread once the page can't scroll further in that direction, and pages that only overflow horizontally no longer hold vertical drags. Closing as completed. If you still see the trap on a build that includes #17211, please reopen with details.
Summary
In the native Android app, an overflowing inline HTML page captures vertical swipes that should let the reader continue through the conversation. Swipes starting inside the HTML do not move the chat, including when the page cannot scroll farther in that direction. Swiping the narrow gutter beside the page moves the chat normally. A large HTML page can occupy almost the entire chat viewport, making the conversation feel locked.
The original report is from a Pixel 10 Fold with no known increase in system text or display size. The same HTML reproduced the problem in a Pixel 10 Pro Fold emulator at a forced 320dp layout width. It did not reproduce at the emulator's default width of about 443dp. The reproduction confirms the gesture trap, but does not yet establish why the original phone reaches the overflow condition at its normal settings.
Area
apps/mobile/ Android / inline HTML in the thread feed.Steps to reproduce
original.htmlandrender-metadata.jsonfrom the attached reproduction archive. Render the HTML as an inline HTML tool result, with ordinary assistant text following it. The original result used a height of 582 and the responsive heights in the metadata file.adb shell wm density 540produced that layout;adb shell wm density resetrestores its default density.Also try the case where the HTML fills the available chat viewport, shown below. The usable gutter becomes easy to miss.
Expected behavior
Vertical swipes over inline HTML should allow conversation scrolling when the embedded page cannot consume the movement, including at its scroll boundaries. Readers should be able to move past a large inline page without finding a narrow gutter.
Actual behavior
The HTML keeps the gesture and the parent chat stays still. A gutter swipe immediately moves the conversation.
A controlled test measured the vertical position of the same assistant text before and after a 250px downward pan:
nestedScrollEnabledtemporarily set tofalseThe recording used longer, 450px pans and showed the same behavior: 0px of chat movement inside the HTML, then 487px from the gutter. The temporary probe was reverted. No fix has been made.
Screenshots and recording
Play the recording (MP4, about 23 seconds).
The conversation stays in the same position during the inside-HTML swipe in the first part of the recording. Around 16–19 seconds, a gutter swipe moves it. The final gutter swipe returns it to the starting position. Gesture locations are described here because the recording does not display a touch pointer.
After the inside-HTML swipe: the following assistant text remains in place.
After the gutter swipe: the following assistant text has moved downward and earlier table content is visible.
Large-page case: the HTML occupies nearly the whole chat viewport.
Default-width screenshot, where this HTML scrolled normally.
Likely cause
HtmlRenderWebView.tsx reports either vertical or horizontal overflow. Overflow enables
scrollEnabledandnestedScrollEnabledfor the inline WebView.In the installed
react-native-webview14.0.1 Android implementation,RNCWebView.onTouchEventcallsrequestDisallowInterceptTouchEvent(true)whenevernestedScrollEnabledis enabled. This prevents the parent from taking the gesture even at a scroll boundary. Horizontal-only overflow can also enable this behavior for vertical swipes.The attached HTML consists of two static tables and contains no scripts or touch-event handlers. The one-variable probe above supports WebView gesture interception as the cause. Disabling nested scrolling was a diagnostic probe; a fix still needs to preserve useful interaction with overflowing HTML.
Impact and workaround
Major degradation when a large inline page fills the chat viewport. Swipe the side gutter outside the HTML to move the conversation.
Version and environment
26285ab80513260d1ff29d2c3fbe18f21990cb62.2.0.0.The Linux native build initially packaged a host Oniguruma library. A disposable APK was repaired to use the dependency's Android library and re-signed for testing. The baseline HTML component and WebView dependency were unchanged. This evidence is from a development build, not a verified reproduction on the Play Store build.
Existing reports
Searches of public issues, recent discussions, and the inline HTML feature's review comments did not find an exact duplicate. Issue #13925: Android scrolling a long, settled thread is janky concerns a related scrolling symptom, with a different reported cause involving text mounting in long threads.
Follow-up
If this issue is marked Approved or Verified, we can implement a fix and open a pull request for review.