Fixed Headers, On-Page Links, and Overlapping Content, Oh My!

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Nehmen wir einen einfachen On-Page-Link

<a href="#section-two">Section Two</a>

Wenn man darauf klickt, scrollt der Browser selbst zu dem Element mit dieser ID: <a href="#section-two">Abschnitt Zwei</a>. Eine Browser-Funktion, die fast so alt ist wie die Browser selbst.

Aber sobald position: fixed; ins Spiel kam, wurde es zu einem Problem. Der Browser springt immer noch, um das neu angesprochene Element anzuzeigen, aber dieses Element kann durch ein Element mit fester Position verdeckt werden, was eine ziemlich schlechte UX ist.

Ich nannte das vor fast 10 Jahren „mit dem Kopf gegen das Browserfenster stoßen“ und ging einige mögliche Lösungen durch. Nicolas Gallagher dokumentierte fünf verschiedene Techniken. Ich verwende sogar einen Header mit fester Position in v17 von CSS-Tricks, und ich liebe keine dieser Techniken besonders. Ich habe es sozusagen abgestritten und allen meinen <h3>-Elementen einen oberen Innenabstand hinzugefügt, der groß genug ist, damit der Header hineinpasst.

Es gibt aber einen neuen Weg! Endlich!

Šime Vidas dokumentierte dies in Web Platform News. Es gibt eine Reihe von CSS-Eigenschaften, die als Teil von CSS Scroll Snapping zusammenarbeiten, aber es stellt sich heraus, dass scroll-padding und scroll-margin außerhalb eines Scroll Snapping Containers verwendet werden können.

html {
  scroll-padding-top: 70px; /* height of sticky header */
}

Als dies zum ersten Mal veröffentlicht wurde, war es nur in Chrome verfügbar, aber da ich dies im April 2021 aktualisiere, funktioniert es auch in Firefox und Safari!

Hiroyuki Ikezoe schrieb mir, dass <body> nicht der richtige Ort für die Verwendung von scroll-padding ist, da document.scrollingElement tatsächlich <html> ist. Leider hat Chrome dies implementiert (v73) so, dass es im Moment nur auf <body> funktioniert, aber es gibt einen Fehlerbericht und das wahrscheinliche Ergebnis ist, dass es auf <body> nicht mehr funktioniert und nur noch auf <html> funktioniert. Dies ist dieselbe Situation wie bei den native spec-ifizierten benutzerdefinierten Scrollbalken: sie funktionieren nur auf <html>.