Flicker-free mobile formatting toolbar: CSS variables + VirtualKeyboard API #2616
Movm
started this conversation in
Ideas & Enhancements
Replies: 1 comment 1 reply
-
|
Seems great, thanks for the write up. Would gladly incorporate this as long as it also has iOS safari support. Looking fwd to a PR! |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
We built an alternative mobile formatting toolbar positioning approach that eliminates the flickering from
ExperimentalMobileFormattingToolbarController. We're using it in production with BlockNote v0.47.3 and would be happy to contribute it as a PR.Problem
The current
ExperimentalMobileFormattingToolbarController(introduced in #1284) uses React state (setTransform) on everyvisualViewportevent. Each state update triggers a React re-render, causing visible flickering as noted in the code comments. This also relates to:Approach: Industry-standard
visualViewport+ CSS variableInstead of React state, we update a CSS custom property directly on the DOM — zero re-renders, the browser compositor handles repositioning.
Tier 1: VirtualKeyboard API (Chrome/Edge 94+, Samsung Internet)
Gives exact keyboard geometry with no delay — toolbar is positioned before the keyboard animation starts:
Tier 2: Visual Viewport API fallback (Safari iOS, Firefox)
The industry-standard approach with focus-based prediction for the initial keyboard open:
CSS
Key differences from current implementation
ExperimentalMobileFormattingToolbarControllersetTransform()→ React state → re-renderstyle.setProperty()→ CSS variable → compositorwindow.innerHeightonlyvisualViewport.offsetTopper standardenv(safe-area-inset-bottom)touch-action: noneprevents scroll interference150ms ease-out(smooth slide, only needed on fallback path)Browser support
What major editors do
position: fixed+visualViewportresizevisualViewport(tiptap#6571)InputAccessoryView(not a web problem)Contribution
Happy to submit a PR with a
MobileFormattingToolbarControllercomponent inpackages/react/src/components/FormattingToolbar/. Would keep the existing experimental controller untouched. Can coordinate with #2591 (portal floating UI to body) if needed.We've been testing this in production on Android Chrome and Samsung Internet — works smoothly. iOS Safari testing is pending but the Visual Viewport fallback follows the established pattern.
Beta Was this translation helpful? Give feedback.
All reactions