Modal-Scroll: Wrapper als definite-height Scroll-Container (Safari-safe)
Ursache: Tailwinds min-h-screen (min-height:100vh) am Flex-Wrapper wächst in Safari nicht mit dem Panel – das Panel ragt sichtbar aus dem Bild, der Container meldet aber keinen Overflow → nichts scrollt, Speichern-Button ist unerreichbar (Chromium wächst dagegen mit, daher dort scheinbar ok). Fix: Die innere .min-h-screen-Box wird zum Scroll-Container mit DEFINITE height:100vh + overflow-y:auto (+ -webkit-overflow-scrolling:touch). Der Backdrop hält overflow:hidden. margin:auto am Panel zentriert kurze Modals und vermeidet Top-Clipping bei langen. Wirkt in Safari, Chrome, Firefox, iOS und Android (verifiziert via Chromium desktop + iPhone-Touch). Zusätzlich Cache-Busting für styles.css (?v=<mtime>) am <link>, damit ein hart zwischengespeichertes altes Stylesheet nach einem Deploy garantiert neu geladen wird. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+15
-11
@@ -452,20 +452,24 @@ button.loading::after {
|
|||||||
============================================ */
|
============================================ */
|
||||||
|
|
||||||
/* Modals: the overlay locks body scroll (overflow:hidden on <body>), so a panel
|
/* Modals: the overlay locks body scroll (overflow:hidden on <body>), so a panel
|
||||||
taller than the viewport would have its bottom cut off and the Save button
|
taller than the viewport must scroll. The scroll container is the INNER
|
||||||
unreachable. Let the OVERLAY itself scroll like a page — the panel grows to
|
wrapper, not the backdrop, and it gets a DEFINITE height:100vh + overflow-y:auto.
|
||||||
its natural height, and the overlay scrolls to reveal it. The panel uses
|
A mere min-height:100vh (Tailwind's min-h-screen) is not enough: in Safari the
|
||||||
`margin:auto`, which centers a short panel but — unlike `align-items:center`
|
flex wrapper then does NOT grow to fit the panel, the panel overflows visibly
|
||||||
— does NOT clip the top when the panel is taller than the viewport (the
|
("card geht aus dem Bild") but the container reports no overflow — so nothing
|
||||||
classic flexbox top-clip bug), so both the close button (top) and the Save
|
scrolls and the Save button is unreachable. A definite height + overflow
|
||||||
button (bottom) stay reachable. Applies on every screen size: the
|
forces a real scroll container in every browser. The panel keeps margin:auto
|
||||||
Bewerbung-hinzufügen form has enough fields (Datum bis Interne Notizen) to
|
so a SHORT modal stays centered, while a tall one starts at the top (no
|
||||||
overflow even on a laptop, not just a phone. */
|
top-clip) and scrolls to the bottom. -webkit-overflow-scrolling gives older
|
||||||
|
iOS momentum touch scrolling. */
|
||||||
.fixed.inset-0 {
|
.fixed.inset-0 {
|
||||||
overflow-y: auto !important;
|
overflow: hidden !important;
|
||||||
}
|
}
|
||||||
.fixed.inset-0 > .min-h-screen {
|
.fixed.inset-0 > .min-h-screen {
|
||||||
min-height: 100vh;
|
height: 100vh !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
align-items: flex-start !important;
|
align-items: flex-start !important;
|
||||||
}
|
}
|
||||||
.fixed.inset-0 > .min-h-screen > .max-w-lg,
|
.fixed.inset-0 > .min-h-screen > .max-w-lg,
|
||||||
|
|||||||
@@ -158,6 +158,18 @@ app.use('/api/indeed-import', (req, res, next) => {
|
|||||||
|
|
||||||
// Set EJS as template engine
|
// Set EJS as template engine
|
||||||
app.set('view engine', 'ejs');
|
app.set('view engine', 'ejs');
|
||||||
|
|
||||||
|
// Cache-busting-Version für styles.css: die mtime der Datei beim Start. Wirkt
|
||||||
|
// nur als Query-Parameter am <link href>, also nach jedem Deploy (neuer
|
||||||
|
// Container → neue mtime → neue URL) erzwingt sie einen echten NeuDownload —
|
||||||
|
// "no-cache" allein reicht manchmal nicht, wenn ein Browser die alte Datei
|
||||||
|
// hart zwischengespeichert hat. Innerhalb eines Laufs bleibt der Wert stabil.
|
||||||
|
try {
|
||||||
|
const cssStat = fs.statSync(path.join(__dirname, 'public', 'css', 'styles.css'));
|
||||||
|
app.locals.assetVersion = String(cssStat.mtimeMs || Date.now());
|
||||||
|
} catch (e) {
|
||||||
|
app.locals.assetVersion = String(Date.now());
|
||||||
|
}
|
||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -20,4 +20,4 @@
|
|||||||
tailwind.config = { darkMode: 'class' };
|
tailwind.config = { darkMode: 'class' };
|
||||||
</script>
|
</script>
|
||||||
<!-- Custom CSS -->
|
<!-- Custom CSS -->
|
||||||
<link rel="stylesheet" href="/css/styles.css">
|
<link rel="stylesheet" href="/css/styles.css?v=<%= assetVersion %>">
|
||||||
|
|||||||
Reference in New Issue
Block a user