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:
1 parent
4c64edc057
commit
f8962ffa50
3 files changed
+23
-7
No files matched your search
@@ -21,7 +21,7 @@
|
|||||||
@media (max-width: 880px), (pointer: coarse) and (max-height: 500px) {
|
@media (max-width: 880px), (pointer: coarse) and (max-height: 500px) {
|
||||||
.kn { --kn-unten: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom)); }
|
.kn { --kn-unten: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom)); }
|
||||||
.kn-blatt {
|
.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;
|
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);
|
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);
|
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 { 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-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-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 { 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-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; }
|
.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 ---------- */
|
/* ---------- 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 { 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-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-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 > 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 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-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 { 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); }
|
.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-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-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 > * { pointer-events: auto; }
|
||||||
.kn-kopf-titel { display: none; }
|
.kn-kopf-titel { display: none; }
|
||||||
.kn-haupt, .kn-blatt { max-width: 1160px; padding: 36px 48px 80px; }
|
.kn-haupt, .kn-blatt { max-width: 1160px; padding: 36px 48px 80px; }
|
||||||
|
|||||||
@@ -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'))
|
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
|
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
|
// 3. Scroll: Stand je Route merken, Kopf (Rand, kleiner Titel) nachführen
|
||||||
|
|||||||
@@ -75,3 +75,15 @@ test('M3: die Fehlertexte der öffentlichen Seiten (Login, Kündigen, Widerrufen
|
|||||||
assert.match(zeile, /role="alert"/, `${datei}: ${zeile}`)
|
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'/)
|
||||||
|
})
|
||||||
Reference in new issue
Block a user