Kundenansicht neu E-Fix M4: Mitarbeiter-Banner verschiebt Blatt und Menü nicht mehr unter den Kopf

Der Banner stand im Fluss (relative) und schob den Kopf nach unten, das am Handy feste Blatt begann aber fest bei der Kopfhöhe: es deckte den
unteren Teil des Kopfs samt Profilbild ab (Konto und Abmelden nicht erreichbar); am Desktop blieb das Menü bei fest 36 px stehen, der Banner
ist aber 40 px hoch und beim Scrollen blieb eine Lücke. Jetzt bleibt der Banner oben stehen (sticky), huelle.js setzt --kn-banner-h auf seine
Höhe (auch bei Umbruch am Handy), und Kopf, Menü, Blatt und Konto-Popover beginnen darunter. Werkzeug-Ansicht kn-huelle-banner-blatt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-16 21:43:20 +00:00
1 parent 4c64edc057
commit f8962ffa50
3 files changed
+23 -7

No files matched your search

+6 -7
View File
@@ -21,7 +21,7 @@
@media (max-width: 880px), (pointer: coarse) and (max-height: 500px) {
.kn { --kn-unten: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom)); }
.kn-blatt {
position: fixed; inset: calc(var(--kn-kopf-h) + env(safe-area-inset-top)) 0 var(--kn-unten, var(--kn-zeile-h)); z-index: 20;
position: fixed; inset: calc(var(--kn-banner-h) + var(--kn-kopf-h) + env(safe-area-inset-top)) 0 var(--kn-unten, var(--kn-zeile-h)); z-index: 20;
overflow-y: auto; overscroll-behavior: contain; border-radius: 12px 12px 0 0;
box-shadow: 0 0 0 1px rgba(26,31,54,.06), 0 -8px 24px rgba(26,31,54,.1);
transform: translateY(100%); transition: transform 550ms var(--kn-bremse);
@@ -55,7 +55,7 @@
.kn-konto-wurzel { position: fixed; inset: 0; z-index: 60; }
.kn-konto-wurzel:focus { outline: none; } /* tabindex -1: ein Tipp ins Leere behält die Tasten (Esc, Tab) im Sheet */
.kn-konto-scrim { position: absolute; inset: 0; background: transparent; }
.kn-konto { position: absolute; top: 56px; right: 24px; width: 280px; max-height: calc(100vh - 72px); padding: 8px 20px; overflow-y: auto; overscroll-behavior: contain; background: var(--kn-bg); border-radius: var(--kn-radius-lg); box-shadow: var(--kn-shadow-pop); animation: kn-aufpoppen .14s ease-out; }
.kn-konto { position: absolute; top: calc(var(--kn-banner-h) + 56px); right: 24px; width: 280px; max-height: calc(100vh - 72px); padding: 8px 20px; overflow-y: auto; overscroll-behavior: contain; background: var(--kn-bg); border-radius: var(--kn-radius-lg); box-shadow: var(--kn-shadow-pop); animation: kn-aufpoppen .14s ease-out; }
.kn-konto-kopf { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 12px; padding: 8px 0 12px; border-bottom: 1px solid var(--kn-line); }
.kn-konto-kopf > div { display: contents; } /* Name neben „Schließen“, die Mail darunter über die volle Breite */
.kn-konto-name { grid-column: 1; grid-row: 1; display: block; font-size: 17px; line-height: 24px; font-weight: 600; overflow-wrap: anywhere; }
@@ -88,18 +88,17 @@
/* ---------- Gerüst: Spalte, Inhalt, Menü (Desktop) und Kopf ---------- */
.kn { --kn-kopf-h: 52px; }
.kn { --kn-kopf-h: 52px; --kn-banner-h: 0px; } /* --kn-banner-h setzt huelle.js auf die Höhe des Mitarbeiter-Banners (E-Fix M4): Kopf, Menü, Blatt und Konto beginnen darunter */
.kn-skip { position: absolute; top: -48px; left: 8px; z-index: 100; padding: 8px 12px; border-radius: var(--kn-radius); background: var(--kn-accent); color: #fff; font-weight: 600; }
.kn-skip:focus { top: 8px; }
.kn-nur-leser { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.kn-banner { position: relative; z-index: 30; display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 36px; padding: 6px max(16px, env(safe-area-inset-right)) 6px max(16px, env(safe-area-inset-left)); background: var(--kn-accent); color: #fff; font-size: 13px; line-height: 20px; }
.kn-banner { position: sticky; top: 0; z-index: 50; display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 36px; padding: 6px max(16px, env(safe-area-inset-right)) 6px max(16px, env(safe-area-inset-left)); background: var(--kn-accent); color: #fff; font-size: 13px; line-height: 20px; }
.kn-banner > span { min-width: 0; overflow-wrap: anywhere; }
.kn-banner button { flex: none; min-height: 28px; padding: 0 4px; color: #fff; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.kn-banner:not([hidden]) ~ .kn-huelle .kn-menue { top: 36px; }
.kn-menue { position: fixed; inset: 0 auto 0 0; z-index: 20; display: flex; flex-direction: column; gap: 2px; width: var(--kn-sidebar-w); padding: 20px 12px; overflow-y: auto; border-right: 1px solid var(--kn-line); background: var(--kn-bg); }
.kn-menue { position: fixed; inset: var(--kn-banner-h) auto 0 0; z-index: 20; display: flex; flex-direction: column; gap: 2px; width: var(--kn-sidebar-w); padding: 20px 12px; overflow-y: auto; border-right: 1px solid var(--kn-line); background: var(--kn-bg); }
.kn-marke { padding: 0 10px 16px; font-size: 15px; line-height: 24px; font-weight: 600; }
.kn-nav-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; padding: 6px 10px; border-radius: var(--kn-radius); font-size: 14px; line-height: 20px; font-weight: 500; color: var(--kn-text-2); text-align: left; }
.kn-nav-item:hover { background: var(--kn-bg-hover); color: var(--kn-text); }
@@ -108,7 +107,7 @@
.kn-nav-zahl--heiss { color: var(--kn-rot-fg); font-weight: 600; }
.kn-spalte { position: relative; min-height: 100vh; margin-left: var(--kn-sidebar-w); }
.kn-kopf { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; justify-content: flex-end; height: var(--kn-kopf-h); margin-bottom: calc(0px - var(--kn-kopf-h)); padding: 0 24px; pointer-events: none; } /* Desktop: nur das Profilbild, bleibt beim Scrollen oben rechts und schiebt den Inhalt nicht */
.kn-kopf { position: sticky; top: var(--kn-banner-h); z-index: 10; display: flex; align-items: center; justify-content: flex-end; height: var(--kn-kopf-h); margin-bottom: calc(0px - var(--kn-kopf-h)); padding: 0 24px; pointer-events: none; } /* Desktop: nur das Profilbild, bleibt beim Scrollen oben rechts und schiebt den Inhalt nicht */
.kn-kopf > * { pointer-events: auto; }
.kn-kopf-titel { display: none; }
.kn-haupt, .kn-blatt { max-width: 1160px; padding: 36px 48px 80px; }
+5
View File
@@ -144,6 +144,11 @@ export async function starteHuelle({ win = window, doc = document, api = apiStan
}
leeren(banner).append(h('span', null, 'Kundenansicht: ', h('strong', null, kunde.name || 'Kunde'), ` · geöffnet von ${admin?.name || 'Mitarbeiter'}`), h('button', { type: 'button', on: { click: beenden } }, 'Beenden'))
banner.hidden = false
// Höhe des Banners für Kopf, Menü, Blatt und Konto (E-Fix M4: --kn-banner-h). Der Banner bleibt oben stehen (sticky) und wird am Handy zweizeilig.
const setzeHoehe = () => doc.body.style?.setProperty?.('--kn-banner-h', `${banner.offsetHeight || 0}px`)
setzeHoehe()
if (typeof win.ResizeObserver === 'function') new win.ResizeObserver(setzeHoehe).observe(banner)
else win.addEventListener('resize', setzeHoehe)
}
// 3. Scroll: Stand je Route merken, Kopf (Rand, kleiner Titel) nachführen
+12
View File
@@ -75,3 +75,15 @@ test('M3: die Fehlertexte der öffentlichen Seiten (Login, Kündigen, Widerrufen
assert.match(zeile, /role="alert"/, `${datei}: ${zeile}`)
}
})
test('M4: der Mitarbeiter-Banner steht oben (sticky), Kopf, Menü, Blatt und Konto beginnen um seine Höhe (--kn-banner-h) darunter', () => {
assert.match(HUELLE, /\.kn \{[^}]*--kn-banner-h:\s*0px/)
assert.match(HUELLE, /\.kn-banner \{[^}]*position:\s*sticky;[^}]*top:\s*0/)
assert.match(HUELLE, /\.kn-menue \{[^}]*inset:\s*var\(--kn-banner-h\) auto 0 0/)
assert.match(HUELLE, /\.kn-kopf \{[^}]*position:\s*sticky;\s*top:\s*var\(--kn-banner-h\)/)
assert.match(HUELLE, /\.kn-blatt \{[^}]*inset:\s*calc\(var\(--kn-banner-h\) \+ var\(--kn-kopf-h\) \+ env\(safe-area-inset-top\)\)/)
assert.match(HUELLE, /\.kn-konto \{[^}]*top:\s*calc\(var\(--kn-banner-h\) \+ 56px\)/)
assert.doesNotMatch(HUELLE, /\.kn-banner:not\(\[hidden\]\) ~ \.kn-huelle \.kn-menue/, 'die feste Höhe 36 px ist weg')
const js = quelle('huelle.js')
assert.match(js, /setProperty\?\.\('--kn-banner-h'/)
})