fix(web): defense-in-depth against iOS Safari auto-zoom on input focus#2434
fix(web): defense-in-depth against iOS Safari auto-zoom on input focus#2434alecramos-sudo wants to merge 1 commit intopingdotgg:mainfrom
Conversation
Upstream PR pingdotgg#1652 patched the chat composer and sidebar rename input by switching from `text-[14px]` to `text-base sm:text-[14px]`, but that pattern has two failure modes: 1. Any future input/textarea/contenteditable that lands without the `text-base sm:` prefix silently re-introduces the bug. There's no linter rule to catch it. 2. The `sm:` breakpoint is 640px, but iPad and iPhone Pro Max in landscape are wider than 640px while still being touch devices that auto-zoom on focus. The desktop-sized `sm:text-[14px]` kicks in there and the bug returns. This adds a global `@media (hover: none) and (pointer: coarse)` rule that floors all form controls to `max(16px, 1em)` — but ONLY on touch devices. Desktop UIs keep their existing density (Tailwind `text-xs`/`text-sm` classes apply unchanged because the touch media query never matches a mouse-pointer environment). Net effect: iOS Safari (any size, any orientation), iPadOS, and Android phones/tablets never auto-zoom into our inputs. Mouse-pointer macOS, Windows, and Linux are completely unaffected.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Approved CSS-only change that adds a media query to prevent iOS Safari auto-zoom on form inputs. The fix is scoped to touch devices, preserves desktop styling, and has no runtime behavior impact beyond the intended visual fix. You can customize Macroscope's approvability policy. Learn more. |
What Changed
Adds a global
@media (hover: none) and (pointer: coarse)rule inapps/web/src/index.cssthat floors all<input>,<textarea>,<select>, and[contenteditable]elements tofont-size: max(16px, 1em)on touch devices.Why
#1652 (merged) patched two specific components — the chat composer and the sidebar thread-rename input — by switching to
text-base sm:text-[14px]. That's a great per-component fix, but it leaves two failure modes open and #1265 remains reproducible:Other inputs are still vulnerable. Settings text fields, search bars (model picker, branch picker), filter inputs, and any future input added without the
text-base sm:prefix silently re-introduce the bug. There's no linter rule to catch it. Confirmed in [Bug]: Focusing the chat input zooms the app in causing weird scroll on mobile #1265 by another user on a Samsung Galaxy S24 Ultra after fix(web): prevent iOS Safari auto-zoom on input focus #1652 was merged — same auto-zoom on a non-composer input.The
sm:breakpoint is 640px, but iOS still auto-zooms past 640px. iPhone Pro Max in landscape (932px wide) and iPad in any orientation are wider thansm:but are still touch devices that trigger Safari's auto-zoom on focus. Withtext-base sm:text-[14px], those devices get the desktop-sized 14px and the bug returns.Approach
Defense-in-depth at the CSS layer. The media query
(hover: none) and (pointer: coarse)matches any device the browser self-reports as touch-only — regardless of viewport width — and explicitly excludes mouse-pointer environments. So:text-xs/text-sm/text-[14px]density classes apply unchanged → no visual changeUsing
max(16px, 1em)instead of a flat16pxpreserves any intentionally larger font (e.g. heading-style inputs,.dialog-titleeditable headers) while still raising the floor.This complements rather than replaces #1652 — the per-component
text-base sm:text-[14px]pattern inComposerPromptEditor.tsxandSidebar.tsxkeeps working on desktop and stays self-documenting at the component level. The new global rule is a safety net that catches everything else.Why not the other approaches
maximum-scale=1in the viewport meta (orusePreventIosInputZoomfrom fix: prevent iOS composer focus zoom #1562) disables pinch-to-zoom entirely while focused, hurting accessibility.<input>elements would only catch missing classes at write time and wouldn't cover thesm:breakpoint gap on iPad/landscape phones.text-baseeverywhere would change desktop UI density (12-14px is intentional for the sidebar / settings rows).The CSS-scoped media query is the smallest, lowest-risk solution that closes both gaps.
Files
apps/web/src/index.css— +21 lines, no deletions, no formatting changes to surrounding codeVerification
bunx prettier --checkon the new block: clean.(hover: none) and (pointer: coarse)is a well-supported Media Queries Level 4 feature — Safari 9+, all evergreen browsers.Closes / refs
Checklist
Note
Prevent iOS Safari auto-zoom on input focus for touch devices
Adds a CSS media rule in index.css targeting touch devices (
hover: noneandpointer: coarse) that setsfont-size: max(16px, 1em)on allinput,textarea,select, andcontenteditableelements. iOS Safari auto-zooms when an input's font size is below 16px; this rule ensures the minimum is always met without overriding larger sizes.Macroscope summarized 6f857e7.