fix(mobile): suppress iOS Safari auto-zoom on every input + contenteditable

iOS Safari auto-zooms (and shifts the viewport right) on focus when the
computed font-size is <16px. Single @media (max-width: 767px) block in
globals.css covers all four input tiers, every relevant bare <input>
type, <textarea>, <select>, and contenteditable surfaces. `!important`
is required because Tailwind utilities (text-[15px] on the chat composer,
text-sm on form fields) emit after @layer components and would otherwise
override the input-tier rules.

Replaces ad-hoc per-input `text-base md:text-sm` overrides with a single
global truth. New inputs/contenteditables get the fix for free.

Spec: docs/systems/design-system.md gains an "iOS Auto-Zoom Suppression"
section under Input Tiers.
This commit is contained in:
Jannis Braun
2026-05-07 22:59:41 +02:00
parent fb9fe326c4
commit f733e39b4a
2 changed files with 38 additions and 0 deletions
+8
View File
@@ -96,6 +96,14 @@ All defined in `globals.css`. No resting border — sunken `surface-input` backg
Override padding/size with utilities: `input-standard w-full py-2.5`
### iOS Auto-Zoom Suppression
iOS Safari auto-zooms (and shifts the viewport right) on input focus when the computed `font-size` is below 16px. The `@media (max-width: 767px)` block in `globals.css` bumps every input tier — and bare `<input>`/`<textarea>`/`<select>` plus `[contenteditable]` — to `font-size: 16px !important`.
`!important` is required because Tailwind utilities like `text-[15px]` (used on the chat composer textarea) and `text-sm` (used on form fields) are emitted in the `@layer utilities` block, which comes after `@layer components` in the cascade and would otherwise override the input-tier rules. There is no legitimate reason to use a `<16px` font-size on a mobile input, so the override is universally correct.
When introducing a new input or contenteditable surface, no extra work is needed — the global rule covers it.
---
## Layout
+30
View File
@@ -244,6 +244,36 @@
focus:ring-2 focus:ring-accent-rose focus:border-accent-rose/30
transition-colors;
}
/* iOS Safari auto-zooms on input focus when computed font-size is below
16px. Bumping every input tier (and bare <input>/<textarea>/<select>)
to 16px on mobile prevents the zoom without changing desktop sizing.
`!important` is required because Tailwind utilities (e.g. `text-[15px]`
on the chat composer textarea, `text-sm` on form fields) are emitted in
the @layer utilities block — which comes after @layer components in the
cascade — so they would otherwise override these rules.
There is no legitimate reason to use a <16px font-size on a mobile
input; the override is universally correct. */
@media (max-width: 767px) {
.input-standard,
.input-search,
.input-embedded,
.input-danger,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="datetime-local"],
textarea,
select,
[contenteditable="true"],
[contenteditable="plaintext-only"] {
font-size: 16px !important;
}
}
}
/* Accessibility: fall back to solid surfaces when transparency is reduced */