webview

2 posts

daangn

Improving the iOS WebView Input Experience for (opens in new tab)

iOS WebViews can shift the entire page upward when an input receives focus, disrupting users as the virtual keyboard appears. The post describes four progressively refined approaches, ultimately using a single input whose opacity is temporarily set to zero before focus. This avoids iOS’s automatic scroll behavior, though it remains a fragile, version-dependent workaround best reserved for input-critical screens. ## Understanding the iOS WebView Problem - iOS uses two viewport concepts: - **Layout Viewport:** The CSS layout area, which does not shrink when the keyboard opens. - **Visual Viewport:** The area visible to the user, which becomes smaller. - Because the focused input must remain visible above the keyboard, iOS shifts the page upward. - The resulting movement can push important content off-screen, and WebView code cannot fully control this behavior. ## Attempt 1: Restore the Scroll Position - The first approach listened for `visualViewport` `resize` and `scroll` events. - It reduced the wrapper’s height by the keyboard height and called `window.scrollTo(0, 0)`. - This failed because iOS moved the page before the event handler could restore it. - Users saw flickering and shaking as multiple resize events triggered repeated corrections. ## Attempt 2: Follow `offsetTop` - Instead of undoing the movement, the implementation followed it. - `visualViewport.offsetTop` was used to adjust a fixed wrapper’s `top` position. - A short delay was required because iOS updates `offsetTop` asynchronously. - This reduced the visible jump but still caused subtle shaking while the keyboard animated. - Rapidly switching inputs or opening and closing the keyboard made the instability more noticeable. ## Attempt 3: Fake and Real Input Swap - This approach prevented iOS from scrolling to the focused input by focusing a real input positioned off-screen. - A visible, read-only “fake” input received the user’s tap, then focused the hidden real input. - Once the keyboard appeared, the two inputs were swapped so the real input became visible. - The page no longer experienced major upward movement. - However, two inputs required synchronization of values, selection, placeholders, textarea sizing, mentions, and emojis. - Swap timing, keyboard detection, and native bridge dependencies made the implementation increasingly complex. ## Attempt 4: Temporarily Hide the Input with Opacity - The final approach kept only one input. - On `touchstart`, the input’s `opacity` was set to `0` before calling `focus()`. - iOS appeared not to perform its automatic scroll-into-view behavior for an invisible input. - After detecting that the keyboard had opened—using the visual viewport and a keyboard-height threshold—the input’s opacity was restored to `1`. - This preserved the input’s state and avoided synchronization problems. - The technique is still a hack: behavior may change across iOS versions, and it can cause minor timing issues. The recommended compromise is to apply the opacity workaround selectively on pages where writing is central to the experience, rather than across the entire WebView application. It prioritizes uninterrupted user interaction despite the lack of a clean, standard iOS API.

figma

Introducing BrowserView for Electron | Figma Blog (opens in new tab)

Figma introduced BrowserView for Electron to address the performance, stability, and feature bugs it experienced with `<webview>`. BrowserView embeds web apps at the operating-system window level, similar to Chrome tabs, allowing them to perform more like native Chrome content. Although it requires manual positioning and layering, Figma found the trade-off worthwhile and shipped it in Figma Desktop 2.0. ## Why Figma Chose Electron - Figma uses the web to make its design tools broadly accessible. - Its desktop app is built with Electron, extending the web experience to desktop platforms. - Figma had already improved performance through technologies such as WebGL and WebAssembly. - The company also contributed fixes and improvements to Electron and Chromium. ## Problems with `<webview>` - Electron commonly uses `<webview>` to embed remote web applications. - Unlike an iframe, a webview renders content in a separate process, improving security, stability, and performance. - Over time, Figma encountered: - Drag-and-drop bugs - Performance below that of Chrome - Other fundamental reliability issues - Because webview is implemented inside Chromium, fixing its underlying problems would require major Chromium changes. - Figma and Electron maintainers therefore chose to develop an alternative rather than continue waiting for Chromium fixes. ## How BrowserView Works - `<webview>` exists within the page’s DOM hierarchy. - BrowserView lives in the operating system’s window hierarchy, much like Chrome’s browser tabs. - This design benefits from the more mature and actively maintained code paths used for Chrome tabs. - BrowserView eliminates many webview-specific bugs. - Applications embedded through BrowserView can perform similarly to applications running directly in Chrome. ## Trade-offs and Adoption - BrowserViews cannot be positioned or layered using ordinary HTML and CSS. - Developers must manually manage their size, location, and stacking order. - This can be difficult for applications with complex interfaces. - For Figma, converting to BrowserView was relatively straightforward. - At the time of publication, BrowserView was experimental and still planned for further refinement. Figma recommends BrowserView as a promising replacement for `<webview>` when improved performance and reliability outweigh the added layout complexity.