Kundenansicht neu: kein Hineinzoomen beim Tippen auf dem iPhone

Messung am iPhone: die Seite ist verkleinert gezeichnet (462 px Breite
auf 393 pt, visualViewport.scale 0,85, wohl Seitenzoom 85 %). Unsere
16-px-Felder haben auf dem Bildschirm dann nur 13,6 pt, iOS zoomt beim
Antippen auf 100 % hinein und danach nicht zurück: Ausschnitt, rechts
abgeschnitten, die Eingabe liegt hinter der Tastatur.

zoom-ausgleich.js setzt auf iOS bei einem Maßstab unter 0,99 die Klasse
kn-zoom-ausgleich und den Faktor 1,01/scale an <html>; huelle.css gibt
dann allen Textfeldern der Kundenansicht 16 px mal Faktor, also auf dem
Bildschirm wieder 16 pt. Nie umgestellt, während ein Feld den Fokus
hat. Bei 100 % ändert sich nichts (Chromium: pixelgleich zu main).
Die Messung meldet zusätzlich Maßstab (3 Stellen), Faktor, Seitenbreite
und Schriftgröße des Feldes im Fokus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-29 11:30:56 +00:00
1 parent 17bce304eb
commit 1a09bebe41
6 files changed
+99 -5

No files matched your search

+46
View File
@@ -0,0 +1,46 @@
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { ausgleichFaktor, beobachteZoom } from '../public/neu/zoom-ausgleich.js'
import { lies } from './support/knHuelle.js'
test('ausgleichFaktor: 85 % (iPhone 2026-10-29) ergibt 16 px × 1,188 ≈ 16,2 pt auf dem Bildschirm; 100 %, hineingezoomt und Unsinn ergeben 1', () => {
const f = ausgleichFaktor(0.8506)
assert.equal(f, 1.188)
assert.ok(16 * f * 0.8506 >= 16)
assert.equal(ausgleichFaktor(0.5), 2.02)
for (const s of [1, 0.99, 1.5, 0, -1, NaN, undefined]) assert.equal(ausgleichFaktor(s), 1)
})
function aufbau(scale) {
const hoerer = []
const vv = { scale, addEventListener: (t, fn) => hoerer.push(fn), removeEventListener: (t, fn) => hoerer.splice(hoerer.indexOf(fn), 1), feuere: () => hoerer.forEach((fn) => fn()) }
const klassen = new Set(); const stil = {}
const doc = {
activeElement: null,
documentElement: {
classList: { add: (k) => klassen.add(k), remove: (k) => klassen.delete(k) },
style: { setProperty: (k, v) => { stil[k] = v }, removeProperty: (k) => { delete stil[k] } },
},
}
return { vv, doc, klassen, stil, hoerer, win: { visualViewport: vv } }
}
test('beobachteZoom: setzt Klasse und Faktor bei 85 %, nimmt sie bei 100 % weg, ändert nichts während ein Textfeld den Fokus hat', () => {
const t = aufbau(0.8506)
const feld = { feld: true }
const z = beobachteZoom({ win: t.win, doc: t.doc, istTextfeld: (el) => el?.feld === true })
assert.deepEqual([[...t.klassen], t.stil, z.faktor()], [['kn-zoom-ausgleich'], { '--kn-zoom-ausgleich': '1.188' }, 1.188])
t.doc.activeElement = feld; t.vv.scale = 1; t.vv.feuere() // iOS zoomt beim Tippen: nichts umstellen
assert.equal(z.faktor(), 1.188)
t.doc.activeElement = null; t.vv.feuere()
assert.deepEqual([[...t.klassen], t.stil, z.faktor()], [[], {}, 1])
z.beende(); assert.equal(t.hoerer.length, 0)
const ohne = beobachteZoom({ win: {}, doc: t.doc }); assert.equal(ohne.faktor(), 1); ohne.beende()
})
test('huelle.css und huelle.js: Ausgleich nur über die Klasse an <html>, für alle Textfelder der Kundenansicht, nur auf iOS verdrahtet', () => {
const css = lies('huelle.css')
assert.match(css, /\.kn-zoom-ausgleich \.kn :is\(input:not\(\[type="checkbox"\]\)[^{]*, textarea, select\) \{ font-size: calc\(16px \* var\(--kn-zoom-ausgleich, 1\)\) !important; \}/)
const js = lies('huelle.js')
assert.match(js, /const zoom = istIos\(\) \? beobachteZoom\(\{ win, doc, istTextfeld \}\) : null/)
})