demo · v138

Proportional chrome

A user at +200% OS font scale shouldn’t end up with 32-pixel text crammed into 24-pixel buttons. Use env(preferred-text-scale) in calc() to scale spacing, icons, and chrome by the same factor as text — not just type.

checking support…
1.00×

// reads env(preferred-text-scale, 1) first; the slider multiplies it.

text-only scale (the anti-pattern)

Account settings

As text grows, the button border, padding, and icon stay tiny. Hit targets shrink relative to the visible word, which fails WCAG 2.5.5.

proportional chrome (the fix)

Account settings

Everything multiplies by the same factor — padding, icon, gap, card margin. The button stays touch-friendly. The card breathes.

the trick

:root { --scale: env(preferred-text-scale, 1); }

.button {
  font-size:   calc(0.85rem * var(--scale));
  padding:     calc(0.4rem * var(--scale)) calc(0.8rem * var(--scale));
  border-width: calc(2px * var(--scale));
  gap:         calc(0.4rem * var(--scale));
}
.icon { width: calc(16px * var(--scale)); height: calc(16px * var(--scale)); }

The OS-level scale was, until 138, only readable via JavaScript user-agent hints — if at all. Sites either ignored it (resulting in unreadable text for low-vision users), or used rem alone (which scales type but not chrome, breaking touch targets). env(preferred-text-scale) exposes the value in CSS so the whole layout can stay proportional.

see also