From 99b3aba39a46b0ad6fa3e62cfb419d5850899f85 Mon Sep 17 00:00:00 2001 From: Umut Kantarci Date: Wed, 16 Sep 2026 21:56:07 +0200 Subject: [PATCH] Lift what sticks to the bottom above the browser's own bar Umut: "Beim Smarphone/iphone geht der button scroll to top nicht. hier gehts." The button was there and did nothing, on every page of every installation, and tapping it did not even put #seitenanfang in the address bar - so the tap never reached the page. Safari on the iPhone folds its address bar into a narrow strip while reading and lays that over the content. A fixed element measures its "bottom" against the full viewport, not against the part that is left: the button stood in the strip the browser had taken for itself. Drawn, visible, and every tap landed on the bar. Measured at 390x844 the button occupies y 780 to 828 - the bottom 64 pixels, which is where that strip sits. The difference between the large viewport (bar folded) and the small one (bar out) is exactly that height, so --kant-browser-chrome carries it and the pieces that stick to the bottom add it. Where there is no such bar it is zero and nothing moves. The @supports around it is not caution but necessity: a browser that does not know lvh/svh would find the calculation invalid at computed-value time, and bottom would fall back to auto - the button would then stand anywhere. The consent bar has the same geometry, so "Annehmen" and "Ablehnen" were just as hard to hit. It is lifted the same way, except where it is glued to the edge - raising it there would leave a gap with the page showing through, so its bottom padding grows instead and the buttons move up with it. Verified with a test page that sets the height to 50px, the only way to see the effect without an iPhone: the button moves up by exactly 50px, the glued bar keeps its edge and its padding goes from 16px to 66px. On the real page in Chromium bottom stays 16px and the jump still goes 1500 to 0. Not verified on a real iPhone - that needs the device. Co-Authored-By: Claude Opus 5 --- public/assets/site.css | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/public/assets/site.css b/public/assets/site.css index a36031e..447aa58 100644 --- a/public/assets/site.css +++ b/public/assets/site.css @@ -6,6 +6,21 @@ h1,h2,h3,h4,h5,h6{hyphens:manual} p{hyphens:auto} .visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.block-image{margin:0;max-width:100%}.block-image img{max-width:100%;height:auto} :root{color-scheme:var(--k-scheme,light);--paper:#f7f8f4;--ink:#182d2b;--muted:#50625d;--line:#d7dfd7;--mint:#e5f0b6;--accent:#315b49;--error:var(--k-error,#8b2f22);--error-bg:var(--k-error-bg,#fff0eb);--error-line:var(--k-error-line,#e2b2a7);font-family:Arial,Helvetica,sans-serif;color:var(--ink);background:var(--paper);font-synthesis:none} +/* Die Hoehe der Browserleiste, die ueber dem Inhalt liegt. + Safari auf dem iPhone schiebt seine Adressleiste beim Herunterscrollen zu einem schmalen + Balken zusammen und legt den ueber die Seite. Ein fixiertes Element rechnet sein `bottom` + aber gegen die volle Ansicht, nicht gegen den freien Teil - was unten klebt, steht damit in + dem Streifen, den der Browser sich selbst genommen hat. Sichtbar ist es, aber jeder Tipp + landet auf der Leiste. Genau das war mit dem Nach-oben-Knopf: am Schreibtisch tadellos, auf + dem Telefon tot, auf jeder Seite jeder Installation. + Die Differenz zwischen grosser Ansicht (`lvh`, Leiste zusammengeschoben) und kleiner Ansicht + (`svh`, Leiste ausgefahren) ist genau diese Hoehe. Wo es keine solche Leiste gibt, ist sie + null, und nichts verschiebt sich. + Die Abfrage davor ist Pflicht, nicht Vorsicht: kennt ein Browser die Einheiten nicht, waere + die Rechnung erst beim Errechnen ungueltig, und `bottom` fiele auf `auto` zurueck - das Ding + stuende dann irgendwo. So bleibt es schlicht bei null. */ +:root{--kant-browser-chrome:0px} +@supports (height:100lvh) and (height:100svh){:root{--kant-browser-chrome:calc(100lvh - 100svh)}} *{box-sizing:border-box}body{margin:0}a{color:inherit;text-underline-offset:5px}a:hover{text-decoration-thickness:2px}:focus-visible{outline:3px solid var(--accent);outline-offset:6px}main:focus{outline:none}.shell{width:min(var(--k-container,1180px),calc(100% - 64px));margin-inline:auto}.site-header{border-bottom:1px solid var(--line)}.site-header.is-sticky{position:sticky;top:0;z-index:40;background:var(--paper);box-shadow:0 1px 0 var(--line),0 10px 30px color-mix(in srgb,var(--ink) 8%,transparent)} /* Über dem Inhalt: der Kopf nimmt keinen Platz ein, die erste Sektion beginnt unter ihm. Farbe und Schatten kommen aus der Gestaltung des Kopfbereichs, auch die für den gescrollten Zustand. */ @@ -182,7 +197,9 @@ p{hyphens:auto} Aussehen aus den Einstellungen: `--kant-consent-*` im Kopf der Seite (Consent::styles), die Anordnung als Klasse. Ohne Einstellung gilt Papier, Tinte und Akzent des Themes. Ein Wert wie `--k-consent` aus der Palette bleibt als Zwischenstufe erhalten. */ -.consent-bar{position:fixed;inset-inline:16px;bottom:16px;z-index:50;max-width:640px;max-height:calc(100dvh - 24px);overflow:auto;margin-inline:auto;background:var(--kant-consent-bg,var(--paper));color:var(--kant-consent-ink,var(--ink));border:1px solid color-mix(in srgb,currentColor 12%,transparent);border-radius:var(--kant-consent-radius,18px);padding:22px 24px 20px;box-shadow:0 24px 60px color-mix(in srgb,var(--ink) 22%,transparent);font-size:14px;line-height:1.6;overscroll-behavior:contain} +/* Das `+ var(--kant-browser-chrome)` hebt die Leiste ueber Safaris zusammengeschobene + Adressleiste; sonst liegen „Annehmen“ und „Ablehnen“ unter ihr und sind nicht zu treffen. */ +.consent-bar{position:fixed;inset-inline:16px;bottom:calc(16px + var(--kant-browser-chrome));z-index:50;max-width:640px;max-height:calc(100dvh - 24px);overflow:auto;margin-inline:auto;background:var(--kant-consent-bg,var(--paper));color:var(--kant-consent-ink,var(--ink));border:1px solid color-mix(in srgb,currentColor 12%,transparent);border-radius:var(--kant-consent-radius,18px);padding:22px 24px 20px;box-shadow:0 24px 60px color-mix(in srgb,var(--ink) 22%,transparent);font-size:14px;line-height:1.6;overscroll-behavior:contain} /* Ein schmaler Streifen in der Akzentfarbe oben: die Fläche gehört sichtbar zur Website. */ .consent-bar::before{content:'';position:absolute;inset:0 0 auto 0;height:4px;background:var(--kant-consent-accent,var(--k-consent,var(--accent)))} .kant .consent-bar h2{display:flex;align-items:center;gap:10px;font-size:17px;line-height:1.3;margin:0 0 8px} @@ -214,7 +231,10 @@ p{hyphens:auto} .consent-links a:hover{color:var(--kant-consent-accent,var(--k-consent,var(--accent)))} /* Leiste: über die ganze Breite am unteren Rand, auf breiten Bildschirmen Text links und Knöpfe rechts. Ecke: eine kleine Karte rechts unten, die den Inhalt kaum verdeckt. */ -.consent-layout-leiste{inset-inline:0;bottom:0;max-width:none;border-radius:var(--kant-consent-radius,18px) var(--kant-consent-radius,18px) 0 0;border-inline:0;border-bottom:0;padding-inline:max(24px,calc((100% - 1180px) / 2))} +/* Klebt die Leiste an der Kante, wird sie nicht angehoben - das gaebe einen Spalt, durch den + die Seite scheint. Stattdessen waechst ihr unterer Innenabstand um die Hoehe der + Browserleiste, sodass die Knoepfe darueber bleiben. */ +.consent-layout-leiste{inset-inline:0;bottom:0;max-width:none;border-radius:var(--kant-consent-radius,18px) var(--kant-consent-radius,18px) 0 0;border-inline:0;border-bottom:0;padding-inline:max(24px,calc((100% - 1180px) / 2));padding-bottom:calc(20px + var(--kant-browser-chrome))} @media (min-width:900px){.consent-layout-leiste{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 40px;align-items:center}.consent-layout-leiste .consent-body p{margin-bottom:0}.consent-layout-leiste .consent-form{width:360px;max-width:100%}} .consent-layout-ecke{inset-inline:auto 16px;max-width:400px;margin:0} /* While the question is open the bar is fixed at the bottom, so the page has to end above it - @@ -226,7 +246,7 @@ body.consent-open{padding-bottom:320px} @media (min-width:900px){body.consent-open{padding-bottom:200px}} .consent-page main{max-width:680px;margin-inline:auto;padding:40px 20px} .consent-page .consent-bar{position:static;inset:auto;box-shadow:none;max-width:none;max-height:none;margin:24px 0 0;display:block} -@media (max-width:620px){.consent-bar,.consent-layout-ecke{inset-inline:0;bottom:0;max-width:none;border-radius:var(--kant-consent-radius,18px) var(--kant-consent-radius,18px) 0 0;border-inline:0;border-bottom:0;padding:18px 18px 16px}.consent-layout-leiste{padding-inline:18px}} +@media (max-width:620px){.consent-bar,.consent-layout-ecke{inset-inline:0;bottom:0;max-width:none;border-radius:var(--kant-consent-radius,18px) var(--kant-consent-radius,18px) 0 0;border-inline:0;border-bottom:0;padding:18px 18px calc(16px + var(--kant-browser-chrome))}.consent-layout-leiste{padding-inline:18px}} /* An embedded third party, and what stands in its place until it may load. */ .block-embed iframe{display:block;width:100%;border:0;border-radius:10px;background:color-mix(in srgb,var(--ink) 8%,var(--paper))} @@ -498,10 +518,12 @@ body.consent-open{padding-bottom:320px} Safari), steht er von Anfang an da: sichtbar und nutzbar ist besser als unsichtbar. Aussehen, Größe, Form, Seite und Schwelle kommen aus den Einstellungen. */ .scroll-top{position:fixed;bottom:22px;right:22px;z-index:40;display:grid;place-items:center;width:var(--kant-top-size,48px);height:var(--kant-top-size,48px);border-radius:var(--kant-top-radius,999px);background:var(--kant-top-bg,var(--accent));color:var(--kant-top-ink,#fff);text-decoration:none;box-shadow:0 8px 24px color-mix(in srgb,var(--ink) 28%,transparent);font-size:calc(var(--kant-top-size,48px) / 2.4);line-height:1} +/* Ueber die Browserleiste hinaus, sonst ist der Knopf auf dem Telefon nicht zu treffen. */ +.scroll-top{bottom:calc(22px + var(--kant-browser-chrome))} .scroll-top-links{right:auto;left:22px} .scroll-top:hover{filter:brightness(1.08)} .scroll-top:focus-visible{outline:3px solid var(--accent);outline-offset:3px} -@media (max-width:767px){.scroll-top{bottom:16px;right:16px}.scroll-top-links{left:16px;right:auto}} +@media (max-width:767px){.scroll-top{bottom:calc(16px + var(--kant-browser-chrome));right:16px}.scroll-top-links{left:16px;right:auto}} /* Solange die Einwilligungsfrage offen ist, bleibt der Knopf da. Frueher verschwand er ganz - und auf dem Telefon bleibt die Frage oft einfach stehen, der Knopf kam dort also nie. Bis 799 px deckt die Leiste die Ecke ab, in der er steht: dort setzt er sich per