Stop iOS zooming the page on every tap into a field
Safari zooms when a focused input is smaller than 16px, and then leaves the page zoomed — so on an iPhone every form throws the layout about, and the way back is a pinch. The usual fix is the meta-viewport switch, which suppresses the zoom by disabling pinch-zoom entirely: it takes a real accessibility feature away from everyone to solve a cosmetic problem for some. Sizing the fields at 16px on touch devices removes the reason instead. !important on purpose: it has to beat every text-size utility on every field in the application, and a rule that loses to `text-sm` on one form is worth nothing. Checkboxes and radios are left alone — no text to inflate, and sizing them there breaks the box. Also -webkit-text-size-adjust, so iOS stops inflating body copy in landscape. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>feat/portal-design tested-20260727-1306-be082b7
parent
b85c12e8b9
commit
be082b7bf9
|
|
@ -24,6 +24,8 @@
|
|||
font-family: var(--font-sans);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
/* Stops iOS inflating body text when the phone is turned to landscape. */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
@ -51,6 +53,69 @@
|
|||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* Registration marks — the corner crosses on a printed form. A pseudo
|
||||
element rather than markup: they are decoration, and a screen reader
|
||||
announcing "plus, plus" on every panel would be noise. Tailwind cannot
|
||||
express ::before content, so this is the one place it lives in CSS. */
|
||||
.doc-marks {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.doc-marks::before,
|
||||
.doc-marks::after {
|
||||
content: "+";
|
||||
position: absolute;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
line-height: 1;
|
||||
color: var(--border-strong);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.doc-marks::before {
|
||||
top: -6px;
|
||||
left: -6px;
|
||||
}
|
||||
|
||||
.doc-marks::after {
|
||||
bottom: -6px;
|
||||
right: -6px;
|
||||
}
|
||||
|
||||
/* The rule that precedes an eyebrow label, in the accent. Same reasoning:
|
||||
decorative, and it has to sit on the text baseline of a flex row. */
|
||||
.doc-eyebrow::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 22px;
|
||||
height: 1px;
|
||||
background: var(--accent);
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* iOS zooms the whole page when a field smaller than 16px takes focus, and
|
||||
* then leaves the page zoomed — every tap into a form throws the layout about.
|
||||
*
|
||||
* There is no way to decline it: the meta-viewport switch that used to suppress
|
||||
* it also kills pinch-zoom, which takes a genuine accessibility feature away
|
||||
* from everyone to fix a cosmetic problem for some. Making the fields 16px on
|
||||
* touch devices removes the reason instead.
|
||||
*
|
||||
* !important, and deliberately: this has to beat every text-size utility on
|
||||
* every field in the application, and a rule that loses to `text-sm` on one
|
||||
* form is worth nothing. Checkboxes and radios are excluded — they have no text
|
||||
* to inflate and sizing them here would break their box.
|
||||
*/
|
||||
@media (pointer: coarse) {
|
||||
input:not([type='checkbox']):not([type='radio']),
|
||||
select,
|
||||
textarea {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
|
|
|
|||
Loading…
Reference in New Issue