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>.
Leider ist es immer noch nicht sehr hilfreich, wenn Sie keine statische/feste Höhe für Ihren Sticky-Header haben (was auf jeden Fall vermieden werden sollte). Sie bräuchten sowieso JavaScript, um die Höhe zu messen, um den Stil anzupassen.
Warum sollte eine feste Header-Höhe „auf jeden Fall“ vermieden werden?
In Antwort auf Todd, weil die Festlegung fester Höhen in CSS im Allgemeinen eine schlechte Idee ist. Das Web ist dazu gemacht, zu fließen und sich in jede Form und Gestalt einzufügen, in der es präsentiert wird. Ein Benutzer stellt eine andere Schriftgröße ein, nun ist Ihr Header mit fester Höhe zu kurz. Selbst wenn Sie eine
em-Einheit verwenden, müssen Sie immer noch alle Höhen im Auge behalten (erste Ansicht, vielleicht schrumpft die Höhe beim Scrollen, ändert sich auf dem Tablet, wieder auf dem Handy usw.). Es wird zu einem riesigen Kopfzerbrechen. Und dann fragt der Chef einen Monat später, ob Sie ein Partnerlogo unter dem Header-Navigationsmenü hinzufügen können, dann müssen Sie all diese Höhen erneut anpassen und Ihren Offset für On-Page-Links wieder anpassen. Dies sind nur einige Beispiele für den Albtraum, den feste Höhen/Breiten Ihnen bescheren werden.Was ist, wenn Sie keinen festen Navigationsbalken haben? Ich habe einen Parallax-Effekt-Hintergrund, dessen obere Hälfte unter meinem Navigationsbalken verborgen ist und ich kann ihn nicht herunterrutschen lassen.
Oh mein Gott, ich hoffe wirklich, dass dies in allen Browsern implementiert wird. Fixed Headers werden aus UX-Gründen immer üblicher. Nicht auf JS zurückgreifen zu müssen, um eine so lange existierende gemeinsame Funktion zu „hijacken und neu zu implementieren“, hilft sehr.
Ich bin mir nicht sicher, warum Sie all die Workarounds benötigen… sogar diesen neuen… wenn Sie einen festen Header haben, positionieren Sie ihn einfach ganz oben und legen Sie alles andere in ein scrollbares
<
div>.
Entschuldigen Sie, aber ich konnte Ihre letzte Demo nicht verstehen. Sie haben den Inhalt mit
marginnach unten verschoben, daher bewirktscroll-padding-topnichts (nichts ändert sich nach dem Entfernen). Habe ich etwas übersehen?Klicken Sie auf den Sprunglink am oberen Rand der Demo. Wo er ankernt und wie viel Platz ist, um die darunter liegende Überschrift anzuzeigen, dort liegt die Magie. :)
Wunderbar! Dieses Problem hat mich so lange geplagt, dass ich versucht habe, Scroll-Links zu ignorieren. Hoffen wir, dass Webkit und Firefox dies so schnell wie möglich übernehmen :)
Danke Chris, diese Props habe ich noch nicht gesehen!
Das ist erstaunlich! Ich musste das vor einiger Zeit für einen Kunden tun und habe es mit JavaScript behoben, aber das ist viel besser.
Ich habe tatsächlich benutzerdefinierte Eigenschaften verwendet, um die Höhe meines Headers zu speichern, und dann können Sie Werte mit dieser Variablen berechnen, um Dinge zu versetzen.
Haben Sie in Erwägung gezogen, dem Element einen oberen Rand hinzuzufügen?
Diese Technik funktioniert hervorragend, auch in älteren Browsern, und erfordert kein JavaScript. Da Browser das Ziel-Element am oberen Rand des
<html>-Elements ausrichten, können Sie vollständig kontrollieren, wohin das Ziel-Element auf der Seite springt (also kein Kopfstoß mehr gegen das Browserfenster).Header und andere Elemente können mit Standardtechniken (und bei Bedarf mit negativen Rändern) positioniert werden.
Ich denke, das fügt den Rand/Innenabstand als unsichtbar hinzu und wird nur von den Quick-Links verwendet.